shithub: mc

Download patch

ref: 019c09f1c3d0d04dc60ba01b0a51e59d5b4fdcaa
parent: 9873b208d15f5486f9b417f4de0f70be4b57ae24
parent: bc6c47037bff22b29abc5418fc04c4af4fbc28d9
author: Ori Bernstein <[email protected]>
date: Tue Sep 4 17:28:19 EDT 2012

Merge branch 'master' of git+ssh://mimir.eigenstate.org/git/ori/mc2

--- a/6/simp.c
+++ b/6/simp.c
@@ -422,18 +422,18 @@
     return NULL;
 }
 
-static Node *uconid(Node *n, size_t off)
+static Node *uconid(Node *n)
 {
     Ucon *uc;
 
     if (exprop(n) != Oucon)
-        return load(addk(addr(n, mktype(n->line, Tyuint)), off));
+        return load(addr(n, mktype(n->line, Tyuint)));
 
     uc = finducon(n);
     return word(uc->line, uc->id);
 }
 
-static Node *uval(Node *n, size_t off, Type *t)
+static Node *patval(Node *n, Type *t)
 {
     if (exprop(n) == Oucon)
         return n->expr.args[1];
@@ -440,13 +440,13 @@
     else if (exprop(n) == Olit)
         return n;
     else
-        return load(addk(addr(n, t), off));
+        return load(addk(addr(n, t), Wordsz));
 }
 
-static void umatch(Simp *s, Node *pat, Node *val, Type *t, size_t off, Node *iftrue, Node *iffalse)
+static void umatch(Simp *s, Node *pat, Node *val, Type *t, Node *iftrue, Node *iffalse)
 {
     Node *v, *x, *y;
-    Node *next;
+    Node *deeper;
     Ucon *uc;
 
     assert(pat->type == Nexpr);
@@ -473,26 +473,25 @@
         case Tyint8: case Tyint16: case Tyint32: case Tyint:
         case Tyuint8: case Tyuint16: case Tyuint32: case Tyuint:
         case Typtr: case Tyfunc:
-            x = uval(pat, off, t);
-            y = uval(val, off, t);
-            v = mkexpr(pat->line, Oeq, x, y, NULL);
+            v = mkexpr(pat->line, Oeq, pat, val, NULL);
             cjmp(s, v, iftrue, iffalse);
             break;
         case Tyunion:
-            x = uconid(pat, off);
-            y = uconid(val, off);
             uc = finducon(pat);
             if (!uc)
                 uc = finducon(val);
+            deeper = genlbl();
 
-            next = genlbl();
+            x = uconid(pat);
+            y = uconid(val);
             v = mkexpr(pat->line, Oeq, x, y, NULL);
             v->expr.type = tyintptr;
-            cjmp(s, v, next, iffalse);
-            append(s, next);
+            cjmp(s, v, deeper, iffalse);
+            append(s, deeper);
             if (uc->etype) {
-                off += Wordsz;
-                umatch(s, pat, val, uc->etype, off, iftrue, iffalse);
+                pat = patval(pat, uc->etype);
+                val = patval(val, uc->etype);
+                umatch(s, pat, val, uc->etype, iftrue, iffalse);
             }
             break;
     }
@@ -518,7 +517,7 @@
         /* check pattern */
         cur = genlbl();
         next = genlbl();
-        umatch(s, m->match.pat, val, val->expr.type, 0, cur, next);
+        umatch(s, m->match.pat, val, val->expr.type, cur, next);
 
         /* do the action if it matches */
         append(s, cur);
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -122,12 +122,12 @@
 
 %type <ty> type structdef uniondef tupledef compoundtype functype funcsig
 %type <ty> generictype
-%type <tylist> tuptybody
+%type <tylist> typelist
 %type <nodelist> typaramlist
 
 %type <tok> asnop cmpop addop mulop shiftop
 
-%type <tydef> tydef
+%type <tydef> tydef typeid
 
 %type <node> exprln retexpr expr atomicexpr littok literal asnexpr lorexpr landexpr borexpr
 %type <node> bandexpr cmpexpr unionexpr addexpr mulexpr shiftexpr prefixexpr postfixexpr
@@ -137,11 +137,11 @@
 %type <node> pat unionpat match
 %type <node> castexpr
 %type <ucon> unionelt
-%type <node> body 
+%type <node> body
 
 %type <nodelist> arglist argdefs params matches
 %type <nodelist> structbody seqbody tupbody tuprest
-%type <uconlist> unionbody 
+%type <uconlist> unionbody
 
 %union {
     struct {
@@ -163,6 +163,8 @@
         int line;
         char *name;
         Type *type;
+        Type **params;
+        size_t nparams;
     } tydef;
     Node *node;
     Tok  *tok;
@@ -256,16 +258,30 @@
             {$$ = $3; setns($3, $1->str);}
         ;
 
-tydef   : Ttype Tident Tasn type
+tydef   : Ttype typeid Tasn type
+            {$$ = $2;
+             $$.type = mktyalias($2.line, mkname($2.line, $2.name), $4);}
+        | Ttype typeid
+            {$$ = $2;}
+        ;
+
+typeid  : Tident
             {$$.line = $1->line;
-             $$.name = $2->str;
-             $$.type = mktyalias($2->line, mkname($2->line, $2->str), $4);}
-        | Ttype Tident
-            {$$.line = $1->line;
-             $$.name = $2->str;
+             $$.name = $1->str;
+             $$.params = NULL;
              $$.type = NULL;}
+        | Tident Toparen typarams Tcparen
+            {$$.line = $1->line;
+             $$.name = $1->str;
+             $$.params = NULL;
+             $$.type = NULL;
+             die("Unimplemented generic types");}
         ;
 
+typarams: generictype
+        | typarams Tcomma generictype
+        ;
+
 type    : structdef
         | tupledef
         | uniondef
@@ -300,8 +316,9 @@
         | type Tosqbrac Tcolon Tcsqbrac {$$ = mktyslice($2->line, $1);}
         | type Tosqbrac expr Tcsqbrac {$$ = mktyarray($2->line, $1, $3);}
         | type Tstar {$$ = mktyptr($2->line, $1);}
-        | name       {$$ = mktynamed($1->line, $1);}
         | Tat Tident {$$ = mktyparam($1->line, $2->str);}
+        | name       {$$ = mktynamed($1->line, $1);}
+        | name Toparen typelist Tcparen {die("Generic types not supported");}
         ;
 
 functype: Toparen funcsig Tcparen {$$ = $2;}
@@ -325,15 +342,14 @@
              $$.nn = 0;}
         ;
 
-tupledef: Tosqbrac tuptybody Tcsqbrac
+tupledef: Tosqbrac typelist Tcsqbrac
             {$$ = mktytuple($1->line, $2.types, $2.ntypes);}
         ;
 
-tuptybody
-        : type
+typelist: type
             {$$.types = NULL; $$.ntypes = 0;
              lappend(&$$.types, &$$.ntypes, $1);}
-        | tuptybody Tcomma type
+        | typelist Tcomma type
             {lappend(&$$.types, &$$.ntypes, $3);}
         ;
 
@@ -714,6 +730,8 @@
     Type *b;
     size_t i;
 
+    if (!t)
+        return;
     b = tybase(t);
     if (b->type != Tyunion)
         return;
--- a/test/tests
+++ b/test/tests
@@ -57,6 +57,7 @@
 B generic	E	42
 B cstr-builtin	E	42
 B genericcall	E	42
+B generictype	E	0
 B sizeof	E	4
 B gsizeof	E	5
 B mkunion	E	0