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) {