shithub: mc

Download patch

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