separate eval into eval and apply and do gc (oops)
This commit is contained in:
parent
2532dd9f4a
commit
0572264f76
3 changed files with 22 additions and 20 deletions
38
eval.c
38
eval.c
|
|
@ -171,6 +171,26 @@ V setupenv(O *env) {
|
|||
*env = cons(mkprim("if", prim_if), *env);
|
||||
}
|
||||
|
||||
O apply(O fn, O args, O env) {
|
||||
I k = kind(fn);
|
||||
switch (k) {
|
||||
case KIND_PRIM: {
|
||||
P *p = (P *)UNTAG(fn);
|
||||
return p->fn(args, env);
|
||||
}
|
||||
case KIND_CLOS: {
|
||||
H *h = UNBOX(fn);
|
||||
L *l = (L *)(h + 1);
|
||||
args = evallist(args, env);
|
||||
O nenv = bind(l->args, args, l->env);
|
||||
return eval(l->body, nenv);
|
||||
}
|
||||
default:
|
||||
fprintf(stderr, "tried to call non-function value\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
O eval(O obj, O env) {
|
||||
I k = kind(obj);
|
||||
|
||||
|
|
@ -194,23 +214,7 @@ O eval(O obj, O env) {
|
|||
O fn = eval(c->car, env);
|
||||
addroot(&fn);
|
||||
|
||||
I fk = kind(fn);
|
||||
O res = NIL;
|
||||
|
||||
if (fk == KIND_PRIM) {
|
||||
P *p = (P *)UNTAG(fn);
|
||||
res = p->fn(c->cdr, env);
|
||||
} else if (fk == KIND_CLOS) {
|
||||
H *h = UNBOX(fn);
|
||||
L *l = (L *)(h + 1);
|
||||
O args = evallist(c->cdr, env);
|
||||
O nenv = bind(l->args, args, l->env);
|
||||
res = eval(l->body, nenv);
|
||||
} else {
|
||||
fprintf(stderr, "tried to call non-function value\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
O res = apply(fn, c->cdr, env);
|
||||
rootreset(mark);
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue