Преглед на файлове

some small fixes related to tuple pattern matching

Simon Krajewski преди 12 години
родител
ревизия
fb93b96c07
променени са 2 файла, в които са добавени 31 реда и са изтрити 7 реда
  1. 13 7
      matcher.ml
  2. 18 0
      tests/unit/TestMatch.hx

+ 13 - 7
matcher.ml

@@ -546,8 +546,9 @@ let default mctx pmat =
 			add (array_tl pv) out
  		| POr(pat1,pat2) ->
 			let tl = array_tl pv in
+			let out2 = clone_out mctx out [pat2] pat2.p_pos in
 			loop2 (Array.append [|pat1|] tl) out;
-			loop2 (Array.append [|pat2|] tl) out;
+			loop2 (Array.append [|pat2|] tl) out2;
 		| PBind(_,pat) ->
 			loop2 (Array.append [|pat|] (array_tl pv)) out
 		| PTuple tl ->
@@ -567,6 +568,8 @@ let pick_column pmat =
 	let rec loop i pv = if Array.length pv = 0 then -1 else match pv.(0).p_def with
 		| PVar _ | PAny ->
 			loop (i + 1) (array_tl pv)
+		| PTuple pl ->
+			loop i pl
 		| _ ->
 			i
 	in
@@ -606,23 +609,24 @@ let column_sigma mctx st pmat =
 	in
 	let rec loop pmat = match pmat with
 		| (pv,out) :: pr ->
-			let rec loop2 = function
+			let rec loop2 out = function
 				| PCon (c,_) ->
 					add c (out.o_guard <> None);
 				| POr(pat1,pat2) ->
-					loop2 pat1.p_def;
-					loop2 pat2.p_def;
+					let out2 = clone_out mctx out [pat2] pat2.p_pos in
+					loop2 out pat1.p_def;
+					loop2 out2 pat2.p_def;
 				| PVar v ->
 					bind_st out st v;
 				| PBind(v,pat) ->
 					bind_st out st v;
-					loop2 pat.p_def
+					loop2 out pat.p_def
 				| PAny ->
 					()
 				| PTuple tl ->
-					loop ((tl,out) :: pr)
+					loop2 out tl.(0).p_def
 			in
-			loop2 pv.(0).p_def;
+			loop2 out pv.(0).p_def;
 			loop pr
 		| [] ->
 			()
@@ -689,6 +693,8 @@ let bind_remaining out pv stl =
 			| st :: stl,PVar v ->
 				bind_st out st v;
 				loop stl (array_tl pv)
+			| stl,PTuple pl ->
+				loop stl pl
 			| _ :: _,_->
 				loop stl (array_tl pv)
 			| [],_ ->

+ 18 - 0
tests/unit/TestMatch.hx

@@ -197,6 +197,24 @@ class TestMatch extends Test {
 		});
 	}
 	
+	function testTuple() {
+		function test(a:Int, b:Int, c:Int) return switch [a, b, c] {
+			case [x, 1, 2] | [1, 2, x] | [1, x, 2]: '0|x:$x';
+			case [3, 4, z] | [z, 3, 4] | [3, z, 4]: '1|z:$z';
+			case [1, y, z] | [2, z, y]: '2|y:$y,z:$z';
+			case [x, y, z]: '_:x:$x,y:$y,z:$z';
+		}
+		eq("0|x:9", test(9, 1, 2));
+		eq("0|x:9", test(1, 2, 9));
+		eq("0|x:9", test(1, 9, 2));
+		eq("1|z:12", test(3, 4, 12));
+		eq("1|z:12", test(12, 3, 4));
+		eq("1|z:12", test(3, 12, 4));
+		eq("2|y:9,z:8", test(1, 9, 8));
+		eq("2|y:9,z:8", test(2, 8, 9));
+		eq("_:x:9,y:8,z:7", test(9, 8, 7));
+	}
+	
 	function testSubtyping() {
 		var c = new MyClass.InitBase();
 		var r = switch(c) {