diff options
Diffstat (limited to 'lib/compiler/test/match_SUITE.erl')
-rw-r--r-- | lib/compiler/test/match_SUITE.erl | 355 |
1 files changed, 355 insertions, 0 deletions
diff --git a/lib/compiler/test/match_SUITE.erl b/lib/compiler/test/match_SUITE.erl new file mode 100644 index 0000000000..20969c0b26 --- /dev/null +++ b/lib/compiler/test/match_SUITE.erl @@ -0,0 +1,355 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +-module(match_SUITE). + +-export([all/1, + pmatch/1,mixed/1,aliases/1,match_in_call/1, + untuplify/1,shortcut_boolean/1,letify_guard/1, + selectify/1]). + +-include("test_server.hrl"). + +all(suite) -> + test_lib:recompile(?MODULE), + [pmatch,mixed,aliases,match_in_call,untuplify,shortcut_boolean, + letify_guard,selectify]. + +pmatch(Config) when is_list(Config) -> + ?line ok = doit(1), + ?line ok = doit(2), + ?line {error,baz} = doit(3), + ?line {error,foobar} = doit(4), + ok. + +%% Thanks to Tobias Lindahl (HiPE). +-define(FOO(X), + case X of + 1 -> foo; + 2 -> bar; + 3 -> baz; + 4 -> foobar + end). + +doit(X) -> + case ?FOO(X) of + foo -> ok; + bar -> ok; + Other -> {error, Other} + end. + +mixed(Config) when is_list(Config) -> + ?line glufs = mixit(1), + ?line klafs = mixit(2), + ?line fnurra = mixit(3), + ?line usch = mixit(4), + ?line {error,blurf} = mixit(5), + ?line {error,87987987} = mixit(6), + ?line {error,{a,b,c}} = mixit(7), + ok. + +mixit(X) -> + case case X of + 1 -> a; + 2 -> b; + 3 -> 42; + 4 -> 77; + 5 -> blurf; + 6 -> 87987987; + 7 -> {a,b,c} + end of + a -> glufs; + b -> klafs; + 42 -> fnurra; + 77 -> usch; + Other -> {error,Other} + end. + +aliases(Config) when is_list(Config) -> + %% Lists/strings. + ?line ok = str_alias("abc"), + ?line ok = str_alias("def"), + ?line ok = str_alias("ghi"), + ?line ok = str_alias("klm"), + ?line ok = str_alias("qrs"), + ?line ok = str_alias("xy"), + ?line ok = str_alias(""), + ?line ok = str_alias([]), + ?line error = str_alias("blurf"), + + %% Characters/integers. + ?line ok = char_alias($v), + ?line ok = char_alias(118), + ?line ok = char_alias($w), + ?line ok = char_alias(119), + ?line ok = char_alias(42), + ?line ok = char_alias(3.0), + ?line error = char_alias($_), + ?line error = char_alias(0), + + ?line {42,42,42} = three(42), + + ?line {1,42,99,1,42,99} = tuple_alias({1,42,99}), + ?line {-10,20,-10,20,-10,20} = tuple_alias({-10,20}), + ?line 6 = tup_lit_alias({1,2,3}), + ?line 6 = tup_lit_alias_rev({1,2,3}), + + ?line {42,42,42,42} = multiple_aliases_1(42), + ?line {7,7,7} = multiple_aliases_2(7), + ?line {{a,b},{a,b},{a,b}} = multiple_aliases_3({a,b}), + ok. + +str_alias(V) -> + Res = str_alias_1(V), + Res = str_alias_2(V). + +str_alias_1([$a,$b,$c]="abc"="a"++[$b,$c]=[97,98,99]) -> ok; +str_alias_1([$d|"ef"]="def") -> ok; +str_alias_1([$g|"hi"]="g"++"hi"="gh"++"i"="ghi"++"") -> ok; +str_alias_1("k"++"lm"=[$k|"lm"]) -> ok; +str_alias_1([113,114,115]="qrs"=[$q,$r,$s]="q"++"r"++"s") -> ok; +str_alias_1([$x,$y]="xy") -> ok; +str_alias_1(""=[]) -> ok; +str_alias_1(_) -> error. + +%% Make sure that different line numbers do not matter. + +str_alias_2([$a,$b,$c]= + "abc"= + "a"++[$b,$c + ]= + [97,98,99 + ]) -> ok; +str_alias_2([$d|"ef"]= + "def") -> ok; +str_alias_2([$g|"hi"]= + "g"++"hi"= + "gh"++"i"= + "ghi"++"") -> ok; +str_alias_2("k"++"lm"= + [$k|"lm" + ]) -> ok; +str_alias_2([113,114,115]= + "qrs"=[$q,$r,$s + ]= + "q"++"r"++"s") -> ok; +str_alias_2([$x,$y]= + "xy") -> ok; +str_alias_2(""= + []) -> ok; +str_alias_2(_) -> error. + +char_alias(V) -> + Res = char_alias_1(V), + Res = char_alias_2(V). + +char_alias_1(118=$v) -> ok; +char_alias_1($w=119) -> ok; +char_alias_1(42=42) -> ok; +char_alias_1(3.0=3.0) -> ok; +char_alias_1(_) -> error. + +char_alias_2(118= + $v) -> ok; +char_alias_2($w= + 119) -> ok; +char_alias_2(42= + 42) -> ok; +char_alias_2(3.0= + 3.0) -> ok; +char_alias_2(_) -> error. + +three(V) -> + Res = three_1(V), + Res = three_2(V). + +three_1(A=B=C) -> + {A,B,C}. + +three_2(A= + B= + C) -> + {A,B,C}. + +tuple_alias({A,B,C}={X,Y,Z}) -> + {A,B,C,X,Y,Z}; +tuple_alias({A,B}={C,D}={E,F}) -> + {A,B,C,D,E,F}. + +tup_lit_alias({A,B,C}={1,2,3}) -> + A+B+C. + +tup_lit_alias_rev({1,2,3}={A,B,C}) -> + A+B+C. + +multiple_aliases_1((A=B)=(C=D)) -> + {A,B,C,D}. + +multiple_aliases_2((A=B)=(A=C)) -> + {A,B,C}. + +multiple_aliases_3((A={_,_}=B)={_,_}=C) -> + {A,B,C}. + +%% OTP-7018. + +match_in_call(Config) when is_list(Config) -> + ?line mac_a(0), + ?line mac_b(1), + ?line mac_c(42), + ?line mac_d(42), + ?line mac_e({gurka,42}), + + ?line [{2,2},{2,2}] = mac_lc([{2,any},{2,2}]), + ?line {'EXIT',_} = (catch mac_lc([{1,1}])), + + ok. + +mac_a(X) -> + id(_Gurka = {gurka,X}), + ok. + +mac_b(X) -> + id(Gurka = {gurka,X}), + gurka(Gurka, X), + ok. + +mac_c(X) -> + id(Gurka = Yxa = {gurka,X}), + id({Gurka,Yxa}), + ok. + +mac_d(X) -> + id({gurka,42} = {gurka,X}), + ok. + +mac_e(X) -> + id({gurka,42} = X), + ok. + +mac_lc(E) -> + Res = mac_lc1(E), + Res = mac_lc2(E). + +mac_lc1(E) -> + [{X,Y} || + {X,_} <- E, + (Y = X) =:= (Y = 1 + 1)]. + +mac_lc2(E) -> + [{X,Y} || + {X,_} <- E, + (Y = X) =:= (Y = 2)]. + +gurka({gurka,X}, X) -> ok. + + +untuplify(Config) when is_list(Config) -> + %% We do this to cover sys_core_fold:unalias_pat/1. + ?line {1,2,3,4,alias,{[1,2],{3,4},alias}} = untuplify_1([1,2], {3,4}, alias), + ?line error = untuplify_1([1,2], {3,4}, 42), + ok. + +untuplify_1(A, B, C) -> + case {A,B,C} of + {[X,Y],{Z,W},alias=Alias}=Top -> + {X,Y,Z,W,Alias,Top}; + [_,_]=CantMatch -> + CantMatch; + _ -> + error + end. + +%% Coverage of beam_dead:shortcut_boolean_label/4. +shortcut_boolean(Config) when is_list(Config) -> + ?line false = shortcut_boolean_1([0]), + ?line true = shortcut_boolean_1({42}), + ?line maybe = shortcut_boolean_1(self()), + ?line {'EXIT',_} = (catch shortcut_boolean_1([a,b])), + ?line {'EXIT',_} = (catch shortcut_boolean_1({a,b})), + ok. + +shortcut_boolean_1(X) -> + Outer = case not is_pid(X) of + true -> + V = case X of + [_] -> true; + {_} -> false + end, + not V; + false -> + maybe + end, + id(Outer). + + +%% Test sys_core_fold:letify_guard/3. +letify_guard(Config) when is_list(Config) -> + ?line {-15,a} = letify_guard(-15, a), + ?line 5 = letify_guard(2, 3), + ok. + +letify_guard(A, B) -> + case {A,B} of + %% The tuple will be built in the guard... + Z when tuple_size(Z) =:= 2, element(1, Z) < 0 -> + %% ... and again here. + Z; + {X,Y} -> X+Y + end. + +%% Test combining of is_eq_exact instructions to select_val +%% instructions in beam_dead and beam_peep. + +selectify(Config) when is_list(Config) -> + ?line integer = sel_different_types({r,42}), + ?line atom = sel_different_types({r,forty_two}), + ?line none = sel_different_types({r,18}), + ?line {'EXIT',_} = (catch sel_different_types([a,b,c])), + + ?line integer = sel_same_value({r,42}), + ?line error = sel_same_value({r,100}), + ?line error = sel_same_value(a), + + ?line integer42 = sel_same_value2(42), + ?line integer43 = sel_same_value2(43), + ?line error = sel_same_value2(44), + ok. + +sel_different_types({r,_}=T) when element(2, T) =:= forty_two -> + atom; +sel_different_types({r,_}=T) when element(2, T) =:= 42 -> + integer; +sel_different_types({r,_}) -> + none. + +sel_same_value({r,V}) when V =:= 42 -> + integer; +sel_same_value({r,V}) when V =:= 42 -> + integer42; +sel_same_value(_) -> + error. + +sel_same_value2(V) when V =:= 42 -> + integer42; +sel_same_value2(V) when V =:= 42; V =:= 43 -> + integer43; +sel_same_value2(_) -> + error. + +id(I) -> I. |