ref: 2b3a550af408c998d0b6d51bb89a9edbd02ec51e
parent: e89a6b09545f09a0f9f6491d0f4614d19d8847cd
author: Ori Bernstein <[email protected]>
date: Mon May 19 09:24:27 EDT 2014
Try to iterate over types. Currently attempts to double specialize, but it's a step forward.
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -196,6 +196,7 @@
| use {lappend(&file->file.uses, &file->file.nuses, $1);}
| implstmt {
lappend(&file->file.stmts, &file->file.nstmts, $1);
+ putimpl(file->file.globls, $1);
}
| traitdef {
size_t i;
@@ -301,6 +302,7 @@
}
| implstmt {
$1->impl.vis = Visexport;
+ putimpl(file->file.exports, $1);
}
| visdef {die("Unimplemented visdef");}
| /* empty */
--- a/parse/htab.c
+++ b/parse/htab.c
@@ -170,6 +170,7 @@
if (i < 0)
return;
ht->dead[i] = 1;
+ ht->nelt--;
}
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -779,6 +779,22 @@
readuse(n->file.uses[i], n->file.globls);
}
+static void fiximpls(Inferstate *st, Stab *s)
+{
+ Node *n;
+ void **k;
+ size_t nk, i;
+
+ k = htkeys(s->impl, &nk);
+ for (i = 0; i < nk; i++) {
+ n = getimpl(s, k[i]);
+ htdel(s->impl, k[i]);
+ n->impl.type = tf(st, n->impl.type);
+ putimpl(s, n);
+ }
+ free(k);
+}
+
/* The exports in package declarations
* need to be merged with the declarations
* at the global scope. Declarations in
@@ -844,6 +860,14 @@
}
free(k);
+ /*
+ * if we neglect to fix the types for impls before
+ * lookups, getimpl() on the global with the key from
+ * the export table will fail.
+ */
+ fiximpls(st, exports);
+ fiximpls(st, globls);
+
/* export the impls */
k = htkeys(exports->impl, &nk);
for (i = 0; i < nk; i++) {
@@ -850,10 +874,6 @@
nx = getimpl(exports, k[i]);
ng = getimpl(globls, k[i]);
- nx->impl.type = tf(st, nx->impl.type);
- if (ng)
- ng->impl.type = tf(st, ng->impl.type);
-
if (nx->impl.isproto) {
if (!ng)
fatal(nx->line, "Missing trait impl body for %s %s\n", namestr(nx->impl.traitname), tystr(nx->impl.type));
@@ -868,7 +888,7 @@
namestr(nx->impl.traitname), tystr(nx->impl.type), ng->line);
}
}
-
+ lappend(&exportimpls, &nexportimpls, ng);
}
free(k);
--- a/parse/node.c
+++ b/parse/node.c
@@ -15,8 +15,8 @@
size_t maxnid;
Node **decls;
size_t ndecls;
-Node **impls;
-size_t nimpls;
+Node **exportimpls;
+size_t nexportimpls;
Node *mknode(int line, Ntype nt)
{
@@ -194,7 +194,6 @@
n->impl.type = t;
n->impl.decls = decls;
n->impl.ndecls = ndecls;
- lappend(&impls, &nimpls, n);
return n;
}
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -319,8 +319,8 @@
extern size_t ntraittab;
extern Node **decls; /* decl id -> decl map */
extern size_t ndecls;
-extern Node **impls;
-extern size_t nimpls;
+extern Node **exportimpls;
+extern size_t nexportimpls;
extern size_t maxnid; /* the maximum node id generated so far */
extern int ispureop[];
--- a/parse/use.c
+++ b/parse/use.c
@@ -899,12 +899,12 @@
}
}
- for (i = 0; i < nimpls; i++) {
- if (impls[i]->impl.isproto)
- continue;
- if (impls[i]->impl.vis == Visexport || impls[i]->impl.vis == Vishidden) {
+ for (i = 0; i < nexportimpls; i++) {
+ /* merging during inference should remove all protos */
+ assert(!exportimpls[i]->impl.isproto);
+ if (exportimpls[i]->impl.vis == Visexport || exportimpls[i]->impl.vis == Vishidden) {
wrbyte(f, 'I');
- implpickle(f, impls[i]);
+ implpickle(f, exportimpls[i]);
}
}