shithub: mc

Download patch

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);