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