shithub: mc

Download patch

ref: 440ff74a6d16e3edb5322976ae5c9446f315c754
parent: 47e2fe4b898f4260414f84424929d8a7e09cd021
author: Ori Bernstein <[email protected]>
date: Wed Jun 27 20:48:08 EDT 2012

Infer types for unions.

--- a/parse/gram.y
+++ b/parse/gram.y
@@ -413,9 +413,9 @@
 
 unioncons
         : Ttick Tident addexpr
-            {$$ = mkexpr($1->line, Ocons, $2, $3, NULL);}
+            {$$ = mkexpr($1->line, Ocons, mkname($2->line, $2->str), $3, NULL);}
         | Ttick Tident
-            {$$ = mkexpr($1->line, Ocons, $2, NULL);}
+            {$$ = mkexpr($1->line, Ocons, mkname($2->line, $2->str), NULL);}
         | addexpr
         ;
 
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -371,6 +371,7 @@
 static void inferexpr(Node *n, Type *ret, int *sawret)
 {
     Node **args;
+    Ucon *uc;
     int nargs;
     Node *s;
     Type *t;
@@ -511,7 +512,16 @@
             }
             break;
         case Ocons:
-            die("Union constructors not yet supported\n");
+            uc = getucon(curstab(), args[0]);
+            if (!uc)
+                fatal(n->line, "No union constructor %s", namestr(n));
+            if (!uc->etype && n->expr.nargs > 1)
+                fatal(n->line, "nullary union constructor %s passed arg ", ctxstr(args[0]));
+            else if (uc->etype && n->expr.nargs != 2)
+                fatal(n->line, "union constructor %s needs arg ", ctxstr(args[0]));
+            else
+                unify(n, uc->etype, type(args[1]));
+            settype(n, uc->utype);
             break;
         case Olit:      /* <lit>:@a::tyclass -> @a */
             switch (args[0]->lit.littype) {