shithub: mc

Download patch

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"},