diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-09-15 06:15:23 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-09-15 06:15:23 -0700 |
commit | d92b5bc1203e5d9a928a3c1da1e5708a7afdafea (patch) | |
tree | 7c210f66fabac8e3894d4153b3f392a0e532828c | |
parent | 146e6c338ef0226f1742a48fb33d8738f2769f93 (diff) | |
download | txr-d92b5bc1203e5d9a928a3c1da1e5708a7afdafea.tar.gz txr-d92b5bc1203e5d9a928a3c1da1e5708a7afdafea.tar.bz2 txr-d92b5bc1203e5d9a928a3c1da1e5708a7afdafea.zip |
places: use Lisp-1 macroexpansion where needed.
A test case for this very subtle bug is this:
(let ((v (list 1 2 3)))
(symacrolet ((x v))
(flet ((x () 42))
(set [x 0] 0))))
Because x is being evaluated in the DWIM brackets which
flatten the two namespaces into one, it must be treated as a
reference to the flet, and so [x 0] denotes the function call.
The assignment is erroneous.
The incorrect behavior being fixed is that the places code
macro-expands x in the Lisp-2 style under which the symacrolet
is not shadowed by the flet. The substitution of v takes
place, and the assignment assigns to [v 0].
* share/txr/stdlib/place.tl (sys:l1-setq, sys:l1-val):
Use macroexpand-lisp1 rather than macroexpand.
-rw-r--r-- | share/txr/stdlib/place.tl | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/share/txr/stdlib/place.tl b/share/txr/stdlib/place.tl index 2ae0d839..9621269b 100644 --- a/share/txr/stdlib/place.tl +++ b/share/txr/stdlib/place.tl @@ -35,7 +35,7 @@ (throwf 'eval-error . params)) (defmacro sys:l1-setq (u-expr new-val :env e) - (let ((e-expr (macroexpand u-expr e))) + (let ((e-expr (macroexpand-lisp1 u-expr e))) (if (symbolp e-expr) (caseq (lexical-lisp1-binding e e-expr) (:var ^(sys:setq ,e-expr ,new-val)) @@ -46,7 +46,7 @@ ^(set ,u-expr ,new-val)))) (defmacro sys:l1-val (u-expr :env e) - (let ((e-expr (macroexpand u-expr e))) + (let ((e-expr (macroexpand-lisp1 u-expr e))) (if (and (symbolp e-expr) (not (constantp e-expr))) (caseq (lexical-lisp1-binding e e-expr) (:fun ^(fun ,e-expr)) |