diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2012-03-03 21:16:43 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2012-03-04 08:49:20 -0800 |
commit | f75994545cb88c6625e4122afa61fbbe1adeb081 (patch) | |
tree | c7206a6c009493b62313f34ae5f2deff58cc08cd /eval.c | |
parent | 66bcec2c491445a76b3ef63c53ed982b896cef00 (diff) | |
download | txr-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.c | 18 |
1 files changed, 16 insertions, 2 deletions
@@ -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))); |