shithub: mc

Download patch

ref: 47860ff9a4411442997c2f8166aa6b24fbfeac2e
parent: d430e0f5a5bce917b9063ef7da943a5bd2d59391
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")