shithub: mc

Download patch

ref: 2bad0c45ccc1489cbba946ee04787e9f9a48eff8
parent: da4e9c9216aeb8455dfd972956e29942fd9d4690
author: Ori Bernstein <[email protected]>
date: Sun Jun 24 09:04:55 EDT 2012

Fixup dids in generics.

    We need to make sure that they're unique AND correctly
    mapped. Do this.

binary files a/8/8m b/8/8m differ
--- a/parse/dump.c
+++ b/parse/dump.c
@@ -116,7 +116,8 @@
                 outnode(n->file.stmts[i], fd, depth + 1);
             break;
         case Ndecl:
-            fprintf(fd, "\n");
+            fprintf(fd, "(did = %zd, isconst = %d, isgeneric = %d, isextern = %d\n",
+                    n->decl.did, n->decl.isconst, n->decl.isgeneric, n->decl.isextern);
             outsym(n, fd, depth + 1);
             outnode(n->decl.init, fd, depth + 1);
             break;
@@ -143,7 +144,8 @@
             break;
         case Nexpr:
             ty = tystr(n->expr.type);
-            fprintf(fd, " (type = %s, op = %s, flags = %d)\n", ty, opstr(n->expr.op), n->expr.isconst);
+            fprintf(fd, " (type = %s, op = %s, flags = %d, did=%zd)\n",
+                    ty, opstr(n->expr.op), n->expr.isconst, n->expr.did);
             free(ty);
             for (i = 0; i < n->expr.nargs; i++)
                 outnode(n->expr.args[i], fd, depth+1);
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -571,7 +571,6 @@
     htput(bt, t->pname, t);
     for (i = 0; i < t->nsub; i++)
         tybind(bt, t->sub[i]);
-    printf("Bound @%s\n", t->pname);
 }
 
 static void bind(Node *n)
--- a/parse/specialize.c
+++ b/parse/specialize.c
@@ -69,7 +69,6 @@
     size_t i;
 
     if (from->type == Typaram) {
-        printf("Specialize %s => %s\n", tystr(from), tystr(to));
         htput(tsmap, from, to);
     }
     if (to->nsub != from->nsub)
@@ -78,6 +77,66 @@
         fillsubst(tsmap, to->sub[i], from->sub[i]);
 }
 
+static void fixup(Node *n)
+{
+    size_t i;
+    Node *d;
+
+    if (!n)
+        return;
+    switch (n->type) {
+        case Nfile:
+        case Nuse:
+            die("Node %s not allowed here\n", nodestr(n->type));
+            break;
+        case Nexpr:
+            for (i = 0; i < n->expr.nargs; i++)
+                fixup(n->expr.args[i]);
+            if (n->expr.op == Ovar) {
+                d = getdcl(curstab(), n->expr.args[0]);
+                if (!d)
+                    die("Missing decl %s\n", namestr(n->expr.args[0]));
+                n->expr.did = d->decl.did;
+            }
+            break;
+        case Nlit:
+            switch (n->lit.littype) {
+                case Lfunc:     fixup(n->lit.fnval);          break;
+                case Larray:    fixup(n->lit.arrval);         break;
+                case Lchr: case Lint: case Lflt: case Lstr: case Lbool:
+                    break;
+            }
+            break;
+        case Nloopstmt:
+            fixup(n->loopstmt.init);
+            fixup(n->loopstmt.cond);
+            fixup(n->loopstmt.step);
+            fixup(n->loopstmt.body);
+            break;
+        case Nifstmt:
+            fixup(n->ifstmt.cond);
+            fixup(n->ifstmt.iftrue);
+            fixup(n->ifstmt.iffalse);
+            break;
+        case Nblock:
+            pushstab(n->block.scope);
+            for (i = 0; i < n->block.nstmts; i++)
+                fixup(n->block.stmts[i]);
+            popstab();
+            break;
+        case Ndecl:
+            fixup(n->decl.init);
+            break;
+        case Nfunc:
+            pushstab(n->func.scope);
+            fixup(n->func.body);
+            popstab();
+            break;
+        case Nnone: case Nlbl: case Nname:
+            break;
+    }
+}
+
 static Node *specializenode(Node *n, Htab *tsmap)
 {
     Node *r;
@@ -131,10 +190,13 @@
             break;
         case Nblock:
             r->block.scope = mkstab();
+            r->block.scope->super = curstab();
+            pushstab(r->block.scope);
             r->block.nstmts = n->block.nstmts;
             r->block.stmts = xalloc(sizeof(Node *)*n->block.nstmts);
             for (i = 0; i < n->block.nstmts; i++)
                 r->block.stmts[i] = specializenode(n->block.stmts[i], tsmap);
+            popstab();
             break;
         case Nlbl:
             r->lbl.name = strdup(n->lbl.name);
@@ -149,6 +211,7 @@
             r->decl.isconst = n->decl.isconst;
             r->decl.isgeneric = n->decl.isgeneric;
             r->decl.isextern = n->decl.isextern;
+            putdcl(curstab(), r);
 
             /* init */
             r->decl.init = specializenode(n->decl.init, tsmap);
@@ -155,6 +218,8 @@
             break;
         case Nfunc:
             r->func.scope = mkstab();
+            r->func.scope->super = curstab();
+            pushstab(r->func.scope);
             r->func.type = tysubst(n->func.type, tsmap);
             r->func.nargs = n->func.nargs;
             r->func.args = xalloc(sizeof(Node *)*n->func.nargs);
@@ -161,6 +226,7 @@
             for (i = 0; i < n->func.nargs; i++)
                 r->func.args[i] = specializenode(n->func.args[i], tsmap);
             r->func.body = specializenode(n->func.body, tsmap);
+            popstab();
             break;
         case Nnone:
             die("Nnone should not be seen as node type!");
@@ -208,11 +274,16 @@
     d = getdcl(file->file.globls, *name);
     if (d)
         return d;
+
     tsmap = mkht(tyhash, tyeq);
     fillsubst(tsmap, to, n->decl.type);
-    d = specializenode(n, tsmap);
-    d->decl.name = *name;
-    d->decl.isgeneric = 0; /* we've specialized it */
+
+    d = mkdecl(n->line, *name, tysubst(n->decl.type, tsmap));
+    d->decl.isconst = n->decl.isconst;
+    d->decl.isextern = n->decl.isextern;
+    d->decl.init = specializenode(n->decl.init, tsmap);
+    fixup(d);
+
     putdcl(file->file.globls, d);
     lappend(&file->file.stmts, &file->file.nstmts, d);
     return d;