From 3540da57b77f4d13a1543d3bf335839ca3080988 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 2 Apr 2025 23:22:23 -0700 Subject: expander: expand arguments after hook processing. * eval.c (do_expand): Do not expand the arguments of a function call prior to checking for and dispatching the expand hook. The expand hook may rewrite the entire form and the arguments, so that those expansions are then thrown away. Not only is it wasteful to calculate them but possibly wrong. A form that is rewritten by a hook may have strange syntax, such that the hook itself will get confused if it is unleashed recursively on the constituent fragments of the syntax. --- eval.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/eval.c b/eval.c index 9cb982b3..7b485e6f 100644 --- a/eval.c +++ b/eval.c @@ -5458,20 +5458,7 @@ again: val insym = first(form_ex); val insym_ex = insym; val args = rest(form_ex); - val args_ex = expand_forms(args, menv); - - if (sym == setq_s) { - syn_check(form, sym, cddr, cdddr); - - { - val target = car(args_ex); - - if (!consp(target) || car(target) != var_s) { - if (!bindable(target)) - not_bindable_warning(form, car(args_ex)); - } - } - } + val args_ex; if (sym == return_s) syn_check(form, sym, identity, cddr); @@ -5508,6 +5495,21 @@ again: } } + args_ex = expand_forms(args, menv); + + if (sym == setq_s) { + syn_check(form, sym, cddr, cdddr); + + { + val target = car(args_ex); + + if (!consp(target) || car(target) != var_s) { + if (!bindable(target)) + not_bindable_warning(form, car(args_ex)); + } + } + } + if (insym_ex == rcons_s && proper_list_p(args_ex) && length(args_ex) == two && constantp_noex(car(args_ex)) && -- cgit v1.2.3