shithub: mc

Download patch

ref: 8bf7a907ceb2f9549041dcfbe87f06eb92c60667
parent: 5192aa93538b09713e30be3063817b1068d415a6
author: Ori Bernstein <[email protected]>
date: Sat Dec 24 14:31:15 EST 2011

Make tyfin() work

--- a/parse/ds.c
+++ b/parse/ds.c
@@ -29,7 +29,7 @@
 
     bs = xalloc(sizeof(Bitset));
     bs->nchunks = 1;
-    bs->chunks = xalloc(1*sizeof(uint));
+    bs->chunks = zalloc(1*sizeof(uint));
     return bs;
 }
 
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -34,6 +34,10 @@
     Bitset *s;
     int n;
 
+    if (a->cstrs)
+        return 1;
+    if (!b->cstrs)
+        return 0;
     /* if b->cstrs \ a->cstrs == 0, then all of
      * a's constraints are satisfied. */
     s = dupbs(b->cstrs);
@@ -75,11 +79,11 @@
 static Type *littype(Node *n)
 {
     switch (n->lit.littype) {
-        case Lchr:      return mktyvar(n->line);       break;
-        case Lbool:     return mktyvar(n->line);       break;
-        case Lint:      return mktyvar(n->line);       break;
-        case Lflt:      return mktyvar(n->line);       break;
-        case Lstr:      return mktyvar(n->line);       break;
+        case Lchr:      return mkty(n->line, Tychar);                           break;
+        case Lbool:     return mkty(n->line, Tybool);                           break;
+        case Lint:      return tylike(mktyvar(n->line), Tyint);                 break;
+        case Lflt:      return tylike(mktyvar(n->line), Tyfloat32);             break;
+        case Lstr:      return mktyslice(n->line, mkty(n->line, Tychar));       break;
         case Lfunc:     return NULL; break;
         case Larray:    return NULL; break;
     };
@@ -107,6 +111,19 @@
     return nodestr(n->type);
 }
 
+static void matchcstrs(Node *ctx, Type *a, Type *b)
+{
+    if (b->type == Tyvar) {
+        if (!b->cstrs)
+            b->cstrs = dupbs(a->cstrs);
+        else
+            bsunion(b->cstrs, a->cstrs);
+    } else {
+        if (!cstrcheck(b, a))
+            fatal(ctx->line, "%s incompatible with %s near %s", tystr(a), tystr(b), ctxstr(ctx));
+    }
+}
+
 static Type *unify(Node *ctx, Type *a, Type *b)
 {
     Type *t;
@@ -120,15 +137,19 @@
         a = b;
         b = t;
     }
+
+    matchcstrs(ctx, a, b);
     if (a->type != b->type && a->type != Tyvar)
         fatal(ctx->line, "%s incompatible with %s near %s", tystr(a), tystr(b), ctxstr(ctx));
 
     tytab[a->tid] = b;
     for (i = 0; i < b->nsub; i++) {
+        /* types must have same arity */
         if (i >= a->nsub)
             fatal(ctx->line, "%s incompatible with %s near %s", tystr(a), tystr(b), ctxstr(ctx));
-        /*
-         * FIXME: recurse properly.
+
+        /* FIXME: recurse properly.
+        matchcstrs(ctx, a, b);
         unify(ctx, a->sub[i], b->sub[i]);
         */
     }
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -257,6 +257,7 @@
 Type *mktyunion(int line, Node **decls, size_t ndecls);
 Type *mktyenum(int line, Node **decls, size_t ndecls);
 Cstr *mkcstr(int line, char *name, Node **memb, size_t nmemb, Node **funcs, size_t nfuncs);
+Type *tylike(Type *t, Ty ty); /* constrains tyvar t like it was builtin ty */
 
 /* type manipulation */
 int hascstr(Type *t, Cstr *c);
--- a/parse/type.c
+++ b/parse/type.c
@@ -21,7 +21,7 @@
 Type **tytab = NULL;
 int ntypes;
 Cstr **cstrtab;
-int ncstr;
+int ncstrs;
 
 static Typename typenames[] = {
     {Tyvoid, "void"},
@@ -58,6 +58,15 @@
     return t;
 }
 
+Type *tylike(Type *t, Ty like)
+{
+    int i;
+
+    for (i = 0; tycstrs[like][i]; i++)
+        constrain(t, tycstrs[like][i]);
+    return t;
+}
+
 /* steals memb, funcs */
 Cstr *mkcstr(int line, char *name, Node **memb, size_t nmemb, Node **funcs, size_t nfuncs)
 {
@@ -69,9 +78,10 @@
     c->nmemb = nmemb;
     c->funcs = funcs;
     c->nfuncs = nfuncs;
-    c->cid = ncstr++;
+    c->cid = ncstrs++;
 
-    cstrtab = xrealloc(cstrtab, ncstr*sizeof(Cstr*));
+    cstrtab = xrealloc(cstrtab, ncstrs*sizeof(Cstr*));
+    cstrtab[c->cid] = c;
     return c;
 }
 
@@ -221,7 +231,29 @@
 
 static int cstrfmt(char *buf, size_t len, Type *t)
 {
-    return 0;
+    char *p;
+    char *end;
+    int first;
+    int i;
+
+    if (!t->cstrs || !bscount(t->cstrs))
+        return 0;
+
+    p = buf;
+    end = p + len;
+    first = 1;
+
+    p += snprintf(p, end - p, " :: ");
+    for (i = 0; i < ncstrs; i++) {
+        if (bshas(t->cstrs, i)) {
+            if (!first) {
+                first = 0;
+                p += snprintf(p, end - p, ", ");
+            }
+            p += snprintf(p, end - p, "%s", cstrtab[i]->name);
+        }
+    }
+    return end - p;
 }
 
 static int tybfmt(char *buf, size_t len, Type *t)
@@ -311,7 +343,9 @@
             break;
     }
 
-    p += cstrfmt(p, end - p, t);
+    /* we only show constraints on non-builtin typarams */
+    if (t->type == Tyvar || t->type == Typaram)
+        p += cstrfmt(p, end - p, t);
 
     return len - (end - p);
 }