ref: 4fb00e671f84192b77bbca4c095b5c5cdf755e31
parent: 5207c09ea6510258a90d83f86cc9f9a365bb3d26
author: Ori Bernstein <[email protected]>
date: Wed Mar 5 16:22:09 EST 2014
Prepare merging traits in preparation for exporting.
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -297,7 +297,10 @@
for (i = 0; i < $1->nfuncs; i++)
putdcl(file->file.exports, $1->funcs[i]);
}
- | implstmt
+ | implstmt {
+ $1->impl.vis = Visexport;
+ lappend(&exportimpls, &nexportimpls, $1);
+ }
| visdef {die("Unimplemented visdef");}
| /* empty */
;
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -844,6 +844,33 @@
}
free(k);
+ /* export the impls */
+ k = htkeys(exports->impl, &nk);
+ for (i = 0; i < nk; i++) {
+ 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));
+ nx->impl.isproto = 0;
+ nx->impl.decls = ng->impl.decls;
+ nx->impl.ndecls = ng->impl.ndecls;
+ } else {
+ if (ng)
+ fatal(nx->line, "Double trait impl body for %s %s on line %d\n",
+ namestr(nx->impl.traitname), tystr(nx->impl.type), ng->line);
+ else
+ putimpl(globls, nx);
+ }
+
+ }
+ free(k);
+
/* export the declarations */
k = htkeys(exports->dcl, &nk);
for (i = 0; i < nk; i++) {
--- a/parse/node.c
+++ b/parse/node.c
@@ -15,6 +15,8 @@
size_t maxnid;
Node **decls;
size_t ndecls;
+Node **exportimpls;
+size_t nexportimpls;
Node *mknode(int line, Ntype nt)
{
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -300,6 +300,8 @@
Type *type;
Node **decls;
size_t ndecls;
+ Vis vis;
+ char isproto;
} impl;
};
};
@@ -316,6 +318,8 @@
extern size_t ntraittab;
extern Node **decls; /* decl id -> decl map */
extern size_t ndecls;
+extern Node **exportimpls;
+extern size_t nexportimpls;
extern size_t maxnid; /* the maximum node id generated so far */
extern int ispureop[];
@@ -390,7 +394,7 @@
Node *getdcl(Stab *st, Node *n);
Type *gettype_l(Stab *st, Node *n);
Type *gettype(Stab *st, Node *n);
-int hasimpl(Stab *st, Node *impl);
+Node *getimpl(Stab *st, Node *impl);
Trait *gettrait(Stab *st, Node *n);
Ucon *getucon(Stab *st, Node *n);
--- a/parse/stab.c
+++ b/parse/stab.c
@@ -261,7 +261,7 @@
void putimpl(Stab *st, Node *n)
{
- if (hasimpl(st, n))
+ if (getimpl(st, n))
fatal(n->line, "Trait %s already implemented over %s", namestr(n->impl.traitname), tystr(n->impl.type));
if (st->name)
setns(n->impl.traitname, namestr(st->name));
@@ -268,9 +268,16 @@
htput(st->impl, n, n);
}
-int hasimpl(Stab *st, Node *n)
+Node *getimpl(Stab *st, Node *n)
{
- return hthas(st->impl, n);
+ Node *imp;
+
+ do {
+ if ((imp = htget(st->impl, n)))
+ return imp;
+ st = st->super;
+ } while (st);
+ return NULL;
}
void putns(Stab *st, Stab *scope)
--- a/parse/use.c
+++ b/parse/use.c
@@ -263,6 +263,11 @@
wrsym(fd, tr->funcs[i]);
}
+static void implpickle(FILE *fd, Node *impl)
+{
+ die("Pickling impls not yet supported.");
+}
+
static void wrtype(FILE *fd, Type *ty)
{
if (ty->tid >= Builtinmask)
@@ -885,6 +890,13 @@
if (traittab[i]->vis == Visexport || traittab[i]->vis == Vishidden) {
wrbyte(f, 'R');
traitpickle(f, traittab[i]);
+ }
+ }
+
+ for (i = 0; i < nexportimpls; i++) {
+ if (exportimpls[i]->impl.vis == Visexport || exportimpls[i]->impl.vis == Vishidden) {
+ wrbyte(f, 'R');
+ implpickle(f, exportimpls[i]);
}
}