void read_tree_recurse ( int space, ephem_const **eind, FILE *fil, int tree, char *string ) { function *f; int i, j; ephem_const *ep; /* read up until a nonwhitespace character in file. the nonwhitespace character is saved in string[0]. */ while ( isspace(string[0]=fgetc(fil)) ); /* get the next character. */ i = fgetc ( fil ); if ( isspace(i) ) /* if the next character is whitespace, then string[0] is a one-character function name. null-terminate the string. */ string[1] = 0; else { /** if the next character is not whitespace, then string[0] is either an open parenthesis or the first character of a multi-character function name. **/ /* push the next character back. */ ungetc ( i, fil ); /* read the function name. skip over an open parenthesis, if there is one. */ fscanf ( fil, "%s ", string+(string[0]!='(') ); } #ifdef DEBUG_READTREE fprintf ( stderr, "function name is [%s]\n", string ); #endif /* look up the function name in this tree's function set. if the function is an ERC terminal (the name is of the form "name:ERCindex"), then place the ERC address in ep. */ f = get_function_by_name ( tree, string, &ep, eind ); /* add an lnode to the tree. */ gensp_next(space)->f = f; switch ( f->type ) { case TERM_NORM: case TERM_ARG: case EVAL_TERM: break; case TERM_ERC: /* record the ERC address as the next lnode in the array. */ gensp_next(space)->d = ep; break; case FUNC_DATA: case EVAL_DATA: /** recursively read child functions, no skip nodes needed. **/ for ( i = 0; i < f->arity; ++i ) read_tree_recurse ( space, eind, fil, tree, string ); break; case FUNC_EXPR: case EVAL_EXPR: /** recursively read child functions, recording skip values. **/ for ( i = 0; i < f->arity; ++i ) { /* save an lnode for the skip value. */ j = gensp_next_int ( space ); /* read the child tree. */ read_tree_recurse ( space, eind, fil, tree, string ); /* figure out how big the child tree was, and save that number in the skip node. */ gensp[space].data[j].s = gensp[space].used-j-1; } break; } }
static jit_value_t parse_recursive(jit_function_t func) { jit_value_t arg1, arg2, result; jit_function_t func1; double val; char *t = token(); // Somebody, do something with this! // It's awful monkeycoding, but I'm too lazy to rewrite it :3 if (STREQ(t, "F")) result = val_freq; else if (STREQ(t, "X")) result = jit_insn_convert(func, val_sample, jit_type_float64, 0); else if (STREQ(t, "LEN")) result = jit_insn_convert(func, val_length, jit_type_float64, 0); else if (STREQ(t, "RATE")) result = const_rate; else if (STREQ(t, "PI")) result = const_pi; else if (STREQ(t, "+")) result = jit_insn_add(func, parse_recursive(func), parse_recursive(func)); else if (STREQ(t, "-")) { arg1 = parse_recursive(func); arg2 = parse_recursive(func); result = jit_insn_sub(func, arg1, arg2); } else if (STREQ(t, "*")) result = jit_insn_mul(func, parse_recursive(func), parse_recursive(func)); else if (STREQ(t, "/")) { arg1 = parse_recursive(func); arg2 = parse_recursive(func); result = jit_insn_div(func, arg1, arg2); } else if (STREQ(t, "%")) { arg1 = parse_recursive(func); arg2 = parse_recursive(func); result = jit_insn_rem(func, arg1, arg2); } else if (STREQ(t, ">")) { arg1 = parse_recursive(func); arg2 = parse_recursive(func); result = jit_insn_gt(func, arg1, arg2); } else if (STREQ(t, "<")) { arg1 = parse_recursive(func); arg2 = parse_recursive(func); result = jit_insn_lt(func, arg1, arg2); } else if (STREQ(t, "if")) { jit_value_t tmpval = jit_value_create(func, jit_type_float64); jit_label_t lb_false = jit_label_undefined, lb_end = jit_label_undefined; jit_insn_branch_if_not(func, jit_insn_to_bool(func, parse_recursive(func)), &lb_false); jit_insn_store(func, tmpval, parse_recursive(func)); jit_insn_branch(func, &lb_end); jit_insn_label(func, &lb_false); jit_insn_store(func, tmpval, parse_recursive(func)); jit_insn_label(func, &lb_end); result = jit_insn_load(func, tmpval); } else if (STREQ(t, "sin")) result = jit_insn_sin(func, parse_recursive(func)); else if (sscanf(t, "%lf", &val) == 1) result = jit_value_create_float64_constant(func, jit_type_float64, val); else if ((func1 = get_function_by_name(t)) != NULL) { arg1 = parse_recursive(func); arg2 = parse_recursive(func); jit_value_t args[3] = {arg1, arg2, val_length}; result = jit_insn_call( func, t, func1, NULL, args, 3, 0); } else { LOGF("Unexpected token '%s'", t); result = NULL; } free(t); return result; }