shithub: mc

Download patch

ref: 0116ef24cb193165de85d3a707d4dbd64ba1b60f
parent: f9c8f07de30e44dc51e82d8c8a83553ac36b92f6
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Jul 28 11:40:57 EDT 2012

Fix up type index hacks a bit.

    We rank and order types by their unifiability.

--- a/parse/infer.c
+++ b/parse/infer.c
@@ -335,18 +335,8 @@
     }
 }
 
-static int idxhacked(Type **pa, Type **pb)
+static int idxhacked(Type *a, Type *b)
 {
-    Type *a, *b;
-
-    a = *pa;
-    b = *pb;
-    /* we want to unify Tyidxhack => concrete indexable. Flip 
-     * to make this happen, if needed */
-    if (b->type == Tyvar && b->nsub > 0) {
-        *pb = a;
-        *pa = b;
-    }
     return (a->type == Tyvar && a->nsub > 0) || a->type == Tyarray || a->type == Tyslice;
 }
 
@@ -364,6 +354,16 @@
     return 0;
 }
 
+static int tyrank(Type *t)
+{
+    if (t->type == Tyvar && t->nsub == 0)
+        return 0;
+    if (t->type == Tyvar && t->nsub > 0)
+        return 1;
+    else
+        return 2;
+}
+
 static Type *unify(Inferstate *st, Node *ctx, Type *a, Type *b)
 {
     Type *t;
@@ -375,7 +375,7 @@
     b = tf(st, b);
     if (a == b)
         return a;
-    if (b->type == Tyvar) {
+    if (tyrank(b) < tyrank(a)) {
         t = a;
         a = b;
         b = t;
@@ -391,7 +391,7 @@
         if (occurs(a, b))
             fatal(ctx->line, "Infinite type %s in %s near %s", tystr(a), tystr(b), ctxstr(st, ctx));
 
-    if (a->type == b->type || idxhacked(&a, &b)) {
+    if ((a->type == b->type || idxhacked(a, b)) && tyrank(a) != 0) {
         for (i = 0; i < b->nsub; i++) {
             /* types must have same arity */
             if (i >= a->nsub)
--- a/parse/type.c
+++ b/parse/type.c
@@ -403,7 +403,7 @@
             p += snprintf(p, end - p, "@$%d", t->tid);
             if (t->nsub) {
                 p += snprintf(p, end - p, "(");
-                for (i = 1; i < t->nsub; i++) {
+                for (i = 0; i < t->nsub; i++) {
                     p += snprintf(p, end - p, "%s", sep);
                     p += tybfmt(p, end - p, t->sub[i]);
                     sep = ", ";
--