aboutsummaryrefslogtreecommitdiff
path: root/src/primitives.c
diff options
context:
space:
mode:
authorMistivia <i@mistivia.com>2025-06-20 15:11:20 +0800
committerMistivia <i@mistivia.com>2025-06-20 15:11:20 +0800
commit815b972460fb83267a719f82afd79c2abaac80cd (patch)
tree7dac972705ead6fc29520a9cb91982ef6b0e5c7f /src/primitives.c
parentf09b34f95134972ecb907dbef0a697f4fcc1abaf (diff)
defun
Diffstat (limited to 'src/primitives.c')
-rw-r--r--src/primitives.c38
1 files changed, 35 insertions, 3 deletions
diff --git a/src/primitives.c b/src/primitives.c
index 9554fb6..f423a6b 100644
--- a/src/primitives.c
+++ b/src/primitives.c
@@ -138,10 +138,42 @@ SExpRef primitive_while(Interp *interp, SExpRef args) {
error:
return new_error(interp, "while: syntax error.\n");
}
+
+SExpRef primitive_lambda(Interp *interp, SExpRef args) {
+ if (lisp_length(interp, args) < 2) goto error;
+ SExpRef env = CAR(interp->stack);
+ SExpRef param = CAR(args);
+ SExpRef body = CDR(args);
+ return new_lambda(interp, param, body, env);
+error:
+ return new_error(interp, "lambda: syntax error.\n");
+}
+
+SExpRef primitive_defun(Interp *interp, SExpRef args) {
+ if (lisp_length(interp, args) < 3) goto error;
+ if (CAR(interp->stack).idx != interp->top_level.idx) {
+ return new_error(interp, "defun: functions can only be defined in top level.\n");
+ }
+ SExpRef name = CAR(args);
+ if (VALTYPE(name) != kSymbolSExp) goto error;
+ SExpRef param = CADR(args);
+ SExpRef body = CDDR(args);
+ SExpRef function = new_lambda(interp, param, body, interp->top_level);
+ lisp_defun(interp, REF(name)->str, function);
+ return name;
+error:
+ return new_error(interp, "defun: syntax error.\n");
+}
+
+SExpRef primitive_function(Interp *interp, SExpRef args) {
+ if (lisp_length(interp, args) != 1) goto error;
+ if (VALTYPE(CAR(args)) != kSymbolSExp) goto error;
+ return lisp_lookup_func(interp, REF(CAR(args))->str);
+error:
+ return new_error(interp, "function: syntax error.\n");
+}
+
// TODO:
-// - while
-// - lambda
-// - defun
// - funcall
// - apply
// - defvar