summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2025-04-02 23:22:23 -0700
committerKaz Kylheku <kaz@kylheku.com>2025-04-02 23:22:23 -0700
commit3540da57b77f4d13a1543d3bf335839ca3080988 (patch)
tree7f61397e3d1c1ff91990f8226e0fe0be8f3f0a8c
parent7e37d257c80cf7160502df232e3cbed538211b3e (diff)
downloadtxr-3540da57b77f4d13a1543d3bf335839ca3080988.tar.gz
txr-3540da57b77f4d13a1543d3bf335839ca3080988.tar.bz2
txr-3540da57b77f4d13a1543d3bf335839ca3080988.zip
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.
-rw-r--r--eval.c30
1 files 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)) &&