ref: f5e054e36b30b4ef160f063c093be55e10585ed5
parent: 62bd41784b871d00d347787069cc31f4d5e41f4f
author: Ori Bernstein <ori@eigenstate.org>
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;