summaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2018-03-13 20:23:18 -0700
committerKaz Kylheku <kaz@kylheku.com>2018-03-13 20:23:18 -0700
commitd32527312c4467817eef8527907fccb3cc5ed42a (patch)
tree81a176256dbb27e6e58ea3038631029dd6b3676f /eval.c
parentf3fddb31b01d7f015d9f35b6c6312fad28177ae4 (diff)
downloadtxr-d32527312c4467817eef8527907fccb3cc5ed42a.tar.gz
txr-d32527312c4467817eef8527907fccb3cc5ed42a.tar.bz2
txr-d32527312c4467817eef8527907fccb3cc5ed42a.zip
expander bug: sequential vars with no init forms.
The test case for this is (let* (a (b a))) which raises suspicion by diagnosing an "unbound variable a" error against the (b a) var-init pair. The error goes away if we make it (let* ((a nil) (b a))), a perfectly equivalent form. The diagnostic is just a symptom; the problem is that in the case when a doesn't have an initform, the (b a) var-init pair is being incorrectly expanded in an environment that hasn't been extended with the a variable. * eval.c (expand_vars): In the sequential binding situation (let*), we must extend the environment for each variable in the no-init-form case exactly as we do in the with-init-form case.
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/eval.c b/eval.c
index 4731c046..85ede40c 100644
--- a/eval.c
+++ b/eval.c
@@ -3355,7 +3355,8 @@ static val expand_vars(val vars, val menv, val form, int seq_p)
return vars;
} else if (symbolp(sym = car(vars))) {
val rest_vars = rest(vars);
- val rest_vars_ex = expand_vars(rest_vars, menv, form, seq_p);
+ val menv_new = seq_p ? make_var_shadowing_env(menv, cons(sym, nil)) : menv;
+ val rest_vars_ex = expand_vars(rest_vars, menv_new, form, seq_p);
if (!bindable(sym))
not_bindable_error(form, sym);