shithub: mc

Download patch

ref: 5fd0c284bc486fd0496e2bc10057946dbf9be2b2
parent: 57114efd8d6aadc94466e0a8ff26fa613d9c3e8f
author: Ori Bernstein <[email protected]>
date: Thu Oct 18 14:05:39 EDT 2012

Remove redundant code.

    We had duplicated type freshening/specializing code. Fix.

--- a/parse/infer.c
+++ b/parse/infer.c
@@ -115,76 +115,22 @@
     return 0;
 }
 
-/* Returns a fresh type with all unbound type
- * parameters (type schemes in most literature)
- * replaced with type variables that we can unify
- * against */
-static Type *tyspecialize(Inferstate *st, Htab *ht, Type *t)
+/* Freshens the type of a declaration. */
+static Type *tyfreshen(Inferstate *st, Type *t)
 {
-    Type *ret;
-    size_t i;
+    Htab *ht;
 
     st->ingeneric++;
     t = tf(st, t);
     st->ingeneric--;
 
-    switch (t->type) {
-        case Typaram:
-            if (hthas(ht, t->pname))
-                return htget(ht, t->pname);
-            ret = mktyvar(t->line);
-            htput(ht, t->pname, ret);
-            break;
-        case Tygeneric:
-            for (i = 0; i < t->nparam; i++)
-                if (!hthas(ht, t->param[i]->pname))
-                    htput(ht, t->param[i]->pname, mktyvar(t->param[i]->line));
-            ret = mktyname(t->line, t->name, tyspecialize(st, ht, t->sub[0]));
-            for (i = 0; i < t->nparam; i++)
-                lappend(&ret->param, &ret->nparam, tyspecialize(st, ht, t->param[i]));
-            break;
-        case Tystruct:
-            die("Freshening structs is not yet implemented");
-            break;
-        case Tyunion:
-            die("Freshening unions is not yet implemented");
-            break;
-        default:
-            if (t->nsub > 0) {
-                ret = tydup(t);
-                for (i = 0; i < t->nsub; i++)
-                    ret->sub[i] = tyspecialize(st, ht, t->sub[i]);
-            } else {
-                ret = t;
-            }
-            break;
-    }
-    return ret;
-}
-
-static Type *tyfreshen(Inferstate *st, Type *t)
-{
-    Htab *ht;
-
-    assert(t->type == Tygeneric);
     ht = mkht(strhash, streq);
-    t = tyspecialize(st, ht, t);
+    t = tyspecialize(t, ht);
     htfree(ht);
 
     return t;
 }
 
-/* Freshens the type of a declaration. */
-static Type *freshen(Inferstate *st, Type *t)
-{
-    Htab *ht;
-
-    ht = mkht(strhash, streq);
-    t = tyspecialize(st, ht, t);
-    htfree(ht);
-    return t;
-}
-
 /* Checks if a type that directly contains itself.
  * Recursive types that contain themselves through
  * pointers or slices are fine, but any other self-inclusion
@@ -740,7 +686,7 @@
     var = mkexpr(n->line, Ovar, nsname, NULL);
     var->expr.did = s->decl.did;
     if (s->decl.isgeneric)
-        settype(st, var, freshen(st, s->decl.type));
+        settype(st, var, tyfreshen(st, s->decl.type));
     else
         settype(st, var, s->decl.type);
     if (s->decl.isgeneric) {
@@ -789,7 +735,7 @@
             s = getdcl(curstab(), args[0]);
             if (s) {
                 if (s->decl.isgeneric)
-                    t = freshen(st, s->decl.type);
+                    t = tyfreshen(st, s->decl.type);
                 else if (s->decl.isconst)
                     t = s->decl.type;
                 else
@@ -962,7 +908,7 @@
                 fatal(n->line, "Undeclared var %s", ctxstr(st, args[0]));
 
             if (s->decl.isgeneric)
-                t = freshen(st, s->decl.type);
+                t = tyfreshen(st, s->decl.type);
             else
                 t = s->decl.type;
             settype(st, n, t);
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -410,6 +410,7 @@
 
 /* specialize generics */
 Node *specializedcl(Node *n, Type *to, Node **name);
+Type *tyspecialize(Type *t, Htab *tymap);
 
 /* usefiles */
 int  loaduse(FILE *f, Stab *into);
--- a/parse/specialize.c
+++ b/parse/specialize.c
@@ -11,26 +11,6 @@
 
 #include "parse.h"
 
-static ulong typaramhash(void *p)
-{
-    Type *t;
-
-    t = p;
-    assert(t->type == Typaram);
-    return strhash(t->pname);
-}
-
-static int typarameq(void *pa, void *pb)
-{
-    Type *a, *b;
-
-    a = pa;
-    b = pb;
-    assert(a->type == Typaram);
-    assert(b->type == Typaram);
-    return streq(a->pname, b->pname);
-}
-
 /*
  * Checks if a type contains any type
  * parameers at all (ie, if it generic).
@@ -41,6 +21,8 @@
 
     if (t->type == Typaram)
         return 1;
+    if (t->type == Tygeneric)
+        return 1;
     for (i = 0; i < t->nsub; i++)
         if (hasparams(t->sub[i]))
             return 1;
@@ -52,19 +34,45 @@
  * parameters substituted with the substitions
  * described in 'tsmap'
  */
-static Type *dosubst(Type *t, Htab *tsmap)
+/* Returns a fresh type with all unbound type
+ * parameters (type schemes in most literature)
+ * replaced with type variables that we can unify
+ * against */
+Type *tyspecialize(Type *t, Htab *ht)
 {
     Type *ret;
-    size_t i;
 
-    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);
+    size_t i;
+    switch (t->type) {
+        case Typaram:
+            if (hthas(ht, t->pname))
+                return htget(ht, t->pname);
+            ret = mktyvar(t->line);
+            htput(ht, t->pname, ret);
+            break;
+        case Tygeneric:
+            for (i = 0; i < t->nparam; i++)
+                if (!hthas(ht, t->param[i]->pname))
+                    htput(ht, t->param[i]->pname, mktyvar(t->param[i]->line));
+            ret = mktyname(t->line, t->name, tyspecialize(t->sub[0], ht));
+            for (i = 0; i < t->nparam; i++)
+                lappend(&ret->param, &ret->nparam, tyspecialize(t->param[i], ht));
+            break;
+        case Tystruct:
+            break;
+        case Tyunion:
+            die("Freshening unions is not yet implemented");
+            break;
+        default:
+            if (t->nsub > 0) {
+                ret = tydup(t);
+                for (i = 0; i < t->nsub; i++)
+                    ret->sub[i] = tyspecialize(t->sub[i], ht);
+            } else {
+                ret = t;
+            }
+            break;
     }
-    assert(ret != NULL);
     return ret;
 }
 
@@ -74,7 +82,7 @@
 static Type *tysubst(Type *t, Htab *tsmap)
 {
     if (hasparams(t))
-        return dosubst(t, tsmap);
+        return tyspecialize(t, tsmap);
     else
         return t;
 }
@@ -88,7 +96,7 @@
     size_t i;
 
     if (from->type == Typaram) {
-        htput(tsmap, from, to);
+        htput(tsmap, from->pname, to);
     }
     if (to->nsub != from->nsub)
         return;
@@ -343,7 +351,7 @@
     }
 
     /* specialize */
-    tsmap = mkht(typaramhash, typarameq);
+    tsmap = mkht(strhash, streq);
     fillsubst(tsmap, to, n->decl.type);
 
     d = mkdecl(n->line, *name, tysubst(n->decl.type, tsmap));
--- a/parse/type.c
+++ b/parse/type.c
@@ -44,7 +44,7 @@
 }
 
 /*
- * Duplicates a type, so we can frob
+ * Shallowly duplicates a type, so we can frob
  * its internals later
  */
 Type *tydup(Type *t)