summaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-11-29 06:16:29 -0800
committerKaz Kylheku <kaz@kylheku.com>2017-11-29 06:16:29 -0800
commit27e54c2db0cbb08b8cd4163c828e964dedd0e08f (patch)
treeccd0ba437a109472aae836e35f2ed7b1b52cf6dd /eval.c
parent87caead8269055b4791de53be0e03afab01f1dd4 (diff)
downloadtxr-27e54c2db0cbb08b8cd4163c828e964dedd0e08f.tar.gz
txr-27e54c2db0cbb08b8cd4163c828e964dedd0e08f.tar.bz2
txr-27e54c2db0cbb08b8cd4163c828e964dedd0e08f.zip
bugfix: code-walk the result of a declined macro.
When a form is a macro, but the macro declines to expand the form, the form must still be code walked; we can't just return it and be done. For instance if it is a function call, its argument expressions have to be expanded. This also causes undefined function warning to be generated properly if a macro declines, and the resulting form is a function call to a not-yet-defined function. * eval.c (do_expand): If expand_macro yields the original form, branch backwards to re-execute the whole if statement again. Use the fact that the local variable macro is now non-nil to skip the macro expansion case.
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/eval.c b/eval.c
index ab7518f6..5dc34960 100644
--- a/eval.c
+++ b/eval.c
@@ -4063,6 +4063,7 @@ static val do_expand(val form, val menv)
menv = default_null_arg(menv);
+again:
if (nilp(form)) {
return nil;
} else if (bindable(form)) {
@@ -4341,10 +4342,10 @@ static val do_expand(val form, val menv)
return rlcp(cons(sym, args_ex), form);
} else if (sym == switch_s) {
return expand_switch(form, menv);
- } else if ((macro = lookup_mac(menv, sym))) {
+ } else if (!macro && (macro = lookup_mac(menv, sym))) {
val mac_expand = expand_macro(form, macro, menv);
if (mac_expand == form)
- return form;
+ goto again;
return expand(rlcp_tree(rlcp_tree(mac_expand, form), macro), menv);
} else if (sym == progn_s) {
val args = rest(form);