aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--src/primitives.c15
-rw-r--r--tests/error.lisp1
-rw-r--r--tests/let-binding.lisp25
4 files changed, 34 insertions, 8 deletions
diff --git a/.gitignore b/.gitignore
index bc44abe..1b30c26 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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))))