summaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/eval.c b/eval.c
index fb4ca4ce..76985a67 100644
--- a/eval.c
+++ b/eval.c
@@ -714,13 +714,27 @@ static val op_defun(val form, val env)
val body = rest(rest(args));
val block = cons(block_s, cons(name, body));
val fun = cons(name, cons(params, cons(block, nil)));
+ val iter;
+ val colon = nil;
if (!bindable(name))
eval_error(form, lit("defun: ~s is not a bindable sybol"), name, nao);
- if (!all_satisfy(params, func_n1(bindable), nil))
- eval_error(form, lit("defun: arguments must be bindable symbols"), nao);
+ for (iter = params; consp(iter); iter = cdr(iter)) {
+ val param = car(iter);
+ if (param == colon_k) {
+ if (colon)
+ eval_error(form, lit("defun: multiple colons in parameter list"), nao);
+ else
+ colon = t;
+ continue;
+ }
+ if (!bindable(param))
+ eval_error(form, lit("defun: parameter ~s is not a bindable symbol"), param, nao);
+ }
+ if (iter && !bindable(iter))
+ eval_error(form, lit("defun: dot parameter ~s is not a bindable symbol"), iter, nao);
/* defun captures lexical environment, so env is passed */
sethash(top_fb, name, cons(name, func_interp(env, fun)));