shithub: mc

Download patch

ref: fbf50215af6de28f1c0ef86acbcba4666d771967
parent: 4e490585cee4656c1b1659956d0693f506db65b6
author: Ori Bernstein <[email protected]>
date: Thu Jun 28 07:34:15 EDT 2012

Work towards codegen for unions

--- a/8/reduce.c
+++ b/8/reduce.c
@@ -55,9 +55,18 @@
 static Node *one;
 static Node *zero;
 static Node *ptrsz;
+static Node *wordsz;
 static Type *tyword;
 static Type *tyvoid;
 
+static int max(int a, int b)
+{
+    if (a > b)
+        return a;
+    else
+        return b;
+}
+
 static Type *base(Type *t)
 {
     assert(t->nsub == 1);
@@ -195,6 +204,8 @@
     size_t i;
 
     sz = 0;
+    if (!t)
+        return 0;
     switch (t->type) {
         case Tyvoid:
             die("void has no size");
@@ -235,7 +246,9 @@
             return sz;
             break;
         case Tyunion:
-            die("Sizes for composite types not implemented yet");
+            sz = Wordsz;
+            for (i = 0; i < t->nmemb; i++)
+                sz = max(sz, tysize(t->udecls[i]->etype) + Wordsz);
             break;
         case Tybad: case Tyvar: case Typaram: case Tyname: case Ntypes:
             die("Type %s does not have size; why did it get down to here?", tystr(t));
@@ -564,6 +577,42 @@
     return r;
 }
 
+static Node *lowerucon(Simp *s, Node *n)
+{
+    Node *tmp, *u, *tag, *elt, *sz;
+    Node *r;
+    Type *ty;
+    Ucon *uc;
+    size_t i;
+
+    /* find the ucon we're constructing here */
+    ty = tybase(n->expr.type);
+    for (i = 0; i < ty->nmemb; i++) {
+        if (!strcmp(namestr(n->expr.args[0]), namestr(ty->udecls[i]->name))) {
+            uc = ty->udecls[i];
+            break;
+        }
+    }
+
+    tmp = temp(s, n);
+    u = addr(tmp, exprtype(n));
+    tag = word(n->line, uc->id);
+    store(u, tag);
+    if (!uc->etype)
+        return tmp;
+
+    elt = rval(s, n->expr.args[1]);
+    u = add(u, wordsz);
+    if (tysize(uc->etype) > Wordsz) {
+        elt = addr(elt, uc->etype);
+        sz = word(n->line, tysize(uc->utype));
+        r = mkexpr(n->line, Oblit, u, elt, sz, NULL);
+    } else {
+        r = store(u, elt);
+    }
+    return tmp;
+}
+
 static Node *rval(Simp *s, Node *n)
 {
     Node *r; /* expression result */
@@ -613,6 +662,9 @@
                 r = load(t);
             }
             break;
+        case Ocons:
+            r = lowerucon(s, n);
+            break;
         case Ocast:
             /* slice -> ptr cast */
             r = lowercast(s, n);
@@ -935,6 +987,7 @@
     one = word(-1, 1);
     zero = word(-1, 0);
     ptrsz = word(-1, Wordsz);
+    wordsz = word(-1, Wordsz);
 
     fn = NULL;
     nfn = 0;
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -99,8 +99,11 @@
     } else if (t->type == Tyunion) {
         for (i = 0; i < t->nmemb; i++) {
             tyresolve(t->udecls[i]->utype);
-            if (t->udecls[i]->etype)
+            t->udecls[i]->utype = tf(t->udecls[i]->utype);
+            if (t->udecls[i]->etype) {
                 tyresolve(t->udecls[i]->etype);
+                t->udecls[i]->etype = tf(t->udecls[i]->etype);
+            }
         }
     } else if (t->type == Tyarray) {
         infernode(t->asize, NULL, NULL);
@@ -710,7 +713,7 @@
 {
 }
 
-/* returns the fixal type for t, after all unifications
+/* returns the final type for t, after all unifications
  * and default constraint selections */
 static Type *tyfix(Node *ctx, Type *t)
 {
@@ -726,8 +729,17 @@
         if (hascstr(t, cstrtab[Tcint]) || cstrcheck(t, tyint))
             return tyint;
     } else {
-        if (t->type == Tyarray)
+        if (t->type == Tyarray) {
             typesub(t->asize);
+        } else if (t->type == Tystruct) {
+            for (i = 0; i < t->nmemb; i++)
+                typesub(t->sdecls[i]);
+        } else if (t->type == Tyunion) {
+            for (i = 0; i < t->nmemb; i++) {
+                if (t->udecls[i]->etype)
+                    t->udecls[i]->etype = tyfix(ctx, t->udecls[i]->etype);
+            }
+        }
         for (i = 0; i < t->nsub; i++)
             t->sub[i] = tyfix(ctx, t->sub[i]);
     }
@@ -875,7 +887,7 @@
     }
 }
 
-void mergeexports(Node *file)
+static void mergeexports(Node *file)
 {
     Stab *exports, *globls;
     size_t i, nk;
@@ -925,7 +937,7 @@
     popstab();
 }
 
-void specialize(Node *f)
+static void specialize(Node *f)
 {
     Node *d, *name;
     size_t i;
--- a/parse/specialize.c
+++ b/parse/specialize.c
@@ -235,7 +235,7 @@
     return r;
 }
 
-size_t tidappend(char *buf, size_t sz, Type *t)
+static size_t tidappend(char *buf, size_t sz, Type *t)
 {
     char *p;
     char *end;
@@ -249,7 +249,7 @@
     return end - p;
 }
 
-Node *genericname(Node *n, Type *t)
+static Node *genericname(Node *n, Type *t)
 {
     char buf[1024];
     char *p;