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;