summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2014-03-05 21:22:09 -0500
committerOri Bernstein <ori@eigenstate.org>2014-03-05 21:22:09 -0500
commit4fb00e671f84192b77bbca4c095b5c5cdf755e31 (patch)
tree77dbc8adc50afcaeed7fedd22e3b470d43723983
parent5207c09ea6510258a90d83f86cc9f9a365bb3d26 (diff)
downloadmc-4fb00e671f84192b77bbca4c095b5c5cdf755e31.tar.gz
Prepare merging traits in preparation for exporting.
-rw-r--r--parse/gram.y5
-rw-r--r--parse/infer.c27
-rw-r--r--parse/node.c2
-rw-r--r--parse/parse.h6
-rw-r--r--parse/stab.c13
-rw-r--r--parse/use.c12
6 files changed, 60 insertions, 5 deletions
diff --git a/parse/gram.y b/parse/gram.y
index c8789f7..2f6bf3f 100644
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -297,7 +297,10 @@ pkgitem : decl {
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 */
;
diff --git a/parse/infer.c b/parse/infer.c
index 03f54bd..2d86122 100644
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -844,6 +844,33 @@ static void mergeexports(Inferstate *st, Node *file)
}
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++) {
diff --git a/parse/node.c b/parse/node.c
index 0589c3d..4fdffa0 100644
--- 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)
{
diff --git a/parse/parse.h b/parse/parse.h
index 816a985..aa3ce31 100644
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -300,6 +300,8 @@ struct Node {
Type *type;
Node **decls;
size_t ndecls;
+ Vis vis;
+ char isproto;
} impl;
};
};
@@ -316,6 +318,8 @@ extern Trait **traittab; /* int -> trait map */
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 @@ Stab *getns_str(Stab *st, char *n);
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);
diff --git a/parse/stab.c b/parse/stab.c
index c86aa53..0aa8399 100644
--- a/parse/stab.c
+++ b/parse/stab.c
@@ -261,16 +261,23 @@ void puttrait(Stab *st, Node *n, Trait *c)
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));
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)
diff --git a/parse/use.c b/parse/use.c
index c75cdc4..bc0ed1e 100644
--- a/parse/use.c
+++ b/parse/use.c
@@ -263,6 +263,11 @@ static void traitpickle(FILE *fd, Trait *tr)
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)
@@ -888,6 +893,13 @@ void writeuse(FILE *f, Node *file)
}
}
+ for (i = 0; i < nexportimpls; i++) {
+ if (exportimpls[i]->impl.vis == Visexport || exportimpls[i]->impl.vis == Vishidden) {
+ wrbyte(f, 'R');
+ implpickle(f, exportimpls[i]);
+ }
+ }
+
k = htkeys(st->dcl, &n);
for (i = 0; i < n; i++) {
s = getdcl(st, k[i]);