shithub: mc

Download patch

ref: 80ad746d8032274e2e6b40d3e4d801aa2085082d
parent: 17b5405f1035985d60539f7d777b77cf56e7231a
author: Ori Bernstein <ori@eigenstate.org>
date: Fri Aug 3 19:35:59 EDT 2018

Record the closure into all nested funcs.

	Funcs can go inside funcs.

--- a/parse/stab.c
+++ b/parse/stab.c
@@ -215,6 +215,16 @@
 	return vals;
 }
 
+static void
+envclose(Stab *start, Stab *found, Stab *fn, Node *s)
+{
+	Stab *st;
+
+	for (st = start; st != found; st = st->super)
+		if (st->env && !s->decl.isglobl && !s->decl.isgeneric)
+			htput(st->env, s->decl.name, s);
+}
+
 /*
  * Searches for declarations from current
  * scope, and all enclosing scopes. Doe
@@ -226,18 +236,17 @@
  * in the scope's closure.
  */
 Node *
-getdcl(Stab *st, Node *n)
+getdcl(Stab *start, Node *n)
 {
+	Stab *st, *fn;
 	Node *s;
-	Stab *fn;
 
 	fn = NULL;
+	st = start;
 	do {
 		s = htget(st->dcl, n);
 		if (s) {
-			/* record that this is in the closure of this scope */
-			if (fn && !s->decl.isglobl && !s->decl.isgeneric)
-				htput(fn->env, s->decl.name, s);
+			envclose(start, st, fn, s);
 			return s;
 		}
 		if (!fn && st->env)
--- /dev/null
+++ b/test/nestclosure.myr
@@ -1,0 +1,11 @@
+use std
+
+const main = {
+	var a = 1
+	var f = std.fndup({
+		{
+			std.put("{}\n", a)
+		}()
+	})
+	f()
+}
--- a/test/tests
+++ b/test/tests
@@ -64,6 +64,7 @@
 B nestfn	E	42
 B foldidx	P	123,456
 B closure	P	111555333666
+B nestclosure	P	1
 B closurerec	E	21
 B fncast	P	ok
 B loop		P	0123401236789