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);
}