diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2018-02-15 12:24:25 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2018-02-15 12:24:25 -0800 |
commit | 5601f8dc37301359a00a1a253ce97178615a8a27 (patch) | |
tree | 1d9439d04cc9bf225e0a382e7533710b6ec84106 | |
parent | f4fa550bf913bc0f559de1b9194764741f00871e (diff) | |
download | txr-5601f8dc37301359a00a1a253ce97178615a8a27.tar.gz txr-5601f8dc37301359a00a1a253ce97178615a8a27.tar.bz2 txr-5601f8dc37301359a00a1a253ce97178615a8a27.zip |
bugfix: broken expansion of sys:lisp1-setq places.
This bug shows up as a spurious warning and incorrect
expansion from a from like (do set [@1 x] y).
In this situation, sys:lisp1-setq is involved in the
assignment to the place denoted by @1, because of the way the
do operator expands the (set [@1 x] y) expression. The @1
meta-variable is replaced by a gensym, but some intermediate
expansion takes place in an environment which has no binding
for the gensym, causing the place to be treated as if it were
a global variable, using sys:lisp1-setq. The subsequent real
expansion in the environment in which the gensym is now bound
then calls upon the expansion of sys:lisp1-setq, which
proceeds via the expand_lisp1_setq function. But now the
variable has a lexical binding.
This bug doesn't show up in ordinary expressions like
(set [foo x] y) which is why it went undetected for a year.
* eval.c (expand_lisp1_setq): Fix the missing symbol in
the generated code for the case when the symbol has a lexical
variable binding. We must emit (sys:setq <sym> <value>), not
(sys:setq <new-value>).
-rw-r--r-- | eval.c | 2 |
1 files changed, 1 insertions, 1 deletions
@@ -2237,7 +2237,7 @@ static val expand_lisp1_setq(val form, val menv) } if (binding_type == var_k) - return expand(rlcp(cons(setq_s, cddr(form)), form), menv); + return expand(rlcp(cons(setq_s, cons(sym, cddr(form))), form), menv); if (binding_type == fun_k) eval_error(form, lit("~s: cannot assign lexical function ~s"), op, sym, nao); |