diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-01-23 22:30:43 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-01-23 22:30:43 -0800 |
commit | 2177a9682d17b059987a5684ce36bfee8a8b07e1 (patch) | |
tree | 7eb565f098d4860a73aa7024768ddfc40a699285 | |
parent | 9968bec40de5a53d86607491594a339a1b92eb95 (diff) | |
download | txr-2177a9682d17b059987a5684ce36bfee8a8b07e1.tar.gz txr-2177a9682d17b059987a5684ce36bfee8a8b07e1.tar.bz2 txr-2177a9682d17b059987a5684ce36bfee8a8b07e1.zip |
bugfix: :whole and :form allow destructuring.
In bind_macro_params allow the argument of :whole and :form
to be a destructuring pattern. Yet, in expand_params, we
are wrongly requiring it to be a bindable symbol, thus
blocking the feature.
* eval.c (expand_opt_params_rec): Only require the argument
of a keyword to be a bindable symbol if that keyword is :env.
(expand_params_rec): Some refactoring here not to recursively
expand keyword as parameters, removing a hacky test in the
atom case. Also car_ex is renamed to param_ex. Other than
that, same fix as in expand_opt_params_rec.
-rw-r--r-- | eval.c | 26 |
1 files changed, 13 insertions, 13 deletions
@@ -821,7 +821,7 @@ static val expand_opt_params_rec(val params, val menv, if (!consp(cdr(params))) eval_error(form, lit("~s: ~s parameter requires name"), car(form), pair, nao); - if (!bindable(cadr(params))) + if (pair == env_k && !bindable(cadr(params))) eval_error(form, lit("~s: ~s parameter requires bindable symbol"), car(form), pair, nao); } else if (!bindable(pair)) { @@ -884,8 +884,6 @@ static val expand_params_rec(val params, val menv, if (!params) { return params; } else if (atom(params)) { - if (params == whole_k || params == form_k || params == env_k) - return params; if (!bindable(params)) not_bindable_error(form, params); if (special_var_p(params)) @@ -902,29 +900,31 @@ static val expand_params_rec(val params, val menv, eval_error(form, lit("~s: parameter symbol expected, not ~s"), car(form), car(params), nao); } else { - val car_ex = expand_params_rec(car(params), menv, - macro_style_p, - form, pspecials); + val param = car(params); + val param_ex; - if (car_ex == whole_k || car_ex == form_k || car_ex == env_k) { + if (param == whole_k || param == form_k || param == env_k) { if (!macro_style_p) eval_error(form, lit("~s: ~s not usable in function parameter list"), - car(form), car_ex, nao); + car(form), param, nao); if (!consp(cdr(params))) eval_error(form, lit("~s: ~s parameter requires name"), - car(form), car_ex, nao); - if (!bindable(cadr(params))) + car(form), param, nao); + if (param == env_k && !bindable(cadr(params))) eval_error(form, lit("~s: ~s parameter requires bindable symbol"), - car(form), car_ex, nao); + car(form), param, nao); + param_ex = param; + } else { + param_ex = expand_params_rec(param, menv, macro_style_p, form, pspecials); } { val params_ex = expand_params_rec(cdr(params), menv, macro_style_p, form, pspecials); - if (car_ex == car(params) && params_ex == cdr(params)) + if (param_ex == car(params) && params_ex == cdr(params)) return params; - return rlcp(cons(car_ex, params_ex), params); + return rlcp(cons(param_ex, params_ex), params); } } } |