summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2019-03-03 21:43:58 -0800
committerOri Bernstein <ori@eigenstate.org>2019-03-03 21:43:58 -0800
commitf5e054e36b30b4ef160f063c093be55e10585ed5 (patch)
treef89720f4fcfada1192b5eea3688600e42cbd2d53
parent62bd41784b871d00d347787069cc31f4d5e41f4f (diff)
downloadmc-f5e054e36b30b4ef160f063c093be55e10585ed5.tar.gz
Merge envs correctly.
Still a couple of straggling issues, but almost there.
-rw-r--r--parse/gram.y26
-rw-r--r--parse/node.c6
2 files changed, 24 insertions, 8 deletions
diff --git a/parse/gram.y b/parse/gram.y
index cbf3888..9fdfbf3 100644
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -34,6 +34,7 @@ static Node *mkpseudodecl(Srcloc, Type *);
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 @@ pkgtydef: attrs tydef {
}
;
-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 @@ implbody
d->decl.init = $4;
d->decl.isconst = 1;
d->decl.isglobl = 1;
+ mergeenv(d, $4);
lappend(&$$.nl, &$$.nn, d);
}
;
@@ -1024,7 +1030,6 @@ forstmt : Tfor optexprln loopcond optexprln block
| 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);
@@ -1236,6 +1241,21 @@ setwith(Type *ty, Traitspec **ts, size_t nts)
}
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)
{
Type *b;
diff --git a/parse/node.c b/parse/node.c
index 0bc31c0..85f1763 100644
--- a/parse/node.c
+++ b/parse/node.c
@@ -207,15 +207,11 @@ mkfunc(Srcloc loc, Node **args, size_t nargs, Type *ret, Node *body)
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;
n->lit.fnval = f;