Eigenstate: myrddin-dev mailing list

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Allow matching of empty structs and arrays


---
This is regarding conversation on #myrddin. Please let me know if
something should be changed in style or substance.

 mi/match.c            |  8 +++++---
 test/empty-struct.myr | 26 ++++++++++++++++++++++++++
 test/tests            |  1 +
 3 files changed, 32 insertions(+), 3 deletions(-)
 create mode 100644 test/empty-struct.myr

diff --git a/mi/match.c b/mi/match.c
index 29f8cc44..3d159624 100644
--- a/mi/match.c
+++ b/mi/match.c
@@ -246,9 +246,11 @@ static int acceptall(Dtree *t, Dtree *accept)
 	return ret;
 }
 
-static int isbasictype(Dtree *dt, Type *ty)
+static int isnonrecursive(Dtree *dt, Type *ty)
 {
-	return istyprimitive(ty) || ty->type == Tyvoid || ty->type == Tyfunc || ty->type == Typtr;
+	return istyprimitive(ty) || ty->type == Tyvoid || ty->type == Tyfunc ||
+	ty->type == Typtr || (ty->type == Tystruct && ty->nmemb == 0) ||
+	(ty->type == Tyarray && fold(ty->asize, 1)->expr.args[0]->lit.intval == 0);
 }
 
 static int ismatchable(Type *ty)
@@ -269,7 +271,7 @@ static int addwildrec(Srcloc loc, Type *ty, Dtree *start, Dtree *accept, Dtree *
 	ty = tybase(ty);
 	if (ty->type == Typtr && start->any && start->any->ptrwalk) {
 		return addwildrec(loc, ty->sub[0], start->any, accept, end, nend);
-	} else if (isbasictype(start, ty)) {
+	} else if (isnonrecursive(start, ty)) {
 		if (start->accept || start == accept)
 			return 0;
 		for (i = 0; i < start->nnext; i++)
diff --git a/test/empty-struct.myr b/test/empty-struct.myr
new file mode 100644
index 00000000..a3ec75a8
--- /dev/null
+++ b/test/empty-struct.myr
@@ -0,0 +1,26 @@
+use std
+
+type foo = struct
+;;
+
+type bar = struct
+        baz : foo[:]
+        quux : foo[0][:]
+;;
+
+
+const main = {
+        var a : foo
+        var z : foo[0]
+        var b : bar = [.baz = [a, a][:], .quux = [z, z, z][:]]
+        var c : int = 0
+        for f in b.baz
+                c += 3
+        ;;
+
+        for f in b.quux
+                c += 5
+        ;;
+
+        std.exit(c)
+}
diff --git a/test/tests b/test/tests
index b7ab8e1d..fcd058c4 100644
--- a/test/tests
+++ b/test/tests
@@ -144,6 +144,7 @@ B strfind	C
 B strjoin	C
 B exporttrait	E	0
 B local-labels	E	10
+B empty-struct	E	21
 F declmismatch
 F infermismatch
 F usedef
-- 
2.13.2


Follow-Ups:
Re: [PATCH] Allow matching of empty structs and arraysOri Bernstein <ori@xxxxxxxxxxxxxx>