static val_ptr eval_ternary(tree_ptr t) { val_ptr x = tree_eval((tree_ptr)darray_at(t->child, 0)); if (v_error == x->type) { return x; } if (x->type != v_elem) { return val_new_error("element expected in ternary operator"); } if (!element_is0(x->elem)) { return tree_eval((tree_ptr)darray_at(t->child, 1)); } return tree_eval((tree_ptr)darray_at(t->child, 2)); }
static val_ptr v_field_cast(val_ptr v, tree_ptr t) { // TODO: Check args, x is an element. val_ptr x = tree_eval((tree_ptr)darray_at(t->child, 0)); element_ptr e = x->elem; if (e->field == M) { if (v->field == M) return x; element_ptr e2 = element_new(v->field); if (element_is0(e)) // if 'set0' is not 'set1' in base field of GT, but we hope 'GT(0)' calls 'set1', we may directly call 'element_set0' here element_set0(e2); else if (element_is1(e)) // reason is same as above element_set1(e2); else element_set_multiz(e2, (multiz)e->data); x->elem = e2; return x; } if (v->field == M) { // Map to/from integer. TODO: Map to/from multiz instead. mpz_t z; mpz_init(z); element_to_mpz(z, e); element_clear(e); element_init(e, v->field); element_set_mpz(e, z); mpz_clear(z); } return x; }
static val_ptr eval_assign(tree_ptr t) { tree_ptr tid = (tree_ptr)darray_at(t->child, 0); val_ptr v = tree_eval((tree_ptr)darray_at(t->child, 1)); if (symtab_at(reserved, tid->id)) { return val_new_error("%s is reserved", tid->id); } symtab_put(tab, v, tid->id); return v; }
// Evaluate statement. void tree_eval_stmt(tree_ptr stmt) { val_ptr v = tree_eval(stmt); if (v && v_error == v->type) { v->type->out_str(stdout, v); putchar('\n'); } else if (stmt->eval != eval_assign && v) { v->type->out_str(stdout, v); putchar('\n'); } }
Regexp * re_update(NODE *t) { NODE *t1; if ((t->re_flags & CASE) == IGNORECASE) { if ((t->re_flags & CONST) != 0) { assert(t->type == Node_regex); return t->re_reg; } t1 = force_string(tree_eval(t->re_exp)); if (t->re_text != NULL) { if (cmp_nodes(t->re_text, t1) == 0) { free_temp(t1); return t->re_reg; } unref(t->re_text); } t->re_text = dupnode(t1); free_temp(t1); } if (t->re_reg != NULL) refree(t->re_reg); if (t->re_cnt > 0) t->re_cnt++; if (t->re_cnt > 10) t->re_cnt = 0; if (t->re_text == NULL || (t->re_flags & CASE) != IGNORECASE) { t1 = force_string(tree_eval(t->re_exp)); unref(t->re_text); t->re_text = dupnode(t1); free_temp(t1); } t->re_reg = make_regexp(t->re_text->stptr, t->re_text->stlen, IGNORECASE, t->re_cnt); t->re_flags &= ~CASE; t->re_flags |= IGNORECASE; return t->re_reg; }
static val_ptr v_builtin(val_ptr v, tree_ptr t) { fun_ptr fun = v->fun; int n = fun->arity; if (1 + n != darray_count(t->child)) { return val_new_error("%s: wrong number of arguments", fun->name); } val_ptr arg[n]; int i; for(i = 0; i < n; i++) { arg[i] = tree_eval(darray_at(t->child, i)); if (fun->sig[i] && arg[i]->type != fun->sig[i]) { return val_new_error("%s: argument %d type mismatch", fun->name, i + 1); } } return fun->run(arg); }
static val_ptr eval_list(tree_ptr t) { element_ptr e = NULL; int n = darray_count(t->child); int i; for (i = 0; i < n; i++) { val_ptr x = tree_eval((tree_ptr)darray_at(t->child, i)); // TODO: Also check x is a multiz. if (v_error == x->type) { return x; } if (v_elem != x->type) { return val_new_error("element expected in list"); } if (!i) e = multiz_new_list(x->elem); else multiz_append(e, x->elem); } return val_new_element(e); }
static val_ptr v_def_call(val_ptr v, tree_ptr t) { int i; const char* name = ((tree_ptr)darray_at(v->def->child, 0))->id; darray_ptr parm = ((tree_ptr)darray_at(v->def->child, 1))->child; int n = darray_count(parm); if (1 + n != darray_count(t->child)) { return val_new_error("%s: wrong number of arguments", name); } for (i = 0; i < n; i++) { const char *id = ((tree_ptr)darray_at(parm, i))->id; val_ptr v1 = tree_eval((tree_ptr)darray_at(t->child, i)); // TODO: Stack frames for recursion. symtab_put(tab, v1, id); } // Evaluate function body. darray_ptr a = ((tree_ptr)darray_at(v->def->child, 2))->child; darray_forall(a, eval_stmt); return NULL; }
static val_ptr v_builtin(val_ptr v, tree_ptr t) { fun_ptr fun = v->fun; int n = fun->arity; if (1 + n != darray_count(t->child)) { return val_new_error("%s: wrong number of arguments", fun->name); } #ifdef _MSC_VER // for VC++ compatibility val_ptr arg[MAX_LIMBS]; #else val_ptr arg[n]; #endif int i; for (i = 0; i < n; i++) { arg[i] = tree_eval((tree_ptr)darray_at(t->child, i)); if (fun->sig[i] && arg[i]->type != fun->sig[i]) { return val_new_error("%s: argument %d type mismatch", fun->name, i + 1); } } return fun->run(arg); }
static val_ptr v_field_cast(val_ptr v, tree_ptr t) { // TODO: Check args, x is an element. val_ptr x = tree_eval(darray_at(t->child, 0)); element_ptr e = x->elem; if (e->field == M) { if (v->field == M) return x; element_ptr e2 = element_new(v->field); element_set_multiz(e2, e->data); x->elem = e2; return x; } if (v->field == M) { // Map to/from integer. TODO: Map to/from multiz instead. mpz_t z; mpz_init(z); element_to_mpz(z, e); element_clear(e); element_init(e, v->field); element_set_mpz(e, z); mpz_clear(z); } return x; }
static val_ptr eval_funcall(tree_ptr t) { val_ptr x = tree_eval((tree_ptr)darray_last(t->child)); return x->type->funcall(x, t); }
static void eval_stmt(void *ptr) { tree_eval((tree_ptr)ptr); }