aboutsummaryrefslogtreecommitdiff
path: root/src/primitives.c
diff options
context:
space:
mode:
authorMistivia <i@mistivia.com>2025-07-01 12:10:11 +0800
committerMistivia <i@mistivia.com>2025-07-01 12:10:11 +0800
commit7dfaa40719c5a264b17aca96cd85e31bf7b8b557 (patch)
tree17c2cb2919393fc89620efb38495121950cf77cf /src/primitives.c
parent6d89e9697b1740366f23387964122d264475b49c (diff)
extend defun
Diffstat (limited to 'src/primitives.c')
-rw-r--r--src/primitives.c33
1 files changed, 22 insertions, 11 deletions
diff --git a/src/primitives.c b/src/primitives.c
index 0eadbb7..73812b8 100644
--- a/src/primitives.c
+++ b/src/primitives.c
@@ -321,17 +321,28 @@ error:
SExpRef primitive_defun(Interp *interp, SExpRef args, bool istail) {
SExpRef name, param, body, function;
- if (LENGTH(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");
- }
- name = CAR(args);
- if (VALTYPE(name) != kSymbolSExp) goto error;
- param = CADR(args);
- body = CDDR(args);
- function = new_lambda(interp, param, body, interp->top_level);
- lisp_defun(interp, name, function);
- return name;
+ if (LENGTH(args) == 2) {
+ if (CAR(interp->stack).idx != interp->top_level.idx) {
+ return new_error(interp, "defun: functions can only be defined in top level.\n");
+ }
+ name = CAR(args);
+ if (VALTYPE(name) != kSymbolSExp) goto error;
+ function = EVAL(CADR(args));
+ if (!CALLABLE(function)) goto error;
+ lisp_defun(interp, name, function);
+ return name;
+ } else if (LENGTH(args) >= 3) {
+ if (CAR(interp->stack).idx != interp->top_level.idx) {
+ return new_error(interp, "defun: functions can only be defined in top level.\n");
+ }
+ name = CAR(args);
+ if (VALTYPE(name) != kSymbolSExp) goto error;
+ param = CADR(args);
+ body = CDDR(args);
+ function = new_lambda(interp, param, body, interp->top_level);
+ lisp_defun(interp, name, function);
+ return name;
+ } else goto error;
error:
return new_error(interp, "defun: syntax error.\n");
}