diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2022-11-10 08:11:33 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2022-11-10 08:11:33 -0800 |
commit | b66440298629c45c4323af6ee6bc19482b83d523 (patch) | |
tree | 4153fbd04223977dfd4b948fb6db3761c002c942 /txr.1 | |
parent | 3fcc1b8b1b826d689ace5e3b98be10a46bf4ae56 (diff) | |
download | txr-b66440298629c45c4323af6ee6bc19482b83d523.tar.gz txr-b66440298629c45c4323af6ee6bc19482b83d523.tar.bz2 txr-b66440298629c45c4323af6ee6bc19482b83d523.zip |
read-once: support globals properly.
When a global variable v is wrapped with (read-once v),
multiple accesses to the place still generate
multiple accesses of the global through getv or getlx
instructions. The reason is that the alet and slet
macros optimize away a temporary bound to the value of
a variable regardless of whether the variable is lexical.
Let's fix that.
* stdlib/place.tl (slet, alet): Replace the bindable test
with lexical-var-p, in the given environment. A binding
to a variable is only alias-like if the variable is
lexical, otherwise we need a real temporary.
* tests/012/struct.tl (get-current-menv): New macro.
(menv): New global variable. Fix a number of tests which
use expand, whose expansion has changed because the
expressions refer to free variables. We introduce an
environment parameter which binds all the variables, so
that the optimized expansion is produced, as before.
* txr.1: Updated documentation. slet gets examples.
Diffstat (limited to 'txr.1')
-rw-r--r-- | txr.1 | 30 |
1 files changed, 26 insertions, 4 deletions
@@ -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 |