diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2018-03-27 22:50:42 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2018-03-27 22:50:42 -0700 |
commit | a23063a7caad00d990ca9ba3c239658280234a80 (patch) | |
tree | e8993f1025f9cd70bf44e9957094d280b2ef3a00 | |
parent | 7e2689debbaf40c77ae572849b73e3821efb25da (diff) | |
download | txr-a23063a7caad00d990ca9ba3c239658280234a80.tar.gz txr-a23063a7caad00d990ca9ba3c239658280234a80.tar.bz2 txr-a23063a7caad00d990ca9ba3c239658280234a80.zip |
compiler: bugfix in let.
Very similar issue to the sys:fbind issue fixed some commits
ago. When we are setting up parallel bindings, we don't want
to compile initforms in the original env, because then they
get the same frame level as the new env we are compiling. Thus
(let ((x (let (...)))) ...) is mistranslated. Both lets,
have environments which are siblings of the same parent env,
which puts them on the same level. But their lifetimes at
run-time are nested, so they cannot share the same level.
The VM caught this since frame instructions declare their
absolute level and it must be one higher than the current
level. (I had the foresight to predict this might be a source
of problems and put in the checks.)
* share/txr/stdlib/compiler.tl (compiler comp-let): Same trick
as in sys:fbind case: set up an empty environment above the
initforms, so when an initform creates an environment, it is a
granddaughter of env, and thus a niece rather than sister of
of nenv, consequenty one frame level higher.
-rw-r--r-- | share/txr/stdlib/compiler.tl | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/share/txr/stdlib/compiler.tl b/share/txr/stdlib/compiler.tl index 6a778ed7..6f0211ad 100644 --- a/share/txr/stdlib/compiler.tl +++ b/share/txr/stdlib/compiler.tl @@ -566,7 +566,8 @@ (frsize (len lexsyms)) (seq (eq sym 'let*)) (nenv (new env up env co me)) - (fenv (if seq nenv env))) + (eenv (unless seq (new env up env co me))) + (fenv (if seq nenv eenv))) (unless seq (each ((lsym lexsyms)) nenv.(extend-var lsym))) |