shithub: mc

Download patch

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]);
         }
     }