shithub: mc

Download patch

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")
+}
+