diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | src/primitives.c | 15 | ||||
| -rw-r--r-- | tests/error.lisp | 1 | ||||
| -rw-r--r-- | tests/let-binding.lisp | 25 |
4 files changed, 34 insertions, 8 deletions
@@ -7,3 +7,4 @@ compile_commands.json .cache todo fibo.lisp +debug.lisp diff --git a/src/primitives.c b/src/primitives.c index b66f357..899cbdd 100644 --- a/src/primitives.c +++ b/src/primitives.c @@ -359,9 +359,13 @@ static SExpRef build_function_env(Interp *interp, SExpRef func, SExpRef args) { SExpRef primitive_funcall(Interp *interp, SExpRef args, bool istail) { if (LENGTH(args) < 1) goto error; - args = lisp_eval_args(interp, args); - if (CTL_FL(args)) return args; - SExpRef ret = lisp_apply(interp, CAR(args), CDR(args), istail); + SExpRef evaled = lisp_eval_args(interp, args); + if (CTL_FL(evaled)) return evaled; + SExpRef fn = CAR(evaled); + SExpRef fnargs = CDR(evaled); + PUSH_REG(fn); + SExpRef ret = lisp_apply(interp, fn, fnargs, istail); + POP_REG(); return ret; error: return new_error(interp, "funcall: syntax error.\n"); @@ -392,7 +396,10 @@ SExpRef primitive_apply(Interp *interp, SExpRef args, bool istail) { args = lisp_eval_args(interp, args); if (CTL_FL(args)) return args; if (!lisp_check_list(interp, CADR(args))) goto error; - ret = lisp_apply(interp, CAR(args), CADR(args), istail); + SExpRef fn = CAR(args); + PUSH_REG(fn); + ret = lisp_apply(interp, fn, CADR(args), istail); + POP_REG(); return ret; error: return new_error(interp, "apply: syntax error.\n"); diff --git a/tests/error.lisp b/tests/error.lisp index e0e0c4a..c774622 100644 --- a/tests/error.lisp +++ b/tests/error.lisp @@ -1,4 +1,5 @@ (assert-error (error "")) +(assert-error (let ((x (error ""))) #t)) (assert-error (let () (error "") #t)) (assert-error (if (error "") #t #t)) (assert-error (and (error ""))) diff --git a/tests/let-binding.lisp b/tests/let-binding.lisp index 33d021e..eead06a 100644 --- a/tests/let-binding.lisp +++ b/tests/let-binding.lisp @@ -1,7 +1,24 @@ -(assert-error (let ((i 0)) (i > 4))) - -(assert (= 3 (let ((a 1) (b 2)) - (+ a b)))) + (assert (= 3 (+ a b)))) + +;; let is letrec by default +(let ((a 1) + (b (+ a 1))) + (assert (= 2 b))) + +(let ((my-evenp + (lambda (x) + (if (= x 0) + #t + (funcall my-oddp (- x 1))))) + (my-oddp + (lambda (x) + (if (= x 0) + #f + (funcall my-evenp (- x 1)))))) + (assert (funcall my-evenp 10)) + (assert (funcall my-oddp 9)) + (assert (not (funcall my-evenp 9))) + (assert (not (funcall my-oddp 10)))) |
