shithub: mc

Download patch

ref: b0ced7c8189081449ffa6073d134a53898cba89f
parent: 6a4f50b69edba3548b265cbcb99c5dbd7ada04c5
author: Ori Bernstein <[email protected]>
date: Sun Jun 24 16:13:53 EDT 2012

Add parsing for union constructors.

--- a/8/isel.c
+++ b/8/isel.c
@@ -559,7 +559,7 @@
         case Osubeq: case Omuleq: case Odiveq: case Omodeq: case Oboreq:
         case Obandeq: case Obxoreq: case Obsleq: case Obsreq: case Omemb:
         case Oslice: case Oidx: case Osize: case Numops:
-        case Oslbase: case Osllen: case Ocast:
+        case Oslbase: case Osllen: case Ocast: case Ocons:
             dump(n, stdout);
             die("Should not see %s in isel", opstr(exprop(n)));
             break;
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -67,6 +67,7 @@
 %token<tok> Tosqbrac /* [ */
 %token<tok> Tcsqbrac /* ] */
 %token<tok> Tat      /* @ */
+%token<tok> Ttick    /* ` */
 
 %token<tok> Ttype            /* type */
 %token<tok> Tfor             /* for */
@@ -122,7 +123,7 @@
 %type <tydef> tydef
 
 %type <node> exprln retexpr expr atomicexpr literal asnexpr lorexpr landexpr borexpr
-%type <node> bandexpr cmpexpr addexpr mulexpr shiftexpr prefixexpr postfixexpr
+%type <node> bandexpr cmpexpr unioncons addexpr mulexpr shiftexpr prefixexpr postfixexpr
 %type <node> funclit arraylit name block blockbody stmt label use
 %type <node> decl declbody declcore structelt unionelt
 %type <node> ifstmt forstmt whilestmt elifs optexprln
@@ -319,7 +320,8 @@
 
 unionbody
         : unionelt
-            {$$.nl = NULL; $$.nn = 0; lappend(&$$.nl, &$$.nn, $1);}
+            {$$.nl = NULL; $$.nn = 0;
+             if ($1) {lappend(&$$.nl, &$$.nn, $1);}}
         | unionbody unionelt
             {if ($2) {lappend(&$$.nl, &$$.nn, $2);}}
         ;
@@ -326,7 +328,7 @@
 
 unionelt
         : Tident type Tendln
-            {$$ = NULL; die("unionelt impl");}
+            {$$ = mkdecl($1->line, mkname($1->line, $1->str), $2);}
         | visdef Tendln
             {$$ = NULL;}
         | Tendln
@@ -390,12 +392,18 @@
         | cmpexpr
         ;
 
-cmpexpr : cmpexpr cmpop addexpr
+cmpexpr : cmpexpr cmpop unioncons
             {$$ = mkexpr($1->line, binop($2->type), $1, $3, NULL);}
-        | addexpr
+        | unioncons
         ;
 
 cmpop   : Teq | Tgt | Tlt | Tge | Tle | Tne ;
+
+unioncons
+        : Ttick Tident addexpr
+            {$$ = mkexpr($1->line, Ocons, $2, $3, NULL);}
+        | addexpr
+        ;
 
 addexpr : addexpr addop mulexpr
             {$$ = mkexpr($1->line, binop($2->type), $1, $3, NULL);}
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -500,6 +500,9 @@
                 lappend(&genericdecls, &ngenericdecls, s);
             }
             break;
+        case Ocons:
+            die("Union constructors not yet supported\n");
+            break;
         case Olit:      /* <lit>:@a::tyclass -> @a */
             switch (args[0]->lit.littype) {
                 case Lfunc: infernode(args[0]->lit.fnval, NULL, NULL); break;
--- a/parse/ops.def
+++ b/parse/ops.def
@@ -48,6 +48,7 @@
 O(Ovar, 1)
 O(Olit, 1)
 O(Olbl, 1)
+O(Ocons, 1)
 /* backend-only */
 O(Ocjmp, 1)        /* conditional jump */
 O(Oload, 1)        /* load from memory */
--- a/parse/tok.c
+++ b/parse/tok.c
@@ -259,6 +259,7 @@
         case '[': tt = Tosqbrac; break;
         case ']': tt = Tcsqbrac; break;
         case ',': tt = Tcomma; break;
+        case '`': tt = Ttick; break;
         case ':':
                   if (match(':'))
                       tt = Tcoloncolon;