diff options
Diffstat (limited to 'parse')
-rw-r--r-- | parse/gram.y | 5 | ||||
-rw-r--r-- | parse/infer.c | 27 | ||||
-rw-r--r-- | parse/node.c | 2 | ||||
-rw-r--r-- | parse/parse.h | 6 | ||||
-rw-r--r-- | parse/stab.c | 13 | ||||
-rw-r--r-- | parse/use.c | 12 |
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]); |