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_id(tree_ptr t) { val_ptr x = (val_ptr)symtab_at(reserved, t->id); if (!x) x = (val_ptr)symtab_at(tab, t->id); if (!x) { return val_new_error("undefined variable %s", t->id); } return x->type->eval(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; }
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_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 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; }