summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-01-23 22:30:43 -0800
committerKaz Kylheku <kaz@kylheku.com>2017-01-23 22:30:43 -0800
commit2177a9682d17b059987a5684ce36bfee8a8b07e1 (patch)
tree7eb565f098d4860a73aa7024768ddfc40a699285
parent9968bec40de5a53d86607491594a339a1b92eb95 (diff)
downloadtxr-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.c26
1 files changed, 13 insertions, 13 deletions
diff --git a/eval.c b/eval.c
index d3884a19..3a5cd547 100644
--- a/eval.c
+++ b/eval.c
@@ -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);
}
}
}