shithub: mc

Download patch

ref: 6094e25e786b8092cf097135a48250917fd6c234
parent: 685a0afcb76c7509ab97fcbc639b330478598bca
author: Ori Bernstein <[email protected]>
date: Mon Mar 3 19:28:55 EST 2014

Put impls into symbol tables.

--- a/parse/infer.c
+++ b/parse/infer.c
@@ -1375,6 +1375,7 @@
                    n->line, namestr(proto->decl.name), tystr(type(st, proto)), namestr(name), tystr(ty));
         lappend(&file->file.stmts, &file->file.nstmts, dcl);
     }
+    putimpl(curstab(), n);
 }
 
 static void inferdecl(Inferstate *st, Node *n)
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -97,11 +97,12 @@
     /* Contents of stab.
      * types and values are in separate namespaces. */
     Htab *dcl;
-    Htab *closure; /* the syms we close over */
-    Htab *ns; /* namespaces */
-    Htab *ty; /* types */
-    Htab *tr; /* traits */
-    Htab *uc; /* union constructors */
+    Htab *closure;      /* the syms we close over */
+    Htab *ns;           /* namespaces */
+    Htab *ty;           /* types */
+    Htab *tr;           /* traits */
+    Htab *uc;           /* union constructors */
+    Htab *impl;         /* trait implementations: really a set of implemented traits. */
 };
 
 struct Type {
@@ -380,6 +381,7 @@
 void putns(Stab *st, Stab *scope);
 void puttype(Stab *st, Node *n, Type *ty);
 void puttrait(Stab *st, Node *n, Trait *trait);
+void putimpl(Stab *st, Node *impl);
 void updatetype(Stab *st, Node *n, Type *t);
 void putdcl(Stab *st, Node *dcl);
 void forcedcl(Stab *st, Node *dcl);
@@ -390,6 +392,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);
 Trait *gettrait(Stab *st, Node *n);
 Ucon *getucon(Stab *st, Node *n);
 
--- a/parse/stab.c
+++ b/parse/stab.c
@@ -63,6 +63,28 @@
     return a == b || !strcmp(namestr(a), namestr(b));
 }
 
+static ulong implhash(void *p)
+{
+    Node *n;
+    ulong h;
+
+    n = p;
+    h = nsnamehash(n->impl.traitname);
+    h *= tyhash(n->impl.type);
+    return h;
+}
+
+static int impleq(void *pa, void *pb)
+{
+    Node *a, *b;
+
+    a = pa;
+    b = pb;
+    if (nsnameeq(a->impl.traitname, b->impl.traitname))
+        return tyeq(a->impl.type, b->impl.type);
+    return 0;
+}
+
 Stab *mkstab()
 {
     Stab *st;
@@ -73,6 +95,7 @@
     st->ty = mkht(nsnamehash, nsnameeq);
     st->tr = mkht(nsnamehash, nsnameeq);
     st->uc = mkht(nsnamehash, nsnameeq);
+    st->impl = mkht(implhash, impleq);
     return st;
 }
 
@@ -234,6 +257,20 @@
     td->name = n;
     td->trait = c;
     htput(st->tr, td->name, td);
+}
+
+void putimpl(Stab *st, Node *n)
+{
+    if (hasimpl(st, n))
+        fatal(n->line, "Trait %s already defined", namestr(n));
+    if (st->name)
+        setns(n->impl.traitname, namestr(st->name));
+    htput(st->impl, n, n);
+}
+
+int hasimpl(Stab *st, Node *n)
+{
+    return hthas(st->impl, n);
 }
 
 void putns(Stab *st, Stab *scope)