ref: 58550115b787023de68c7f760e8dd68c7d57c719
parent: 778de2674cd8f3b2951e367482ef6e56f7382424
author: Ori Bernstein <[email protected]>
date: Sat Dec 28 09:35:44 EST 2013
Add parsing support for iter loops 'for expr in loop' syntax is now parsed, although we don't actually generate code for it.
--- a/myrtypes/myrtypes.c
+++ b/myrtypes/myrtypes.c
@@ -68,6 +68,11 @@
dumptypes(n->loopstmt.step, indent);
dumptypes(n->loopstmt.body, indent);
break;
+ case Niterstmt:
+ dumptypes(n->iterstmt.elt, indent);
+ dumptypes(n->iterstmt.seq, indent);
+ dumptypes(n->iterstmt.body, indent);
+ break;
case Nmatchstmt:
dumptypes(n->matchstmt.val, indent);
for (i = 0; i < n->matchstmt.nmatches; i++)
--- a/parse/dump.c
+++ b/parse/dump.c
@@ -161,6 +161,12 @@
outnode(n->loopstmt.step, fd, depth+1);
outnode(n->loopstmt.body, fd, depth+1);
break;
+ case Niterstmt:
+ fprintf(fd, "\n");
+ outnode(n->iterstmt.elt, fd, depth+1);
+ outnode(n->iterstmt.seq, fd, depth+1);
+ outnode(n->iterstmt.body, fd, depth+1);
+ break;
case Nmatchstmt:
fprintf(fd, "\n");
outnode(n->matchstmt.val, fd, depth+1);
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -77,6 +77,7 @@
%token<tok> Ttype /* type */
%token<tok> Tfor /* for */
+%token<tok> Tin /* in */
%token<tok> Twhile /* while */
%token<tok> Tif /* if */
%token<tok> Telse /* else */
@@ -689,6 +690,8 @@
forstmt : Tfor optexprln optexprln optexprln block
{$$ = mkloopstmt($1->line, $2, $3, $4, $5);}
+ | Tfor expr Tin exprln block
+ {$$ = mkiterstmt($1->line, $2, $4, $5);}
/* FIXME: allow decls in for loops
| Tfor decl Tendln optexprln optexprln block
{$$ = mkloopstmt($1->line, $2, $4, $5, $6);}
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -1317,6 +1317,12 @@
infernode(st, n->loopstmt.body, ret, sawret);
constrain(st, n, type(st, n->loopstmt.cond), cstrtab[Tctest]);
break;
+ case Niterstmt:
+ infernode(st, n->iterstmt.elt, NULL, sawret);
+ infernode(st, n->iterstmt.seq, NULL, sawret);
+ infernode(st, n->loopstmt.body, ret, sawret);
+ constrain(st, n, type(st, n->loopstmt.cond), cstrtab[Tctest]);
+ break;
case Nmatchstmt:
infernode(st, n->matchstmt.val, NULL, sawret);
if (tybase(type(st, n->matchstmt.val))->type == Tyvoid)
@@ -1617,6 +1623,11 @@
typesub(st, n->loopstmt.step);
typesub(st, n->loopstmt.body);
break;
+ case Niterstmt:
+ typesub(st, n->iterstmt.elt);
+ typesub(st, n->iterstmt.seq);
+ typesub(st, n->iterstmt.body);
+ break;
case Nmatchstmt:
typesub(st, n->matchstmt.val);
for (i = 0; i < n->matchstmt.nmatches; i++) {
@@ -1716,6 +1727,11 @@
nodetag(st, n->loopstmt.cond, ingeneric);
nodetag(st, n->loopstmt.step, ingeneric);
nodetag(st, n->loopstmt.body, ingeneric);
+ break;
+ case Niterstmt:
+ nodetag(st, n->iterstmt.elt, ingeneric);
+ nodetag(st, n->iterstmt.seq, ingeneric);
+ nodetag(st, n->iterstmt.body, ingeneric);
break;
case Nmatchstmt:
nodetag(st, n->matchstmt.val, ingeneric);
--- a/parse/node.c
+++ b/parse/node.c
@@ -119,6 +119,18 @@
return n;
}
+Node *mkiterstmt(int line, Node *elt, Node *seq, Node *body)
+{
+ Node *n;
+
+ n = mknode(line, Niterstmt);
+ n->iterstmt.elt = elt;
+ n->iterstmt.seq = seq;
+ n->iterstmt.body = body;
+
+ return n;
+}
+
Node *mkmatchstmt(int line, Node *val, Node **matches, size_t nmatches)
{
Node *n;
--- a/parse/nodes.def
+++ b/parse/nodes.def
@@ -3,6 +3,7 @@
N(Nblock)
N(Nifstmt)
N(Nloopstmt)
+N(Niterstmt)
N(Nmatchstmt)
N(Nmatch)
N(Nuse)
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -214,6 +214,12 @@
} loopstmt;
struct {
+ Node *elt;
+ Node *seq;
+ Node *body;
+ } iterstmt;
+
+ struct {
Node *cond;
Node *iftrue;
Node *iffalse;
@@ -401,6 +407,7 @@
Node *mkcall(int line, Node *fn, Node **args, size_t nargs);
Node *mkifstmt(int line, Node *cond, Node *iftrue, Node *iffalse);
Node *mkloopstmt(int line, Node *init, Node *cond, Node *incr, Node *body);
+Node *mkiterstmt(int line, Node *elt, Node *seq, Node *body);
Node *mkmatchstmt(int line, Node *val, Node **matches, size_t nmatches);
Node *mkmatch(int line, Node *pat, Node *body);
Node *mkblock(int line, Stab *scope);
--- a/parse/specialize.c
+++ b/parse/specialize.c
@@ -191,6 +191,11 @@
fixup(n->loopstmt.step);
fixup(n->loopstmt.body);
break;
+ case Niterstmt:
+ fixup(n->iterstmt.elt);
+ fixup(n->iterstmt.seq);
+ fixup(n->iterstmt.body);
+ break;
case Nmatchstmt:
fixup(n->matchstmt.val);
for (i = 0; i < n->matchstmt.nmatches; i++)
@@ -280,6 +285,11 @@
r->loopstmt.step = specializenode(n->loopstmt.step, tsmap);
r->loopstmt.body = specializenode(n->loopstmt.body, tsmap);
break;
+ case Niterstmt:
+ r->iterstmt.elt = specializenode(n->iterstmt.elt, tsmap);
+ r->iterstmt.seq = specializenode(n->iterstmt.seq, tsmap);
+ r->iterstmt.body = specializenode(n->iterstmt.body, tsmap);
+ break;
case Nmatchstmt:
r->matchstmt.val = specializenode(n->matchstmt.val, tsmap);
r->matchstmt.nmatches = n->matchstmt.nmatches;
@@ -336,30 +346,10 @@
}
return r;
}
-
-static size_t tidappend(char *buf, size_t sz, Type *t)
-{
- char *p;
- char *end;
- size_t i;
-
- p = buf;
- end = buf + sz;
- p += snprintf(p, end - p, "$%d", t->tid);
- if (t->type == Tyname) {
- for (i = 0; i < t->narg; i++)
- p += tidappend(p, end - p, t->arg[i]);
- } else {
- for (i = 0; i < t->nsub; i++)
- p += tidappend(p, end - p, t->sub[i]);
- }
- return p - buf;
-}
-
static Node *genericname(Node *n, Type *t)
{
char buf[1024];
- char *p;
+ char *p, *s;
char *end;
Node *name;
@@ -367,9 +357,10 @@
return n->decl.name;
p = buf;
end = buf + 1024;
+ s = tystr(t);
p += snprintf(p, end - p, "%s", n->decl.name->name.name);
- p += snprintf(p, end - p, "$%zd", n->decl.did);
- tidappend(p, end - p, t);
+ p += snprintf(p, end - p, "$%zd$%lu", n->decl.did, strhash(s));
+ free(s);
name = mkname(n->line, buf);
if (n->decl.name->name.ns)
setns(name, n->decl.name->name.ns);
@@ -387,6 +378,7 @@
Node *d;
Node *ns;
Stab *st;
+ extern int stabstkoff;
assert(n->type == Ndecl);
assert(n->decl.isgeneric);
@@ -394,7 +386,7 @@
*name = genericname(n, to);
d = getdcl(file->file.globls, *name);
if (debugopt['S'])
- printf("specializing %s => %s\n", namestr(n->decl.name), namestr(*name));
+ printf("depth[%d] specializing [%d]%s => %s\n", stabstkoff, n->line, namestr(n->decl.name), namestr(*name));
if (d)
return d;
/* namespaced names need to be looked up in their correct
--- a/parse/stab.c
+++ b/parse/stab.c
@@ -29,7 +29,7 @@
#define Maxstabdepth 128
static Stab *stabstk[Maxstabdepth];
-static int stabstkoff;
+int stabstkoff;
/* scope management */
Stab *curstab()
--- a/parse/tok.c
+++ b/parse/tok.c
@@ -171,6 +171,7 @@
{"generic", Tgeneric},
{"goto", Tgoto},
{"if", Tif},
+ {"in", Tin},
{"match", Tmatch},
{"pkg", Tpkg},
{"protect", Tprotect},
--- a/parse/use.c
+++ b/parse/use.c
@@ -414,6 +414,11 @@
pickle(n->loopstmt.step, fd);
pickle(n->loopstmt.body, fd);
break;
+ case Niterstmt:
+ pickle(n->iterstmt.elt, fd);
+ pickle(n->iterstmt.seq, fd);
+ pickle(n->iterstmt.body, fd);
+ break;
case Nmatchstmt:
pickle(n->matchstmt.val, fd);
wrint(fd, n->matchstmt.nmatches);
@@ -529,6 +534,11 @@
n->loopstmt.cond = unpickle(fd);
n->loopstmt.step = unpickle(fd);
n->loopstmt.body = unpickle(fd);
+ break;
+ case Niterstmt:
+ n->iterstmt.elt = unpickle(fd);
+ n->iterstmt.seq = unpickle(fd);
+ n->iterstmt.body = unpickle(fd);
break;
case Nmatchstmt:
n->matchstmt.val = unpickle(fd);