shithub: mc

Download patch

ref: a2207af9fb5f49a2663e058658571638a509a3e6
parent: 290af5c176be42347969ad80ed9d73391a36c61e
author: Ori Bernstein <[email protected]>
date: Fri Jun 22 16:20:36 EDT 2012

Correctly generate specialized versions of funcs.

    Yay!

--- a/parse/infer.c
+++ b/parse/infer.c
@@ -16,6 +16,10 @@
 static size_t npostcheck;
 static Htab **tybindings;
 static size_t ntybindings;
+static Node **genericdecls;
+static size_t ngenericdecls;
+static Node **specializations;
+static size_t nspecializations;
 
 static void infernode(Node *n, Type *ret, int *sawret);
 static void inferexpr(Node *n, Type *ret, int *sawret);
@@ -464,6 +468,10 @@
                 t = s->decl.type;
             settype(n, t);
             n->expr.did = s->decl.did;
+            if (s->decl.isgeneric) {
+                lappend(&specializations, &nspecializations, n);
+                lappend(&genericdecls, &ngenericdecls, s);
+            }
             break;
         case Olit:      /* <lit>:@a::tyclass -> @a */
             switch (args[0]->lit.littype) {
@@ -867,6 +875,17 @@
     popstab();
 }
 
+void specialize(Node *f)
+{
+    Node *n;
+    size_t i;
+
+    for (i = 0; i < nspecializations; i++) {
+        n = specializedcl(genericdecls[i], specializations[i]->expr.type, NULL);
+        dump(n, stdout);
+    }
+}
+
 void infer(Node *file)
 {
     assert(file->type == Nfile);
@@ -877,4 +896,5 @@
     infercompn(file);
     checkcast(file);
     typesub(file);
+    specialize(file);
 }
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -346,7 +346,7 @@
 Node **aggrmemb(Type *t, size_t *n);
 
 /* specialize generics */
-Node *specialize(Node *n, Type *to, Type *from);
+Node *specializedcl(Node *n, Type *to, Node **dcl);
 
 /* usefiles */
 void readuse(Node *use, Stab *into);
--- a/parse/specialize.c
+++ b/parse/specialize.c
@@ -45,12 +45,14 @@
     Type *ret;
     size_t i;
 
-    if (t->type == Typaram)
-        return htget(tsmap, t);
-
-    ret = tydup(t);
-    for (i = 0; i < t->nsub; i++)
-        ret->sub[i] = dosubst(t->sub[i], tsmap);
+    if (t->type == Typaram) {
+        ret = htget(tsmap, t);
+    } else {
+        ret = tydup(t);
+        for (i = 0; i < t->nsub; i++)
+            ret->sub[i] = dosubst(t->sub[i], tsmap);
+    }
+    assert(ret != NULL);
     return ret;
 }
 
@@ -79,6 +81,8 @@
     Node *r;
     size_t i;
 
+    if (!n)
+        return NULL;
     r = mknode(n->line, n->type);
     switch (n->type) {
         case Nfile:
@@ -103,13 +107,13 @@
             r->lit.littype = n->lit.littype;
             r->lit.type = tysubst(n->expr.type, tsmap);
             switch (n->lit.littype) {
-                case Lchr:      n->lit.chrval = n->lit.chrval;       break;
-                case Lint:      n->lit.intval = n->lit.intval;       break;
-                case Lflt:      n->lit.fltval = n->lit.fltval;       break;
-                case Lstr:      n->lit.strval = n->lit.strval;       break;
-                case Lbool:     n->lit.boolval = n->lit.boolval;     break;
-                case Lfunc:     n->lit.fnval = specializenode(n->lit.fnval, tsmap);       break;
-                case Larray:    n->lit.arrval = specializenode(n->lit.arrval, tsmap);     break;
+                case Lchr:      r->lit.chrval = n->lit.chrval;       break;
+                case Lint:      r->lit.intval = n->lit.intval;       break;
+                case Lflt:      r->lit.fltval = n->lit.fltval;       break;
+                case Lstr:      r->lit.strval = n->lit.strval;       break;
+                case Lbool:     r->lit.boolval = n->lit.boolval;     break;
+                case Lfunc:     r->lit.fnval = specializenode(n->lit.fnval, tsmap);       break;
+                case Larray:    r->lit.arrval = specializenode(n->lit.arrval, tsmap);     break;
             }
             break;
         case Nloopstmt:
@@ -136,7 +140,7 @@
         case Ndecl:
             /* sym */
             r->decl.name = specializenode(n->decl.name, tsmap);
-            n->decl.type = tysubst(n->decl.type, tsmap);
+            r->decl.type = tysubst(n->decl.type, tsmap);
 
             /* symflags */
             r->decl.isconst = n->decl.isconst;
@@ -161,11 +165,14 @@
     return r;
 }
 
-Node *specialize(Node *n, Type *to, Type *from)
+Node *specializedcl(Node *n, Type *to, Node **dcl)
 {
     Htab *tsmap;
 
+    assert(n->type == Ndecl);
+    assert(n->decl.isgeneric);
+
     tsmap = mkht(tidhash, tideq);
-    fillsubst(tsmap, to, from);
+    fillsubst(tsmap, to, n->decl.type);
     return specializenode(n, tsmap);
 }