ref: c9abdb3231c701b9602b9d8c74c2cd03299233a9
parent: efb34ddd6b8f6aa92a0e9460968da4275ec5f178
author: Ori Bernstein <[email protected]>
date: Mon Dec 19 14:42:52 EST 2011
Stub in more type inference.
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -12,6 +12,15 @@
#include "parse.h"
+/* find the most accurate type mapping */
+static Type *tf(Type *t)
+{
+ while (typetab[t->tid])
+ t = typetab[t->tid];
+ return t;
+}
+
+
static void loaduses(Node *n)
{
int i;
@@ -34,25 +43,50 @@
static Type *type(Node *n)
{
- die("Unimplemented type()");
- return NULL;
-}
+ Type *t;
-static Type *littype(Node *lit)
-{
- return NULL;
+ switch (n->type) {
+ case Nlit: t = littypes[n->lit.littype]; break;
+ case Nexpr: t = n->expr.type; break;
+ case Ndecl: t = decltype(n); break;
+ default:
+ die("untypeable %s", nodestr(n->type));
+ break;
+ };
+ return tf(t);
}
-static Type *unify(Type *a, Type *b)
+static char *ctxstr(Node *n)
{
- die("Unimplemented unify");
- return NULL;
+ return nodestr(n->type);
}
-static Type *tyfind(Type *t)
+static Type *unify(Node *ctx, Type *a, Type *b)
{
- die("Unimplemented tyfind");
- return t;
+ Type *t;
+ int i;
+
+ /* a ==> b */
+ a = tf(a);
+ b = tf(b);
+ if (b->type == Tyvar) {
+ t = a;
+ a = b;
+ b = t;
+ }
+ if (a->type != b->type && a->type != Tyvar)
+ fatal(ctx->line, "%s incompatible with %s near %s", tystr(a), tystr(b), ctxstr(ctx));
+
+ typetab[a->tid] = b;
+ for (i = 0; i < b->nsub; i++) {
+ if (i >= a->nsub)
+ fatal(ctx->line, "%s incompatible with %s near %s", tystr(a), tystr(b), ctxstr(ctx));
+ /*
+ * FIXME: recurse properly.
+ unify(ctx, a->sub[i], b->sub[i]);
+ */
+ }
+ return b;
}
static void unifycall(Node *n)
@@ -100,8 +134,8 @@
case Obsreq: /* @a >>= @a -> @a */
t = type(args[0]);
for (i = 1; i < nargs; i++)
- t = unify(t, type(args[i]));
- settype(n, tyfind(t));
+ t = unify(n, t, type(args[i]));
+ settype(n, tf(t));
break;
/* operands same type, returning bool */
@@ -116,7 +150,7 @@
case Ole: /* @a <= @b -> bool */
t = type(args[0]);
for (i = 1; i < nargs; i++)
- unify(t, type(args[i]));
+ unify(n, t, type(args[i]));
settype(n, mkty(-1, Tybool));
break;
@@ -125,7 +159,7 @@
settype(n, mktyptr(n->line, type(args[0])));
break;
case Oderef: /* *@a* -> @a */
- t = unify(type(args[0]), mktyptr(n->line, mktyvar(n->line)));
+ t = unify(n, type(args[0]), mktyptr(n->line, mktyvar(n->line)));
settype(n, t);
break;
case Oidx: /* @a[@b::tcint] -> @a */
@@ -158,7 +192,7 @@
settype(n, decltype(n));
break;
case Olit: /* <lit>:@a::tyclass -> @a */
- settype(n, littype(n));
+ settype(n, type(n));
break;
case Olbl: /* :lbl -> void* */
settype(n, mktyptr(n->line, mkty(-1, Tyvoid)));
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -189,6 +189,17 @@
};
};
+/* globals */
+extern int debug;
+extern char *filename;
+extern int ignorenl;
+extern Tok *curtok; /* the last token we tokenized */
+extern int line; /* the last line number we tokenized */
+extern Node *file; /* the current file we're compiling */
+extern Stab *scope; /* the current scope to insert symbols into */
+extern Type **typetab; /* type -> type map used by inference. size maintained by type creation code */
+extern Type *littypes[]; /* literal type -> type map */
+
/* data structures */
Bitset *mkbs();
Bitset *dupbs(Bitset *bs);
@@ -199,15 +210,6 @@
void bsunion(Bitset *a, Bitset *b);
void bsintersect(Bitset *a, Bitset *b);
void bsdiff(Bitset *a, Bitset *b);
-
-/* globals */
-extern int debug;
-extern char *filename;
-extern int ignorenl;
-extern int line;
-extern Tok *curtok;
-extern Node *file;
-extern Stab *scope;
/* util functions */
void *zalloc(size_t size);
--- a/parse/type.c
+++ b/parse/type.c
@@ -17,7 +17,10 @@
char *name;
};
-Typename typenames[] = {
+Type *littypes[Nlit] = {0,};
+Type **typetab = NULL;
+
+static Typename typenames[] = {
{Tyvoid, "void"},
{Tychar, "char"},
{Tybyte, "byte"},