/* execute a udf */ void f_call(union argument *x) { struct udft_entry *udf; struct value save_dummy; udf = x->udf_arg; if (!udf->at) int_error(NO_CARET, "undefined function: %s", udf->udf_name); save_dummy = udf->dummy_values[0]; (void) pop(&(udf->dummy_values[0])); if (udf->dummy_num != 1) int_error(NO_CARET, "function %s requires %d variables", udf->udf_name, udf->dummy_num); if (recursion_depth++ > STACK_DEPTH) int_error(NO_CARET, "recursion depth limit exceeded"); execute_at(udf->at); gpfree_string(&udf->dummy_values[0]); udf->dummy_values[0] = save_dummy; recursion_depth--; }
/* execute a udf of n variables */ void f_calln(union argument *x) { struct udft_entry *udf; struct value save_dummy[MAX_NUM_VAR]; int i; int num_pop; struct value num_params; udf = x->udf_arg; if (!udf->at) /* undefined */ int_error(NO_CARET, "undefined function: %s", udf->udf_name); for (i = 0; i < MAX_NUM_VAR; i++) save_dummy[i] = udf->dummy_values[i]; (void) pop(&num_params); if (num_params.v.int_val != udf->dummy_num) int_error(NO_CARET, "function %s requires %d variable%c", udf->udf_name, udf->dummy_num, (udf->dummy_num == 1)?'\0':'s'); /* if there are more parameters than the function is expecting */ /* simply ignore the excess */ if (num_params.v.int_val > MAX_NUM_VAR) { /* pop and discard the dummies that there is no room for */ num_pop = num_params.v.int_val - MAX_NUM_VAR; for (i = 0; i < num_pop; i++) (void) pop(&(udf->dummy_values[0])); num_pop = MAX_NUM_VAR; } else { num_pop = num_params.v.int_val; } /* pop parameters we can use */ for (i = num_pop - 1; i >= 0; i--) (void) pop(&(udf->dummy_values[i])); if (recursion_depth++ > STACK_DEPTH) int_error(NO_CARET, "recursion depth limit exceeded"); execute_at(udf->at); recursion_depth--; for (i = 0; i < MAX_NUM_VAR; i++) { gpfree_string(&udf->dummy_values[i]); udf->dummy_values[i] = save_dummy[i]; } }
void f_sum(union argument *arg) { struct value beg, end, varname; /* [<var> = <start>:<end>] */ udft_entry *udf; /* function to evaluate */ udvt_entry *udv; /* iteration variable */ struct value ret; /* result */ struct value z; int i; (void) pop(&end); (void) pop(&beg); (void) pop(&varname); if (beg.type != INTGR || end.type != INTGR) int_error(NO_CARET, "range specifiers of sum must have integer values"); if (varname.type != STRING) int_error(NO_CARET, "internal error: f_sum expects argument (varname) of type string."); udv = get_udv_by_name(varname.v.string_val); if (!udv) int_error(NO_CARET, "internal error: f_sum could not access iteration variable."); udv->udv_undef = false; udf = arg->udf_arg; if (!udf) int_error(NO_CARET, "internal error: f_sum could not access summation coefficient function"); Gcomplex(&ret, 0, 0); for (i=beg.v.int_val; i<=end.v.int_val; ++i) { double x, y; /* calculate f_i = f() with user defined variable i */ Ginteger(&udv->udv_value, i); execute_at(udf->at); pop(&z); x = real(&ret) + real(&z); y = imag(&ret) + imag(&z); Gcomplex(&ret, x, y); } gpfree_string(&varname); push(Gcomplex(&z, real(&ret), imag(&ret))); }
/* execute a udf */ void f_call(union argument *x) { struct udft_entry *udf; struct value save_dummy; udf = x->udf_arg; if (!udf->at) { /* undefined */ int_error(NO_CARET, "undefined function: %s", udf->udf_name); } save_dummy = udf->dummy_values[0]; (void) pop(&(udf->dummy_values[0])); if (udf->dummy_num != 1) int_error(NO_CARET, "function %s requires %d variables", udf->udf_name, udf->dummy_num); execute_at(udf->at); gpfree_string(&udf->dummy_values[0]); udf->dummy_values[0] = save_dummy; }