Пример #1
0
/* Look for an iterate-over-plot construct, of the form
 *    {s}plot  for [<var> = <start> : <end> { : <increment>}] ...
 */
void
check_for_iteration()
{
    char *errormsg = "Expecting iterator \tfor [<var> = <start> : <end>]\n\t\t\tor\tfor [<var> in \"string of words\"]";

    iteration_udv = NULL;
    free(iteration_string);
    iteration_string = NULL;
    iteration_increment = 1;
    iteration = 0;

    if (!equals(c_token, "for"))
	return;

    c_token++;
    if (!equals(c_token++, "[") || !isletter(c_token))
	int_error(c_token-1, errormsg);
    iteration_udv = add_udv(c_token++);

    if (equals(c_token, "=")) {
	c_token++;
	iteration_start = int_expression();
	if (!equals(c_token++, ":"))
	    int_error(c_token-1, errormsg);
	iteration_end = int_expression();
	if (equals(c_token,":")) {
	    c_token++;
	    iteration_increment = int_expression();
	}
	if (!equals(c_token++, "]"))
	    int_error(c_token-1, errormsg);
	if (iteration_udv->udv_undef == FALSE)
	    gpfree_string(&iteration_udv->udv_value);
	Ginteger(&(iteration_udv->udv_value), iteration_start);
	iteration_udv->udv_undef = FALSE;
    }

    else if (equals(c_token++, "in")) {
	iteration_string = try_to_get_string();
	if (!iteration_string)
	    int_error(c_token-1, errormsg);
	if (!equals(c_token++, "]"))
	    int_error(c_token-1, errormsg);
	iteration_start = 1;
	iteration_end = gp_words(iteration_string);
	if (iteration_udv->udv_undef == FALSE)
	    gpfree_string(&iteration_udv->udv_value);
	Gstring(&(iteration_udv->udv_value), gp_word(iteration_string, 1));
	iteration_udv->udv_undef = FALSE;
    }

    else /* Neither [i=B:E] or [s in "foo"] */
 	int_error(c_token-1, errormsg);

    iteration_current = iteration_start;

}
Пример #2
0
/* Look for iterate-over-plot constructs, of the form
 *    for [<var> = <start> : <end> { : <increment>}] ...
 * If one (or more) is found, an iterator structure is allocated and filled
 * and a pointer to that structure is returned.
 * The pointer is NULL if no "for" statements are found.
 */
t_iterator *
check_for_iteration()
{
    char *errormsg = "Expecting iterator \tfor [<var> = <start> : <end> {: <incr>}]\n\t\t\tor\tfor [<var> in \"string of words\"]";
    int nesting_depth = 0;
    t_iterator *iter = NULL;
    t_iterator *this_iter = NULL;

    /* Now checking for iteration parameters */
    /* Nested "for" statements are supported, each one corresponds to a node of the linked list */
    while (equals(c_token, "for")) {
	struct udvt_entry *iteration_udv = NULL;
	char *iteration_string = NULL;
	int iteration_start;
	int iteration_end;
	int iteration_increment = 1;
	int iteration_current;
	int iteration = 0;
	TBOOLEAN empty_iteration;
	TBOOLEAN just_once = FALSE;

	c_token++;
	if (!equals(c_token++, "[") || !isletter(c_token))
	    int_error(c_token-1, errormsg);
	iteration_udv = add_udv(c_token++);

	if (equals(c_token, "=")) {
	    c_token++;
	    iteration_start = int_expression();
	    if (!equals(c_token++, ":"))
	    	int_error(c_token-1, errormsg);
	    iteration_end = int_expression();
	    if (equals(c_token,":")) {
	    	c_token++;
	    	iteration_increment = int_expression();
		if (iteration_increment == 0)
		    int_error(c_token-1, errormsg);
	    }
	    if (!equals(c_token++, "]"))
	    	int_error(c_token-1, errormsg);
	    if (iteration_udv->udv_undef == FALSE)
		gpfree_string(&(iteration_udv->udv_value));
	    Ginteger(&(iteration_udv->udv_value), iteration_start);
	    iteration_udv->udv_undef = FALSE;
	}
	else if (equals(c_token++, "in")) {
	    iteration_string = try_to_get_string();
	    if (!iteration_string)
	    	int_error(c_token-1, errormsg);
	    if (!equals(c_token++, "]"))
	    	int_error(c_token-1, errormsg);
	    iteration_start = 1;
	    iteration_end = gp_words(iteration_string);
	    if (iteration_udv->udv_undef == FALSE)
	    	gpfree_string(&(iteration_udv->udv_value));
	    Gstring(&(iteration_udv->udv_value), gp_word(iteration_string, 1));
	    iteration_udv->udv_undef = FALSE;
	}
	else /* Neither [i=B:E] or [s in "foo"] */
	    int_error(c_token-1, errormsg);

	iteration_current = iteration_start;

	empty_iteration = FALSE;	
	if ( (iteration_udv != NULL)
	&&   ((iteration_end > iteration_start && iteration_increment < 0)
	   || (iteration_end < iteration_start && iteration_increment > 0))) {
		empty_iteration = TRUE;
		FPRINTF((stderr,"Empty iteration\n"));
	}

	/* Allocating a node of the linked list nested iterations. */
	/* Iterating just once is the same as not iterating at all */
	/* so we skip building the node in that case.		   */
	if (iteration_start == iteration_end)
	    just_once = TRUE;
	if (iteration_start < iteration_end && iteration_end < iteration_start + iteration_increment)
	    just_once = TRUE;
	if (iteration_start > iteration_end && iteration_end > iteration_start + iteration_increment)
	    just_once = TRUE;

	if (!just_once) {
	    this_iter = gp_alloc(sizeof(t_iterator), "iteration linked list");
	    this_iter->iteration_udv = iteration_udv; 
	    this_iter->iteration_string = iteration_string;
	    this_iter->iteration_start = iteration_start;
	    this_iter->iteration_end = iteration_end;
	    this_iter->iteration_increment = iteration_increment;
	    this_iter->iteration_current = iteration_current;
	    this_iter->iteration = iteration;
	    this_iter->done = FALSE;
	    this_iter->really_done = FALSE;
	    this_iter->empty_iteration = empty_iteration;
	    this_iter->next = NULL;
	    this_iter->prev = NULL;
	    if (nesting_depth == 0) {
		/* first "for" statement: this will be the listhead */
		iter = this_iter;
	    }
	    else {
		/* not the first "for" statement: attach the newly created node to the end of the list */
		iter->prev->next = this_iter;  /* iter->prev points to the last node of the list */
		this_iter->prev = iter->prev;
	    }
	    iter->prev = this_iter; /* a shortcut: making the list circular */

	    /* if one iteration in the chain is empty, the subchain of nested iterations is too */
	    if (!iter->empty_iteration) 
		iter->empty_iteration = empty_iteration;

	    nesting_depth++;
	}
    }

    return iter;
}