ref: 0a7a934f544bdd4ad8784fe87d3e87d0e154ff59
parent: 2a833f441b9a03e1222ab501e71fc029bf069665
author: Ori Bernstein <[email protected]>
date: Wed Sep 24 10:00:04 EDT 2014
Fix struct matching for out of order members.
--- a/6/simp.c
+++ b/6/simp.c
@@ -397,6 +397,28 @@
return tysize(t);
}
+/* gets the byte offset of 'memb' within the aggregate type 'aggr' */
+static size_t offset(Node *aggr, Node *memb)
+{
+ Type *ty;
+ size_t i;
+ size_t off;
+
+ ty = tybase(exprtype(aggr));
+ if (ty->type == Typtr)
+ ty = tybase(ty->sub[0]);
+
+ assert(ty->type == Tystruct);
+ off = 0;
+ for (i = 0; i < ty->nmemb; i++) {
+ off = alignto(off, decltype(ty->sdecls[i]));
+ if (!strcmp(namestr(memb), declname(ty->sdecls[i])))
+ return off;
+ off += size(ty->sdecls[i]);
+ }
+ die("Could not find member %s in struct", namestr(memb));
+ return -1;
+}
static Node *gentemp(Simp *simp, Node *e, Type *ty, Node **dcl)
{
char buf[128];
@@ -708,7 +730,7 @@
/* We got lucky. The structure of tuple, array, and struct literals
* is the same, so long as we don't inspect the type, so we can
* share the code*/
- case Tystruct: case Tytuple: case Tyarray:
+ case Tytuple: case Tyarray:
patarg = pat->expr.args;
off = 0;
for (i = 0; i < pat->expr.nargs; i++) {
@@ -721,6 +743,16 @@
}
jmp(s, iftrue);
break;
+ case Tystruct:
+ patarg = pat->expr.args;
+ for (i = 0; i < pat->expr.nargs; i++) {
+ off = offset(pat, patarg[i]->expr.idx);
+ next = genlbl();
+ v = load(addk(addr(s, val, exprtype(patarg[i])), off));
+ matchpattern(s, patarg[i], v, exprtype(patarg[i]), next, iffalse);
+ append(s, next);
+ }
+ break;
case Tyunion:
uc = finducon(pat);
if (!uc)
@@ -804,29 +836,6 @@
lappend(l, nl, d);
return r;
-}
-
-/* gets the byte offset of 'memb' within the aggregate type 'aggr' */
-static size_t offset(Node *aggr, Node *memb)
-{
- Type *ty;
- size_t i;
- size_t off;
-
- ty = tybase(exprtype(aggr));
- if (ty->type == Typtr)
- ty = tybase(ty->sub[0]);
-
- assert(ty->type == Tystruct);
- off = 0;
- for (i = 0; i < ty->nmemb; i++) {
- off = alignto(off, decltype(ty->sdecls[i]));
- if (!strcmp(namestr(memb), declname(ty->sdecls[i])))
- return off;
- off += size(ty->sdecls[i]);
- }
- die("Could not find member %s in struct", namestr(memb));
- return -1;
}
static Node *ptrsized(Simp *s, Node *v)
--- a/test/matchstruct.myr
+++ b/test/matchstruct.myr
@@ -13,7 +13,7 @@
v.v2 = 40
v.v3 = 10
match v
- | [.v1 = x, .v2 = y, .v3 = 10]:
+ | [.v2 = x, .v1 = y, .v3 = 10]:
std.exit(x + y)
| _:
std.die("Wat")