shithub: mc

Download patch

ref: f5e054e36b30b4ef160f063c093be55e10585ed5
parent: 62bd41784b871d00d347787069cc31f4d5e41f4f
author: Ori Bernstein <[email protected]>
date: Sun Mar 3 16:43:58 EST 2019

Merge envs correctly.

	Still a couple of straggling issues, but almost there.

--- a/parse/gram.y
+++ b/parse/gram.y
@@ -34,6 +34,7 @@
 static void installucons(Stab *, Type *);
 static void setattrs(Node *, char **attrs, size_t);
 static void setwith(Type *, Traitspec **, size_t);
+static void mergeenv(Node *, Node *);
 static void mangleautocall(Node *, char *);
 static void addinit(Node *, Node *);
 static void setuname(Type *);
@@ -424,8 +425,12 @@
 	}
 	;
 
-declbody: declcore Tasn expr {$$ = $1; $1->decl.init = $3;}
-	| declcore
+declbody: declcore
+	| declcore Tasn expr {
+		$$ = $1;
+		$1->decl.init = $3;
+		mergeenv($1, $3);
+	}
 	;
 
 declcore: name {$$ = mkdecl($1->loc, $1, mktyvar($1->loc));}
@@ -471,6 +476,7 @@
 		d->decl.init = $4;
 		d->decl.isconst = 1;
 		d->decl.isglobl = 1;
+		mergeenv(d, $4);
 		lappend(&$$.nl, &$$.nn, d);
 	}
 	;
@@ -1024,7 +1030,6 @@
 	| Tfor expr Tcolon exprln block
 	{$$ = mkiterstmt($1->loc, $2, $4, $5);}
 	| Tfor decl Tendln loopcond optexprln block {
-		//Node *init;
 		if ($2.nn != 1)
 			lfatal($1->loc, "only one declaration is allowed in for loop");
 		$$ = mkloopstmt($1->loc, $2.nl[0], $4, $5, $6);
@@ -1234,6 +1239,21 @@
 		}
 	}
 }
+
+static void
+mergeenv(Node *dcl, Node *init)
+{
+	Node *f;
+
+	if (init->type != Nexpr || exprop(init) != Olit)
+		return;
+	if (init->lit.littype != Lfunc)
+		return;
+	f = init->lit.fnval;
+	f->func.env = dcl->decl.env;
+	bindtype(dcl->decl.env, f->func.type);
+}
+
 
 static void
 installucons(Stab *st, Type *t)
--- a/parse/node.c
+++ b/parse/node.c
@@ -207,14 +207,10 @@
 	f->func.type = mktyfunc(loc, args, nargs, ret);
 	f->func.env = mkenv();
 
+	bindtype(f->func.env, f->func.type);
 	st = body->block.scope;
 	for (i = 0; i < nargs; i++)
 		putdcl(st, args[i]);
-
-	bindtype(f->func.env, ret);
-	for (i = 0; i < nargs; i++)
-		bindtype(f->func.env, decltype(args[i]));
-
 
 	n = mknode(loc, Nlit);
 	n->lit.littype = Lfunc;