summaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2012-03-03 21:16:43 -0800
committerKaz Kylheku <kaz@kylheku.com>2012-03-04 08:49:20 -0800
commitf75994545cb88c6625e4122afa61fbbe1adeb081 (patch)
treec7206a6c009493b62313f34ae5f2deff58cc08cd /eval.c
parent66bcec2c491445a76b3ef63c53ed982b896cef00 (diff)
downloadtxr-f75994545cb88c6625e4122afa61fbbe1adeb081.tar.gz
txr-f75994545cb88c6625e4122afa61fbbe1adeb081.tar.bz2
txr-f75994545cb88c6625e4122afa61fbbe1adeb081.zip
Version 60
* txr.c (version): Bumped. * txr.1: Bumped version and set date. * configure (txr_ver): Bumped. * RELNOTES: Updated. * txr.vim: Handle : symbol properly. * eval.c (op_defun): Bugfix: documentation says that defun supports the same parameter list as lambda, and that is the intent. But this was broken, since op_defun was expecting the parameter list to be a proper list containing only bindable symbols, ruling out the use of the consing dot for rest parameter as well as the colon keyword symbol for optional parmeters.
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)));