summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMura Li <mura_li@castech.com.tw>2020-04-22 09:32:04 +0000
committerOri Bernstein <ori@eigenstate.org>2020-05-05 20:33:19 -0700
commit15ad5bac3dd1a18be6e632afa73f5ac12b4a5ec1 (patch)
treed133a3ccd553cd5e00dc45864c8882cfd29fddab
parent9ef8abbefa9171d713fba46d8f84ac0000cb758b (diff)
downloadmc-15ad5bac3dd1a18be6e632afa73f5ac12b4a5ec1.tar.gz
Support or-patterns with wildcard variables
-rw-r--r--mi/match.c9
-rw-r--r--parse/infer.c22
-rw-r--r--test/matchor.myr20
3 files changed, 45 insertions, 6 deletions
diff --git a/mi/match.c b/mi/match.c
index 1d69eda..a6f585c 100644
--- a/mi/match.c
+++ b/mi/match.c
@@ -906,7 +906,14 @@ clearemit(Dtree *dt)
static int
capeq(Node *a, Node *b)
{
- return 1;
+ Node *pa, *pb, *va, *vb;
+
+ pa = a->expr.args[0];
+ pb = b->expr.args[0];
+ va = a->expr.args[1];
+ vb = b->expr.args[1];
+
+ return decltype(decls[pa->expr.did]) == decltype(decls[pb->expr.did]) && loadeq(va, vb);
}
Dtree *
diff --git a/parse/infer.c b/parse/infer.c
index 5150621..eff416a 100644
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -1580,11 +1580,23 @@ inferpat(Node **np, Node *val, Node ***bind, size_t *nbind)
fatal(n, "pattern shadows variable declared on %s:%d near %s",
fname(s->loc), lnum(s->loc), ctxstr(s));
} else {
- t = mktyvar(n->loc);
- s = mkdecl(n->loc, n->expr.args[0], t);
- s->decl.init = val;
- settype(n, t);
- lappend(bind, nbind, s);
+ /* Scan the already collected bound variables in the pattern of this match case.
+ * If a bound variable with the same name is found, assign the variable the existing decl.
+ * Otherwise, create a new decl for the variable */
+ s = NULL;
+ for (i = 0; !s && i < *nbind; i++)
+ if (nameeq(args[0], (*bind)[i]->decl.name))
+ s = (*bind)[i];
+
+ if (s) {
+ t = s->decl.type;
+ } else {
+ t = mktyvar(n->loc);
+ s = mkdecl(n->loc, n->expr.args[0], t);
+ s->decl.init = val;
+ settype(n, t);
+ lappend(bind, nbind, s);
+ }
}
settype(n, t);
n->expr.did = s->decl.did;
diff --git a/test/matchor.myr b/test/matchor.myr
index 0ac8b7a..9d07668 100644
--- a/test/matchor.myr
+++ b/test/matchor.myr
@@ -41,5 +41,25 @@ const main = {
| _: std.exit(1)
;;
+ type bar = union
+ `A int
+ `B int
+ `C int
+ `D (byte[:], int)
+ `E (byte[:], int)
+ `F (int, std.option(int))
+ `G (int, std.option(int))
+ ;;
+
+ match `A 123
+ | `A x || `B x: std.put("good #4 {}\n", x)
+ | _: std.exit(1)
+ ;;
+
+ match `G (223, `std.Some 556)
+ | `F (x, `std.Some y) || `G (x, `std.Some y): std.put("good #5 x={} y={}\n", x, y)
+ | _: std.exit(1)
+ ;;
+
std.put("all good\n")
}