summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2018-03-27 22:50:42 -0700
committerKaz Kylheku <kaz@kylheku.com>2018-03-27 22:50:42 -0700
commita23063a7caad00d990ca9ba3c239658280234a80 (patch)
treee8993f1025f9cd70bf44e9957094d280b2ef3a00
parent7e2689debbaf40c77ae572849b73e3821efb25da (diff)
downloadtxr-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.tl3
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)))