diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/interp.c | 8 | ||||
| -rw-r--r-- | src/primitives.c | 5 |
2 files changed, 13 insertions, 0 deletions
diff --git a/src/interp.c b/src/interp.c index 80ddfed..65eeaff 100644 --- a/src/interp.c +++ b/src/interp.c @@ -478,6 +478,13 @@ SExpRef lisp_macroexpand1(Interp *interp, SExpRef macro, SExpRef args) { PUSH_REG(fn); SExpRef ret = lisp_apply(interp, fn, args, false); POP_REG(); + while (VALTYPE(ret) == kTailcallSExp) { + fn = REF(ret)->tailcall.fn; + args = REF(ret)->tailcall.args; + PUSH_REG(ret); + ret = lisp_apply(interp, fn, args, false); + POP_REG(); + } return ret; error: return new_error(interp, "macroexpand: syntax error.\n"); @@ -734,6 +741,7 @@ end: return ret; } + SExpRef lisp_eval(Interp *interp, SExpRef sexp, bool istail) { if (interp->recursion_depth > 2048) { return new_error(interp, "eval: stack overflow.\n"); diff --git a/src/primitives.c b/src/primitives.c index 5f70f09..8e56bf9 100644 --- a/src/primitives.c +++ b/src/primitives.c @@ -198,6 +198,11 @@ SExpRef primitive_let(Interp *interp, SExpRef args, bool istail) { } body = CDR(args); + if (istail) { + SExpRef closure = new_lambda(interp, NIL, body, env); + ret = new_tailcall(interp, closure, NIL); + goto end; + } iter = body; while (!NILP(iter)) { exp = CAR(iter); |
