shithub: mc

Download patch

ref: a8935c73459f261ab58b80d4c3936910181813cd
parent: a0697ff99ca952c46320707b2532bf1459078f56
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Jan 24 18:02:36 EST 2016

Add pointer match syntax.

--- a/mi/match.c
+++ b/mi/match.c
@@ -168,7 +168,7 @@
 	case Tybool:	return 2;	break;
 	case Tychar:	return 0x10ffff;	break;
 
-			/* signed ints */
+	/* signed ints */
 	case Tyint8:	return 0x100;	break;
 	case Tyint16:	return 0x10000;	break;
 	case Tyint32:	return 0x100000000;	break;
@@ -175,7 +175,7 @@
 	case Tyint:	return 0x100000000;	break;
 	case Tyint64:	return ~0ull;	break;
 
-			/* unsigned ints */
+	/* unsigned ints */
 	case Tybyte:	return 0x100;	break;
 	case Tyuint8:	return 0x100;	break;
 	case Tyuint16:	return 0x10000;	break;
@@ -183,11 +183,11 @@
 	case Tyuint:	return 0x100000000;	break;
 	case Tyuint64:	return ~0ull;	break;
 
-			/* floats */
+	/* floats */
 	case Tyflt32:	return ~0ull;	break;
 	case Tyflt64:	return ~0ull;	break;
 
-			/* complex types */
+	/* complex types */
 	case Typtr:	return 1;	break;
 	case Tyarray:	return 1;	break;
 	case Tytuple:	return 1;	break;
@@ -339,6 +339,11 @@
 		ret = acceptall(start, accept);
 		lappend(&last, &nlast, accept);
 		break;
+	case Typtr:
+		/* we only want to descend if there's something to match here. */
+		if (start->any || start->nnext > 0)
+			ret = addwildrec(loc, ty->sub[0], start, accept, &last, &nlast);
+		break;
 	default:
 		ret = 1;
 		lappend(&last, &nlast, accept);
@@ -584,6 +589,16 @@
 	return ret;
 }
 
+static int addderefpat(Node *pat, Node *val, Dtree *start, Dtree *accept, Node ***cap, size_t *ncap, Dtree ***end, size_t *nend)
+{
+	Node *deref;
+
+	deref = mkexpr(val->loc, Oderef, val, NULL);
+	deref->expr.type = exprtype(pat->expr.args[0]);
+	start->nconstructors = nconstructors(exprtype(deref));
+	return addpat(pat->expr.args[0], deref, start, accept, cap, ncap, end, nend);
+}
+
 static int addpat(Node *pat, Node *val, Dtree *start, Dtree *accept, Node ***cap, size_t *ncap, Dtree ***end, size_t *nend)
 {
 	int ret;
@@ -616,6 +631,9 @@
 		break;
 	case Ogap:
 		ret = addwild(pat, NULL, start, accept, NULL, NULL, end, nend);
+		break;
+	case Oaddr:
+		ret = addderefpat(pat, val, start, accept, cap, ncap, end, nend);
 		break;
 	default:
 		fatal(pat, "unsupported pattern %s of type %s", opstr[exprop(pat)], tystr(exprtype(pat)));
--- /dev/null
+++ b/test/matchptr.myr
@@ -1,0 +1,13 @@
+use std
+
+const main = {
+	var x : std.option(std.option(int)#)
+
+	x = `std.Some &(`std.Some 123)
+	match x
+	| `std.Some &(`std.None):	std.put("failed\n")
+	| `std.Some &(`std.Some 666):	std.put("failed\n")
+	| `std.Some &(`std.Some 123):	std.put("worked\n")
+	| _:	std.put("failed\n")
+	;;
+}
--- a/test/tests
+++ b/test/tests
@@ -114,6 +114,7 @@
 B matchargstr	C
 B matchunion_sl	P	foo
 B matchbind	E	8
+B matchptr	P	'worked'
 F matchmixed
 B bigliteral	P	34359738368
 B arraylit-ni	E	2