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
commit280221ed0e05d5a1c3887e088a2dfc6b292c8a63 (patch)
treee8993f1025f9cd70bf44e9957094d280b2ef3a00
parent441c92dbc628aa7e12411ec4aabc4b95f3cfeca4 (diff)
downloadtxr-280221ed0e05d5a1c3887e088a2dfc6b292c8a63.tar.gz
txr-280221ed0e05d5a1c3887e088a2dfc6b292c8a63.tar.bz2
txr-280221ed0e05d5a1c3887e088a2dfc6b292c8a63.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)))