summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--stdlib/place.tl5
-rw-r--r--tests/012/struct.tl22
-rw-r--r--txr.130
3 files changed, 42 insertions, 15 deletions
diff --git a/stdlib/place.tl b/stdlib/place.tl
index fcc86735..b3b6395f 100644
--- a/stdlib/place.tl
+++ b/stdlib/place.tl
@@ -129,13 +129,14 @@
[sys:r-s-let-expander bindings body e 'let constantp])
(defmacro slet (bindings :env e . body)
- (sys:r-s-let-expander bindings body e 'let [orf constantp bindable]))
+ (sys:r-s-let-expander bindings body e 'let [orf constantp
+ (op lexical-var-p e)]))
(defmacro alet (bindings :env e . body)
(let ((exp-bindings (mapcar (aret ^(,@1 ,(macroexpand @2 e))) bindings)))
(if [some exp-bindings constantp second]
[sys:r-s-let-expander exp-bindings body e 'alet constantp]
- ^(,(if [all exp-bindings bindable second]
+ ^(,(if [all exp-bindings (op lexical-var-p e) second]
'symacrolet 'let)
,exp-bindings ,*body))))
diff --git a/tests/012/struct.tl b/tests/012/struct.tl
index bdff6311..93979786 100644
--- a/tests/012/struct.tl
+++ b/tests/012/struct.tl
@@ -28,32 +28,36 @@
(slot (slot (slot a 'b)
'c) 'd))
-(test (expand 's.a)
+(defmacro get-current-menv (:env e) e)
+(defvarl menv (let (s a b c d) (macro-time (get-current-menv))))
+
+(test (expand 's.a menv)
(slot s 'a))
-(test (expand 's.[a])
+(test (expand 's.[a] menv)
[(slot s 'a) s])
-(test (expand 's.[a b c])
+(test (expand 's.[a b c] menv)
[(slot s 'a) s b c])
(set *gensym-counter* 0)
-(stest (ignwarn (expand 's.(a)))
+
+(stest (ignwarn (expand 's.(a) menv))
"(call (slot s 'a)\n \
\ s)")
(set *gensym-counter* 0)
-(stest (ignwarn (expand 's.(a b c)))
+(stest (ignwarn (expand 's.(a b c) menv))
"(call (slot s 'a)\n \
\ s b c)")
-(test (expand 's.[a].b)
+(test (expand 's.[a].b menv)
(slot [(slot s 'a) s] 'b))
-(test (expand 's.[a b c].b)
+(test (expand 's.[a b c].b menv)
(slot [(slot s 'a) s b c] 'b))
(set *gensym-counter* 0)
-(stest (ignwarn (expand 's.(a).d))
+(stest (ignwarn (expand 's.(a).d menv))
"(slot (call (slot s 'a)\n \
\ s)\n \
\ 'd)")
(set *gensym-counter* 0)
-(stest (ignwarn (expand 's.(a b c).d))
+(stest (ignwarn (expand 's.(a b c).d menv))
"(slot (call (slot s 'a)\n \
\ s b c)\n \
\ 'd)")
diff --git a/txr.1 b/txr.1
index 3f585b29..cf6289d3 100644
--- a/txr.1
+++ b/txr.1
@@ -44223,8 +44223,30 @@ reduces bindings initialized by constant expressions
to symbol macros. In addition, unlike
.codn rlet ,
.code slet
-also reduces to symbol macros those bindings which
-are initialized by symbol expressions (values of variables).
+also reduces to symbol macros those bindings whose initializing
+expressions are simple references to lexical variables.
+
+.TP* Examples:
+
+.verb
+ ;; reduces to let
+ (slet ((a (list x y)))
+ a)
+
+ ;; b is a free variable, so this is also let
+ (slet ((a b))
+ a)
+
+ ;; b is lexical, so a becomes a symbol macro
+ ;; the (slet ...) form becomes b.
+ (let (b)
+ (slet ((a b))
+ a))
+
+ ;; a becomes symbol macro; form transforms to 1.
+ (slet ((a 1))
+ a)
+.brev
.coNP Macro @ alet
.synb
@@ -44237,7 +44259,7 @@ The macro
.code slet
macro. All bindings initialized by constant expressions are
turned to symbol macros. Then, if all of the remaining bindings are
-all initialized by symbol expressions, they are also turned to
+all initialized by lexical variables, they are also turned to
symbol macros. Otherwise, none of the remaining bindings
are turned to symbol macros.
@@ -44249,7 +44271,7 @@ others' evaluations. In this situation
.code alet
still propagates constants via symbol macros, and can eliminate the
remaining temporaries if they can all be made symbol macros for
-existing variables: i.e. there doesn't exist any initialization form
+existing lexicals: i.e. there doesn't exist any initialization form
with interfering side effects.
.coNP Macro @ define-accessor