ref: ae9a74441cba3160943ad18bf500781143bff096
parent: 80c52bc20a53ac4c1c304df7a1e470c0ab62c576
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Sep 12 04:35:08 EDT 2015
Allow 'var' in loop statements.
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -855,10 +855,14 @@
{$$ = mkloopstmt($1->loc, $2, $3, $4, $5);}
| Tfor expr Tin exprln block
{$$ = mkiterstmt($1->loc, $2, $4, $5);}
- /* FIXME: allow decls in for loops
- | Tfor decl Tendln optexprln optexprln block
- {$$ = mkloopstmt($1->loc, $2, $4, $5, $6);}
- */
+ | Tfor decl Tendln optexprln 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);
+ putdcl($$->loopstmt.scope, $2.nl[0]);
+ }
+
;
whilestmt
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -1651,11 +1651,14 @@
unify(st, n, type(st, n->ifstmt.cond), mktype(n->loc, Tybool));
break;
case Nloopstmt:
+ setsuper(n->loopstmt.scope, curstab());
+ pushstab(n->loopstmt.scope);
infernode(st, &n->loopstmt.init, ret, sawret);
infernode(st, &n->loopstmt.cond, NULL, sawret);
infernode(st, &n->loopstmt.step, ret, sawret);
infernode(st, &n->loopstmt.body, ret, sawret);
unify(st, n, type(st, n->loopstmt.cond), mktype(n->loc, Tybool));
+ popstab();
break;
case Niterstmt:
bound = NULL;
--- a/parse/node.c
+++ b/parse/node.c
@@ -146,6 +146,7 @@
n->loopstmt.cond = cond;
n->loopstmt.step = incr;
n->loopstmt.body = body;
+ n->loopstmt.scope = mkstab();
return n;
}
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -266,6 +266,7 @@
Node *cond;
Node *step;
Node *body;
+ Stab *scope;
} loopstmt;
struct {
--- a/parse/specialize.c
+++ b/parse/specialize.c
@@ -191,10 +191,12 @@
fixup(n->ifstmt.iffalse);
break;
case Nloopstmt:
+ pushstab(n->loopstmt.scope);
fixup(n->loopstmt.init);
fixup(n->loopstmt.cond);
fixup(n->loopstmt.step);
fixup(n->loopstmt.body);
+ popstab();
break;
case Niterstmt:
pushstab(n->iterstmt.body->block.scope);
@@ -290,10 +292,14 @@
r->ifstmt.iffalse = specializenode(n->ifstmt.iffalse, tsmap);
break;
case Nloopstmt:
+ r->loopstmt.scope = mkstab();
+ r->loopstmt.scope->super = curstab();
+ pushstab(r->loopstmt.scope);
r->loopstmt.init = specializenode(n->loopstmt.init, tsmap);
r->loopstmt.cond = specializenode(n->loopstmt.cond, tsmap);
r->loopstmt.step = specializenode(n->loopstmt.step, tsmap);
r->loopstmt.body = specializenode(n->loopstmt.body, tsmap);
+ popstab();
break;
case Niterstmt:
r->iterstmt.elt = specializenode(n->iterstmt.elt, tsmap);