shithub: mc

Download patch

ref: 2d5321bb2fa2e34fce928bfef653776aba2c39d3
parent: 36fbbe032a98da86409bdb82da1b34cb3a83cca4
parent: 779a3ef073261c6919ec2a65545435a35a3f5b6f
author: Ori Bernstein <[email protected]>
date: Wed Aug 27 07:21:08 EDT 2014

Merge branch 'master' of git+ssh://git.eigenstate.org/git/ori/mc

--- a/parse/infer.c
+++ b/parse/infer.c
@@ -624,9 +624,54 @@
     return t->type == Tyname && t->narg > 0;
 }
 
-static void membunify(Inferstate *st, Node *ctx, Type *u, Type *v) {
-    size_t i;
+static void unionunify(Inferstate *st, Node *ctx, Type *u, Type *v)
+{
+    size_t i, j;
+    int found;
 
+    if (u->nmemb != v->nmemb)
+        fatal(ctx->line, "can't unify %s and %s near %s\n", tystr(u), tystr(v), ctxstr(st, ctx));
+
+    for (i = 0; i < u->nmemb; i++) {
+        found = 0;
+        for (j = 0; j < v->nmemb; j++) {
+            if (strcmp(namestr(u->udecls[i]->name), namestr(v->udecls[i]->name)) != 0)
+                continue;
+            found = 1;
+            if (u->udecls[i]->etype == NULL && v->udecls[i]->etype == NULL)
+                continue;
+            else if (u->udecls[i]->etype && v->udecls[i]->etype)
+                unify(st, ctx, u->udecls[i]->etype, v->udecls[i]->etype);
+            else
+                fatal(ctx->line, "can't unify %s and %s near %s\n", tystr(u), tystr(v), ctxstr(st, ctx));
+        }
+        if (!found)
+            fatal(ctx->line, "can't unify %s and %s near %s\n", tystr(u), tystr(v), ctxstr(st, ctx));
+    }
+}
+
+static void structunify(Inferstate *st, Node *ctx, Type *u, Type *v)
+{
+    size_t i, j;
+    int found;
+
+    if (u->nmemb != v->nmemb)
+        fatal(ctx->line, "can't unify %s and %s near %s\n", tystr(u), tystr(v), ctxstr(st, ctx));
+
+    for (i = 0; i < u->nmemb; i++) {
+        found = 0;
+        for (j = 0; j < v->nmemb; j++) {
+            if (strcmp(namestr(u->sdecls[i]->decl.name), namestr(v->sdecls[i]->decl.name)) != 0)
+                continue;
+            found = 1;
+            unify(st, u->sdecls[i], type(st, u->sdecls[i]), type(st, v->sdecls[i]));
+        }
+        if (!found)
+            fatal(ctx->line, "can't unify %s and %s near %s\n", tystr(u), tystr(v), ctxstr(st, ctx));
+    }
+}
+
+static void membunify(Inferstate *st, Node *ctx, Type *u, Type *v) {
     if (hthas(st->delayed, u))
         u = htget(st->delayed, u);
     u = tybase(u);
@@ -633,19 +678,10 @@
     if (hthas(st->delayed, v))
         v = htget(st->delayed, v);
     v = tybase(v);
-    if (u->type == Tyunion && v->type == Tyunion && u != v) {
-        assert(u->nmemb = v->nmemb);
-        for (i = 0; i < v->nmemb; i++) {
-            if (u->udecls[i]->etype)
-                unify(st, ctx, u->udecls[i]->etype, v->udecls[i]->etype);
-        }
-    } else if (u->type == Tystruct && v->type == Tystruct && u != v) {
-        assert(u->nmemb = v->nmemb);
-        for (i = 0; i < v->nmemb; i++) {
-            assert(!strcmp(namestr(u->sdecls[i]->decl.name), namestr(v->sdecls[i]->decl.name)));
-            unify(st, u->sdecls[i], type(st, u->sdecls[i]), type(st, v->sdecls[i]));
-        }
-    }
+    if (u->type == Tyunion && v->type == Tyunion && u != v)
+        unionunify(st, ctx, u, v);
+    else if (u->type == Tystruct && v->type == Tystruct && u != v)
+        structunify(st, ctx, u, v);
 }
 
 /* Unifies two types, or errors if the types are not unifiable. */