ref: eaf77a290652b4ce336260a69726fc5d0cb3ca69
parent: 5b10fd810aacd52389f3025bb085ef40b5b83037
author: Ori Bernstein <[email protected]>
date: Mon Oct 21 17:32:56 EDT 2013
Add support for struct patterns in matches.
--- a/6/simp.c
+++ b/6/simp.c
@@ -504,7 +504,7 @@
/* Should never show up */
case Tyint64: case Tyuint64: case Tylong: case Tyulong:
case Tyfloat32: case Tyfloat64:
- case Tyslice: case Tyarray: case Tystruct:
+ case Tyslice: case Tyarray:
die("Unsupported type for compare");
break;
case Tybool: case Tychar: case Tybyte:
@@ -515,15 +515,17 @@
v->expr.type = mktype(pat->line, Tybool);
cjmp(s, v, iftrue, iffalse);
break;
- case Tytuple:
+ /* We got lucky. The structure of tuple and struct literals is the
+ * same, so long as we don't inspect the type */
+ case Tystruct: case Tytuple:
patarg = pat->expr.args;
off = 0;
for (i = 0; i < pat->expr.nargs; i++) {
next = genlbl();
- v = load(addk(addr(s, val, t->sub[i]), off));
- umatch(s, patarg[i], v, t->sub[i], next, iffalse);
+ v = load(addk(addr(s, val, exprtype(patarg[i])), off));
+ umatch(s, patarg[i], v, exprtype(patarg[i]), next, iffalse);
append(s, next);
- off += tysize(t->sub[i]);
+ off += size(patarg[i]);
}
jmp(s, iftrue);
break;
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -133,7 +133,7 @@
%type <node> exprln retexpr goto expr atomicexpr littok literal asnexpr lorexpr landexpr borexpr
%type <node> bandexpr cmpexpr unionexpr addexpr mulexpr shiftexpr prefixexpr postfixexpr
-%type <node> funclit seqlit name block stmt label use
+%type <node> funclit seqlit tuplit name block stmt label use
%type <node> decl declbody declcore structent arrayelt structelt tuphead
%type <node> ifstmt forstmt whilestmt matchstmt elifs optexprln optexpr
%type <node> pat unionpat match
@@ -570,8 +570,6 @@
| literal
| Toparen expr Tcparen
{$$ = $2;}
- | Toparen tupbody Tcparen
- {$$ = mkexprl($1->line, Otup, $2.nl, $2.nn);}
| Tsizeof Toparen type Tcparen
{$$ = mkexpr($1->line, Osize, mkpseudodecl($3), NULL);}
;
@@ -595,8 +593,12 @@
literal : funclit {$$ = mkexpr($1->line, Olit, $1, NULL);}
| littok {$$ = mkexpr($1->line, Olit, $1, NULL);}
| seqlit {$$ = $1;}
+ | tuplit {$$ = $1;}
;
+tuplit : Toparen tupbody Tcparen
+ {$$ = mkexprl($1->line, Otup, $2.nl, $2.nn);}
+
littok : Tstrlit {$$ = mkstr($1->line, $1->str);}
| Tintlit {$$ = mkint($1->line, $1->intval);}
| Tchrlit {$$ = mkchar($1->line, *$1->str);} /* FIXME: expand escapes, unicode */
@@ -704,6 +706,7 @@
;
pat : unionpat {$$ = $1;}
+ | seqlit {$$ = $1;}
| tuppat {$$ = mkexprl($1.line, Otup, $1.nl, $1.nn);}
| littok {$$ = mkexpr($1->line, Olit, $1, NULL);}
| Tident {$$ = mkexpr($1->line, Ovar, mkname($1->line, $1->str), NULL);}
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -915,6 +915,7 @@
inferpat(st, args[i], val, bind, nbind);
switch (exprop(n)) {
case Otup: infernode(st, n, NULL, NULL); break;
+ case Ostruct: infernode(st, n, NULL, NULL); break;
case Olit: infernode(st, n, NULL, NULL); break;
case Omemb: infernode(st, n, NULL, NULL); break;
case Oucon: inferucon(st, n, &n->expr.isconst); break;
--- a/test/tests
+++ b/test/tests
@@ -82,6 +82,7 @@
B matchconst E 88
B matchunion E 84
B matchtup E 42
+B matchstruct E 42
B matchargunion E 69
B matchunion_sl P foo
B matchbind E 8