ref: fbf50215af6de28f1c0ef86acbcba4666d771967
parent: 4e490585cee4656c1b1659956d0693f506db65b6
author: Ori Bernstein <ori@eigenstate.org>
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;
--
⑨