summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-02-28 00:56:33 -0800
committerKaz Kylheku <kaz@kylheku.com>2014-02-28 00:56:33 -0800
commita9e06b4e815240f7f954d237f8625c30338be55f (patch)
treee8239869b0ea540e42b7083f95e3b60a61eff53b
parent9caae19a42d87582a82c3d855b7dc59fe6427e7b (diff)
downloadtxr-a9e06b4e815240f7f954d237f8625c30338be55f.tar.gz
txr-a9e06b4e815240f7f954d237f8625c30338be55f.tar.bz2
txr-a9e06b4e815240f7f954d237f8625c30338be55f.zip
Bugfixing semantics of symbol macro hiding by variable bindings.
* eval.c (expand_vars): Expand vars needs to know whether it's handling a sequential (let*-like) or parallel (let-like) binding. The init form of a variable sees the previous macro environment, but that variable must, for the remaining variables, shadow any previous symbol macro. (expand): In expand we must inform expand_vars whether we have a sequential or parallel binding construct. Moreover, there was a huge bug here: the new_menv (with the shadows) was passed to expand_vars, so that all the variables were hiding same-named symbol macros from all their initforms.
-rw-r--r--ChangeLog15
-rw-r--r--eval.c22
2 files changed, 31 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 9cef4a5d..e3fc9541 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2014-02-28 Kaz Kylheku <kaz@kylheku.com>
+
+ Bugfixing semantics of symbol macro hiding by variable bindings.
+
+ * eval.c (expand_vars): Expand vars needs to know whether it's
+ handling a sequential (let*-like) or parallel (let-like) binding.
+ The init form of a variable sees the previous macro environment,
+ but that variable must, for the remaining variables, shadow any
+ previous symbol macro.
+ (expand): In expand we must inform expand_vars whether we have
+ a sequential or parallel binding construct. Moreover, there was
+ a huge bug here: the new_menv (with the shadows) was passed to
+ expand_vars, so that all the variables were hiding same-named
+ symbol macros from all their initforms.
+
2014-02-27 Kaz Kylheku <kaz@kylheku.com>
* eval.c (delay_s): Global variable removed.
diff --git a/eval.c b/eval.c
index bc01cdf3..a5b5aba5 100644
--- a/eval.c
+++ b/eval.c
@@ -2070,7 +2070,8 @@ static val me_qquote(val form, val menv)
return expand_qquote(second(form), menv);
}
-static val expand_vars(val vars, val menv, val form, val *spec_p)
+static val expand_vars(val vars, val menv, val form,
+ val *spec_p, int seq_p)
{
val sym;
@@ -2082,21 +2083,27 @@ static val expand_vars(val vars, val menv, val form, val *spec_p)
return vars;
} else if (special_p(sym = car(vars))) {
val rest_vars = rest(vars);
- val rest_vars_ex = rlcp(expand_vars(rest_vars, menv, form, spec_p),
+ val rest_vars_ex = rlcp(expand_vars(rest_vars, menv, form, spec_p, seq_p),
rest_vars);
val var_ex = cons(special_s, cons(nil, cons(sym, nil)));
return rlcp(cons(var_ex, rest_vars_ex), vars);
} else if (symbolp(sym)) {
val rest_vars = rest(vars);
- val rest_vars_ex = expand_vars(rest_vars, menv, form, spec_p);
+ val rest_vars_ex = expand_vars(rest_vars, menv, form, spec_p, seq_p);
if (rest_vars == rest_vars_ex)
return vars;
return rlcp(cons(sym, rest_vars_ex), vars);
} else {
cons_bind (var, init, sym);
val rest_vars = rest(vars);
+ /* This var's init form sees a previous symbol macro whose name is
+ the same as the variable, so menv is used. */
val init_ex = rlcp(expand_forms(init, menv), init);
- val rest_vars_ex = rlcp(expand_vars(rest_vars, menv, form, spec_p),
+ /* The initforms of subsequent vars in a sequential binding
+ do not see a previous symbol macro; they see the var. */
+ val menv_new = seq_p ? make_var_shadowing_env(menv, cons(var, nil)) : menv;
+ val rest_vars_ex = rlcp(expand_vars(rest_vars, menv_new, form,
+ spec_p, seq_p),
rest_vars);
if (special_p(var)) {
@@ -2343,10 +2350,12 @@ tail:
{
val body = rest(rest(form));
val vars = second(form);
+ int seq_p = sym == let_star_s || sym == each_star_s ||
+ sym == collect_each_star_s || sym == append_each_star_s;
val new_menv = make_var_shadowing_env(menv, vars);
val body_ex = expand_forms(body, new_menv);
val specials_p = nil;
- val vars_ex = expand_vars(vars, new_menv, form, &specials_p);
+ val vars_ex = expand_vars(vars, menv, form, &specials_p, seq_p);
if (body == body_ex && vars == vars_ex && !specials_p) {
return form;
} else {
@@ -2431,7 +2440,8 @@ tail:
val incs = fourth(form);
val forms = rest(rest(rest(rest(form))));
val specials_p = nil;
- val vars_ex = expand_vars(vars, menv, form, &specials_p);
+ val vars_ex = expand_vars(vars, menv, form, &specials_p,
+ sym == for_star_s);
val new_menv = make_var_shadowing_env(menv, vars);
val cond_ex = expand_forms(cond, new_menv);
val incs_ex = expand_forms(incs, new_menv);