ref: 61a9e807de75f67fd5467aa671b00935d202f0e3
parent: 7f27f03b1887e599d6e9be6644895e8ab2bd5940
author: Ori Bernstein <ori@eigenstate.org>
date: Mon Jan 19 19:32:35 EST 2015
Add support for constant union initializers. Oops, that was broked.
--- a/6/gengas.c
+++ b/6/gengas.c
@@ -327,6 +327,19 @@
return n->lit.intval;
}
+static size_t writeucon(FILE *fd, Htab *globls, Htab *strtab, Node *n)
+{
+ size_t sz;
+ Ucon *uc;
+
+ sz = 4;
+ uc = finducon(exprtype(n), n->expr.args[0]);
+ fprintf(fd, ".long %zd\n", uc->id);
+ if (n->expr.nargs > 1)
+ sz += writeblob(fd, globls, strtab, n->expr.args[1]);
+ return writepad(fd, size(n) - sz);
+}
+
static size_t writeslice(FILE *fd, Htab *globls, Htab *strtab, Node *n)
{
Node *base, *lo, *hi;
@@ -387,20 +400,15 @@
size_t i, sz;
switch(exprop(n)) {
+ case Oucon: sz = writeucon(fd, globls, strtab, n); break;
+ case Oslice: sz = writeslice(fd, globls, strtab, n); break;
+ case Ostruct: sz = writestruct(fd, globls, strtab, n); break;
+ case Olit: sz = writelit(fd, strtab, n->expr.args[0], exprtype(n)); break;
case Otup:
case Oarr:
sz = 0;
for (i = 0; i < n->expr.nargs; i++)
sz += writeblob(fd, globls, strtab, n->expr.args[i]);
- break;
- case Ostruct:
- sz = writestruct(fd, globls, strtab, n);
- break;
- case Olit:
- sz = writelit(fd, strtab, n->expr.args[0], exprtype(n));
- break;
- case Oslice:
- sz = writeslice(fd, globls, strtab, n);
break;
default:
dump(n, stdout);
--- a/6/simp.c
+++ b/6/simp.c
@@ -488,24 +488,6 @@
s->nloopexit--;
}
-static Ucon *finducon(Node *n)
-{
- size_t i;
- Type *t;
- Ucon *uc;
-
- t = tybase(n->expr.type);
- if (exprop(n) != Oucon)
- return NULL;
- for (i = 0; i < t->nmemb; i++) {
- uc = t->udecls[i];
- if (!strcmp(namestr(uc->name), namestr(n->expr.args[0])))
- return uc;
- }
- die("No ucon?!?");
- return NULL;
-}
-
static Node *uconid(Simp *s, Node *n)
{
Ucon *uc;
@@ -513,7 +495,7 @@
if (exprop(n) != Oucon)
return load(addr(s, n, mktype(n->loc, Tyuint)));
- uc = finducon(n);
+ uc = finducon(exprtype(n), n->expr.args[0]);
return word(uc->loc, uc->id);
}
@@ -620,9 +602,10 @@
}
break;
case Tyunion:
- uc = finducon(pat);
- if (!uc)
- uc = finducon(val);
+ if (exprop(pat) == Oucon)
+ uc = finducon(exprtype(pat), pat->expr.args[0]);
+ else
+ uc = finducon(exprtype(val), val->expr.args[0]);
deeper = genlbl(pat->loc);
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -1051,6 +1051,7 @@
Ucon *uc;
Type *t;
+ *isconst = 1;
uc = uconresolve(st, n);
t = tyfreshen(st, tf(st, uc->utype));
uc = tybase(t)->udecls[uc->id];
@@ -1057,8 +1058,8 @@
if (uc->etype) {
inferexpr(st, &n->expr.args[1], NULL, NULL);
unify(st, n, uc->etype, type(st, n->expr.args[1]));
+ *isconst = n->expr.args[1]->expr.isconst;
}
- *isconst = n->expr.args[0]->expr.isconst;
settype(st, n, delayeducon(st, t));
}
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -495,6 +495,7 @@
Type *mktyunion(Srcloc l, Ucon **decls, size_t ndecls);
Trait *mktrait(Srcloc l, Node *name, Type *param, Node **memb, size_t nmemb, Node **funcs, size_t nfuncs, int isproto);
Type *mktylike(Srcloc l, Ty ty); /* constrains tyvar t like it was builtin ty */
+Ucon *finducon(Type *t, Node *name);
int istysigned(Type *t);
int istyunsigned(Type *t);
int istyfloat(Type *t);
--- a/parse/type.c
+++ b/parse/type.c
@@ -273,6 +273,17 @@
return t;
}
+Ucon *finducon(Type *ty, Node *name)
+{
+ size_t i;
+
+ ty = tybase(ty);
+ for (i = 0; i < ty->nmemb; i++)
+ if (!strcmp(namestr(ty->udecls[i]->name), namestr(name)))
+ return ty->udecls[i];
+ return NULL;
+}
+
int istyunsigned(Type *t)
{
switch (tybase(t)->type) {
--- a/test/tests
+++ b/test/tests
@@ -83,6 +83,7 @@
# B compoundimpl P intptr,charptr BUGGERED
B nestucon P asdf
B mkunion E 0
+B uconinit P 'A B C 123'
B genericcall E 42
B generictype E 0
B genericret E 42
--- /dev/null
+++ b/test/uconinit.myr
@@ -1,0 +1,21 @@
+use std
+
+type u = union
+ `A
+ `B
+ `C int
+;;
+
+const a = [`A, `B, `C 123]
+
+const main = {
+ for v in a
+ match v
+ | `A: std.put("A ")
+ | `B: std.put("B ")
+ | `C x: std.put("C %i\n", x)
+ ;;
+ ;;
+ std.put("\n")
+}
+