summaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-12-14 20:03:39 -0800
committerKaz Kylheku <kaz@kylheku.com>2015-12-14 20:03:39 -0800
commitd4e6090d6f5d38e2901686d3b37c19da3ce7d6fa (patch)
treebcbc5e2756c7cb4a2eed018d9bc16cd2a4aa7345 /eval.c
parenta1dbd3f219a2ad552de98d5e9e7b28af975ab47d (diff)
downloadtxr-d4e6090d6f5d38e2901686d3b37c19da3ce7d6fa.tar.gz
txr-d4e6090d6f5d38e2901686d3b37c19da3ce7d6fa.tar.bz2
txr-d4e6090d6f5d38e2901686d3b37c19da3ce7d6fa.zip
Allow :whole and :form to do destructuring.
* eval.c (bind_macro_params): Remove the restriction that the :whole and :form do not allow a destructuring pattern, requring strictly a symbol. Common Lisp's &whole also does destructuring. As a side effect of this change, the :env parameter also supports destructuring, thought this isn't going to be meaningful since macro environments aren't lists.
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/eval.c b/eval.c
index 07ce4ff6..36228f1e 100644
--- a/eval.c
+++ b/eval.c
@@ -864,20 +864,28 @@ static val bind_macro_params(val env, val menv, val params, val form,
if (param == whole_k || param == form_k || param == env_k) {
val nparam;
val next = cdr(params);
+ val bform = if3(param == whole_k, whole,
+ if3(param == form_k,
+ ctx_form, menv));
if (!next)
eval_error(ctx_form, lit("~s: dangling ~s in param list"),
car(ctx_form), param, nao);
nparam = car(next);
- if (!bindable(nparam)) {
+
+ if (bindable(nparam)) {
+ env_vbind_special(new_env, nparam,
+ bform,
+ specials);
+ } else if (consp(nparam)) {
+ new_env = bind_macro_params(new_env, menv,
+ nparam, bform,
+ loose_p, ctx_form);
+ if (!new_env)
+ goto nil_out;
+ } else {
err_sym = nparam;
goto nbind;
}
- env_vbind_special(new_env, nparam,
- if3(param == whole_k,
- whole,
- if3(param == form_k,
- ctx_form, menv)),
- specials);
params = cdr(next);
continue;
}