diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-11-29 06:16:29 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-11-29 06:16:29 -0800 |
commit | 27e54c2db0cbb08b8cd4163c828e964dedd0e08f (patch) | |
tree | ccd0ba437a109472aae836e35f2ed7b1b52cf6dd /eval.c | |
parent | 87caead8269055b4791de53be0e03afab01f1dd4 (diff) | |
download | txr-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.c | 5 |
1 files changed, 3 insertions, 2 deletions
@@ -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); |