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;