Beispiel #1
0
void define()
{
    register int start_token;	/* the 1st token in the function definition */
    register struct udvt_entry *udv;
    register struct udft_entry *udf;

    if (equals(c_token + 1, "(")) {
	/* function ! */
	int dummy_num = 0;
	struct at_type *at_tmp;
	char save_dummy[MAX_NUM_VAR][MAX_ID_LEN + 1];
	memcpy(save_dummy, c_dummy_var, sizeof(save_dummy));
	start_token = c_token;
	do {
	    c_token += 2;	/* skip to the next dummy */
	    copy_str(c_dummy_var[dummy_num++], c_token, MAX_ID_LEN);
	} while (equals(c_token + 1, ",") && (dummy_num < MAX_NUM_VAR));
	if (equals(c_token + 1, ","))
	    int_error("function contains too many parameters", c_token + 2);
	c_token += 3;		/* skip (, dummy, ) and = */
	if (END_OF_COMMAND)
	    int_error("function definition expected", c_token);
	udf = dummy_func = add_udf(start_token);
	if ((at_tmp = perm_at()) == (struct at_type *) NULL)
	    int_error("not enough memory for function", start_token);
	if (udf->at)		/* already a dynamic a.t. there */
	    free((char *) udf->at);	/* so free it first */
	udf->at = at_tmp;	/* before re-assigning it. */
	memcpy(c_dummy_var, save_dummy, sizeof(save_dummy));
	m_capture(&(udf->definition), start_token, c_token - 1);
	dummy_func = NULL;	/* dont let anyone else use our workspace */
    } else {
	/* variable ! */
	start_token = c_token;
	c_token += 2;
	udv = add_udv(start_token);
	(void) const_express(&(udv->udv_value));
	udv->udv_undef = FALSE;
    }
}
Beispiel #2
0
/*
 * Syntax: set link {x2|y2} {via <expression1> inverse <expression2>}
 * Create action code tables for the functions linking primary and secondary axes.
 * expression1 maps primary coordinates into the secondary coordinate space.
 * expression2 maps secondary coordinates into the primary coordinate space.
 */
void
parse_link_via( struct udft_entry *udf )
{
    int start_token;
    
    /* Caller left us pointing at "via" or "inverse" */
    c_token++;
    start_token = c_token;
    if (END_OF_COMMAND)
	int_error(c_token,"Missing expression");

    /* Save action table for the linkage mapping */
    strcpy(c_dummy_var[0], "x");
    strcpy(c_dummy_var[1], "y");
    dummy_func = udf;
    free_at(udf->at);
    udf->at = perm_at();
    dummy_func = NULL;

    /* Save the mapping expression itself */
    m_capture(&(udf->definition), start_token, c_token - 1);
}
Beispiel #3
0
/* create action code for 'sum' expressions */
static void
parse_sum_expression()
{
    /* sum [<var>=<range>] <expr>
     * - Pass a udf to f_sum (with action code (for <expr>) that is not added
     *   to the global action table).
     * - f_sum uses a newly created udv (<var>) to pass the current value of
     *   <var> to <expr> (resp. its ac).
     * - The original idea was to treat <expr> as function f(<var>), but there
     *   was the following problem: Consider 'g(x) = sum [k=1:4] f(k)'. There
     *   are two dummy variables 'x' and 'k' from different functions 'g' and
     *   'f' which would require changing the parsing of dummy variables.
     */

    char *errormsg = "Expecting 'sum [<var> = <start>:<end>] <expression>'\n";
    char *varname = NULL;
    union argument *arg;
    struct udft_entry *udf;

    struct at_type * save_at;
    int save_at_size;
    int i;
    
    /* Caller already checked for string "sum [" so skip both tokens */
    c_token += 2;

    /* <var> */
    if (!isletter(c_token))
        int_error(c_token, errormsg);
    /* create a user defined variable and pass it to f_sum via PUSHC, since the
     * argument of f_sum is already used by the udf */
    m_capture(&varname, c_token, c_token);
    add_udv(c_token);
    arg = add_action(PUSHC);
    Gstring(&(arg->v_arg), varname);
    c_token++;

    if (!equals(c_token, "="))
        int_error(c_token, errormsg);
    c_token++;

    /* <start> */
    parse_expression();

    if (!equals(c_token, ":"))
        int_error(c_token, errormsg);
    c_token++;

    /* <end> */
    parse_expression();

    if (!equals(c_token, "]"))
        int_error(c_token, errormsg);
    c_token++;

    /* parse <expr> and convert it to a new action table. */
    /* modeled on code from temp_at(). */
    /* 1. save environment to restart parsing */
    save_at = at;
    save_at_size = at_size;
    at = NULL;

    /* 2. save action table in a user defined function */
    udf = (struct udft_entry *) gp_alloc(sizeof(struct udft_entry), "sum");
    udf->next_udf = (struct udft_entry *) NULL;
    udf->udf_name = NULL; /* TODO maybe add a name and definition */ 
    udf->at = perm_at();
    udf->definition = NULL;
    udf->dummy_num = 0;
    for (i = 0; i < MAX_NUM_VAR; i++)
        (void) Ginteger(&(udf->dummy_values[i]), 0);

    /* 3. restore environment */
    at = save_at;
    at_size = save_at_size;

    /* pass the udf to f_sum using the argument */
    add_action(SUM)->udf_arg = udf;
}