aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2016-11-18 12:06:42 +0100
committerBjörn Gustavsson <[email protected]>2016-11-18 12:06:42 +0100
commit79653c709f854e6fadd719ef5f079f66219c6bdf (patch)
tree2f2a3a1a3b1a06a5e458424da5cb88f9733ec56f /lib
parentf578f6c57438ac7dd11a3d113406a104f4064b26 (diff)
parent09f170e35cf9df8438ae42d48b51becff167b5b4 (diff)
downloadotp-79653c709f854e6fadd719ef5f079f66219c6bdf.tar.gz
otp-79653c709f854e6fadd719ef5f079f66219c6bdf.tar.bz2
otp-79653c709f854e6fadd719ef5f079f66219c6bdf.zip
Merge branch 'bjorn/compiler/guards/PR-1232/OTP-14042'
* bjorn/compiler/guards/PR-1232/OTP-14042: compile_SUITE: Make sure that guards are optimized beam_dead: Remove redundant 'or' instruction beam_dead: Remove redundant 'bif' instructions Add test using LFE-generated Core Erlang modules Remove beam_bool v3_kernel: Generate optimized code for guards sys_core_fold: Remove unnecessary calls to opt_bool_case/1 record_SUITE: Strengthen test of record access in guards
Diffstat (limited to 'lib')
-rw-r--r--lib/compiler/src/Makefile1
-rw-r--r--lib/compiler/src/beam_bool.erl765
-rw-r--r--lib/compiler/src/beam_dead.erl32
-rw-r--r--lib/compiler/src/beam_jump.erl32
-rw-r--r--lib/compiler/src/beam_utils.erl16
-rw-r--r--lib/compiler/src/compile.erl3
-rw-r--r--lib/compiler/src/compiler.app.src1
-rw-r--r--lib/compiler/src/sys_core_fold.erl94
-rw-r--r--lib/compiler/src/v3_codegen.erl20
-rw-r--r--lib/compiler/src/v3_kernel.erl474
-rw-r--r--lib/compiler/src/v3_kernel.hrl2
-rw-r--r--lib/compiler/src/v3_kernel_pp.erl9
-rw-r--r--lib/compiler/src/v3_life.erl4
-rw-r--r--lib/compiler/test/Makefile17
-rw-r--r--lib/compiler/test/beam_bool_SUITE.erl197
-rw-r--r--lib/compiler/test/bs_match_SUITE.erl33
-rw-r--r--lib/compiler/test/compile_SUITE.erl104
-rw-r--r--lib/compiler/test/core_SUITE.erl20
-rw-r--r--lib/compiler/test/core_SUITE_data/cover_v3_kernel_1.core147
-rw-r--r--lib/compiler/test/core_SUITE_data/cover_v3_kernel_2.core98
-rw-r--r--lib/compiler/test/core_SUITE_data/cover_v3_kernel_3.core98
-rw-r--r--lib/compiler/test/core_SUITE_data/cover_v3_kernel_4.core82
-rw-r--r--lib/compiler/test/core_SUITE_data/cover_v3_kernel_5.core98
-rw-r--r--lib/compiler/test/guard_SUITE.erl153
-rw-r--r--lib/compiler/test/lfe-core.patch97
-rw-r--r--lib/compiler/test/lfe-source.patch117
-rw-r--r--lib/compiler/test/lfe.readme31
-rw-r--r--lib/compiler/test/lfe_andor_SUITE.core2014
-rw-r--r--lib/compiler/test/lfe_guard_SUITE.core3438
-rw-r--r--lib/compiler/test/misc_SUITE.erl8
-rw-r--r--lib/compiler/test/record_SUITE_data/record_access_in_guards.erl63
31 files changed, 7118 insertions, 1150 deletions
diff --git a/lib/compiler/src/Makefile b/lib/compiler/src/Makefile
index b5ca6c3c49..c37f731d8c 100644
--- a/lib/compiler/src/Makefile
+++ b/lib/compiler/src/Makefile
@@ -49,7 +49,6 @@ MODULES = \
beam_a \
beam_asm \
beam_block \
- beam_bool \
beam_bs \
beam_bsm \
beam_clean \
diff --git a/lib/compiler/src/beam_bool.erl b/lib/compiler/src/beam_bool.erl
deleted file mode 100644
index 99e4ccb1e9..0000000000
--- a/lib/compiler/src/beam_bool.erl
+++ /dev/null
@@ -1,765 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-%% Purpose: Optimizes booleans in guards.
-
--module(beam_bool).
-
--export([module/2]).
-
--import(lists, [reverse/1,reverse/2,foldl/3,mapfoldl/3,map/2]).
-
--record(st,
- {next, %Next label number.
- ll %Live regs at labels.
- }).
-
-module({Mod,Exp,Attr,Fs0,Lc}, _Opts) ->
- %%io:format("~p:\n", [Mod]),
- {Fs,_} = mapfoldl(fun(Fn, Lbl) -> function(Fn, Lbl) end, 100000000, Fs0),
- {ok,{Mod,Exp,Attr,Fs,Lc}}.
-
-function({function,Name,Arity,CLabel,Is0}, Lbl0) ->
- try
- {Is,#st{next=Lbl}} = bool_opt(Is0, Lbl0),
- {{function,Name,Arity,CLabel,Is},Lbl}
- catch
- Class:Error ->
- Stack = erlang:get_stacktrace(),
- io:fwrite("Function: ~w/~w\n", [Name,Arity]),
- erlang:raise(Class, Error, Stack)
- end.
-
-%%
-%% Optimize boolean expressions that use guard bifs. Rewrite to
-%% use test instructions if possible.
-%%
-
-bool_opt(Asm, Lbl) ->
- LiveInfo = beam_utils:index_labels(Asm),
- bopt(Asm, [], #st{next=Lbl,ll=LiveInfo}).
-
-bopt([{block,Bl0}=Block|
- [{jump,{f,Succ}},
- {label,Fail},
- {block,[{set,[Dst],[{atom,false}],move}]},
- {label,Succ}|Is]=Is0], Acc0, St) ->
- case split_block(Bl0, Dst, Fail, Acc0, true) of
- failed ->
- bopt(Is0, [Block|Acc0], St);
- {Bl,PreBlock} ->
- Acc1 = case PreBlock of
- [] -> Acc0;
- _ -> [{block,PreBlock}|Acc0]
- end,
- Acc = [{protected,[Dst],Bl,{Fail,Succ}}|Acc1],
- bopt(Is, Acc, St)
- end;
-bopt([{test,is_eq_exact,{f,Fail},[Reg,{atom,true}]}=I|Is], [{block,_}|_]=Acc0, St0) ->
- case bopt_block(Reg, Fail, Is, Acc0, St0) of
- failed -> bopt(Is, [I|Acc0], St0);
- {Acc,St} -> bopt(Is, Acc, St)
- end;
-bopt([I|Is], Acc, St) ->
- bopt(Is, [I|Acc], St);
-bopt([], Acc, St) ->
- {bopt_reverse(Acc, []),St}.
-
-bopt_reverse([{protected,[Dst],Block,{Fail,Succ}}|Is], Acc0) ->
- Acc = [{block,Block},{jump,{f,Succ}},
- {label,Fail},
- {block,[{set,[Dst],[{atom,false}],move}]},
- {label,Succ}|Acc0],
- bopt_reverse(Is, Acc);
-bopt_reverse([I|Is], Acc) ->
- bopt_reverse(Is, [I|Acc]);
-bopt_reverse([], Acc) -> Acc.
-
-%% bopt_block(Reg, Fail, OldIs, Accumulator, St) -> failed | {NewAcc,St}
-%% Attempt to optimized a block of guard BIFs followed by a test
-%% instruction.
-bopt_block(Reg, Fail, OldIs, [{block,Bl0}|Acc0], St0) ->
- case split_block(Bl0, Reg, Fail, Acc0, false) of
- failed ->
- %% Reason for failure: The block either contained no
- %% guard BIFs with the failure label Fail, or the final
- %% instruction in the block did not assign the Reg register.
-
- %%io:format("split ~p: ~P\n", [Reg,Bl0,20]),
- failed;
- {Bl1,BlPre} ->
- %% The block has been splitted. Bl1 is a non-empty list
- %% of guard BIF instructions having the failure label Fail.
- %% BlPre is a (possibly empty list) of instructions preceeding
- %% Bl1.
- Acc1 = make_block(BlPre, Acc0),
- {Bl,Acc} = extend_block(Bl1, Fail, Acc1),
- try
- {NewCode,St} = bopt_tree_cg(Bl, Fail, St0),
- ensure_opt_safe(Bl, NewCode, OldIs, Fail, Acc, St),
- {NewCode++Acc,St}
- catch
- %% Not possible to rewrite because a boolean value is
- %% passed to another guard bif, e.g. 'abs(A > B)'
- %% (in this case, obviously nonsense code). Rare in
- %% practice.
- throw:mixed ->
- failed;
-
- %% There was a reference to a boolean expression
- %% from inside a protected block (try/catch), to
- %% a boolean expression outside.
- throw:protected_barrier ->
- failed;
-
- %% The 'xor' operator was used. We currently don't
- %% find it worthwile to translate 'xor' operators
- %% (the code would be clumsy).
- throw:'xor' ->
- failed;
-
- %% The block does not contain a boolean expression,
- %% but only a call to a guard BIF.
- %% For instance: ... when element(1, T) ->
- throw:not_boolean_expr ->
- failed;
-
- %% The optimization is not safe. (A register
- %% used by the instructions following the
- %% optimized code is either not assigned a
- %% value at all or assigned a different value.)
- throw:all_registers_not_killed ->
- failed;
- throw:registers_used ->
- failed;
-
- %% A protected block refered to the value
- %% returned by another protected block,
- %% probably because the Core Erlang code
- %% used nested try/catches in the guard.
- %% (v3_core never produces nested try/catches
- %% in guards, so it must have been another
- %% Core Erlang translator.)
- throw:protected_violation ->
- failed;
-
- %% Failed to work out the live registers for a GC
- %% BIF. For example, if the number of live registers
- %% needed to be 4 because {x,3} was a source register,
- %% but {x,2} was not known to be initialized, this
- %% exception would be thrown.
- throw:gc_bif_alloc_failure ->
- failed
-
- end
- end.
-
-%% ensure_opt_safe(OriginalCode, OptCode, FollowingCode, Fail,
-%% ReversedPrecedingCode, State) -> ok
-%% Comparing the original code to the optimized code, determine
-%% whether the optimized code is guaranteed to work in the same
-%% way as the original code.
-%%
-%% Throw an exception if the optimization is not safe.
-%%
-ensure_opt_safe(Bl, NewCode, OldIs, Fail, PrecedingCode, St) ->
- %% Here are the conditions that must be true for the
- %% optimization to be safe.
- %%
- %% 1. If a register is INITIALIZED by PrecedingCode,
- %% then if that register assigned a value in the original
- %% code, but not in the optimized code, it must be UNUSED or KILLED
- %% in the code that follows.
- %%
- %% 2. If a register is not known to be INITIALIZED by PreccedingCode,
- %% then if that register assigned a value in the original
- %% code, but not in the optimized code, it must be KILLED
- %% by the code that follows.
- %%
- %% 3. Any register that is assigned a value in the optimized
- %% code must be UNUSED or KILLED in the following code,
- %% unless we can be sure that it is always assigned the same
- %% value.
-
- InitInPreceding = initialized_regs(PrecedingCode),
-
- PrevDst = dst_regs(Bl),
- NewDst = dst_regs(NewCode),
- NotSet = ordsets:subtract(PrevDst, NewDst),
- MustBeKilled = ordsets:subtract(NotSet, InitInPreceding),
-
- case all_killed(MustBeKilled, OldIs, Fail, St) of
- false -> throw(all_registers_not_killed);
- true -> ok
- end,
- MustBeUnused = ordsets:subtract(ordsets:union(NotSet, NewDst),
- MustBeKilled),
- case none_used(MustBeUnused, OldIs, Fail, St) of
- false -> throw(registers_used);
- true -> ok
- end,
- ok.
-
-update_fail_label([{set,Ds,As,{bif,N,{f,_}}}|Is], Fail, Acc) ->
- update_fail_label(Is, Fail, [{set,Ds,As,{bif,N,{f,Fail}}}|Acc]);
-update_fail_label([{set,Ds,As,{alloc,Regs,{gc_bif,N,{f,_}}}}|Is], Fail, Acc) ->
- update_fail_label(Is, Fail,
- [{set,Ds,As,{alloc,Regs,{gc_bif,N,{f,Fail}}}}|Acc]);
-update_fail_label([], _, Acc) -> reverse(Acc).
-
-make_block(Bl) ->
- make_block(Bl, []).
-
-make_block([], Acc) -> Acc;
-make_block(Bl, Acc) -> [{block,Bl}|Acc].
-
-extend_block(BlAcc, Fail, [{protected,_,_,_}=Prot|OldAcc]) ->
- extend_block([Prot|BlAcc], Fail, OldAcc);
-extend_block(BlAcc0, Fail, [{block,Is0}|OldAcc]) ->
- case extend_block_1(reverse(Is0), Fail, BlAcc0) of
- {BlAcc,[]} -> extend_block(BlAcc, Fail, OldAcc);
- {BlAcc,Is} -> {BlAcc,[{block,Is}|OldAcc]}
- end;
-extend_block(BlAcc, _, OldAcc) -> {BlAcc,OldAcc}.
-
-extend_block_1([{set,[{x,_}],_,{bif,_,{f,Fail}}}=I|Is], Fail, Acc) ->
- extend_block_1(Is, Fail, [I|Acc]);
-extend_block_1([{set,[{x,_}],As,{bif,Bif,_}}=I|Is]=Is0, Fail, Acc) ->
- case safe_bool_op(Bif, length(As)) of
- false -> {Acc,reverse(Is0)};
- true -> extend_block_1(Is, Fail, [I|Acc])
- end;
-extend_block_1([_|_]=Is, _, Acc) -> {Acc,reverse(Is)};
-extend_block_1([], _, Acc) -> {Acc,[]}.
-
-%% split_block([Instruction], Destination, FailLabel, [PreInstruction],
-%% ProhibitFailLabelInPreBlock) -> failed | {Block,PreBlock}
-%% Split a sequence of instructions into two blocks - one containing
-%% all guard bif instructions and a pre-block all instructions before
-%% the guard BIFs.
-
-split_block(Is0, Dst, Fail, PreIs, ProhibitFailLabel) ->
- case ProhibitFailLabel andalso beam_jump:is_label_used_in(Fail, PreIs) of
- true ->
- %% The failure label was used in one of the instructions (most
- %% probably bit syntax construction) preceeding the block,
- %% the caller might eliminate the label.
- failed;
- false ->
- case reverse(Is0) of
- [{set,[Dst],_,_}|_]=Is ->
- split_block_1(Is, Fail, ProhibitFailLabel);
- _ -> failed
- end
- end.
-
-split_block_1(Is, Fail, ProhibitFailLabel) ->
- case split_block_2(Is, Fail, []) of
- {[],_} -> failed;
- {_,PreBlock}=Res ->
- case ProhibitFailLabel andalso
- split_block_label_used(PreBlock, Fail) of
- true ->
- %% The failure label was used in the pre-block;
- %% not allowed, because the label may be removed.
- failed;
- false ->
- Res
- end
- end.
-
-split_block_2([{set,[_],_,{bif,_,{f,Fail}}}=I|Is], Fail, Acc) ->
- split_block_2(Is, Fail, [I|Acc]);
-split_block_2([{set,[_],_,{alloc,_,{gc_bif,_,{f,Fail}}}}=I|Is], Fail, Acc) ->
- split_block_2(Is, Fail, [I|Acc]);
-split_block_2(Is0, _, Acc) ->
- Is = reverse(Is0),
- {Acc,Is}.
-
-split_block_label_used([{set,[_],_,{bif,_,{f,Fail}}}|_], Fail) ->
- true;
-split_block_label_used([{set,[_],_,{alloc,_,{gc_bif,_,{f,Fail}}}}|_], Fail) ->
- true;
-split_block_label_used([{set,[_],_,{alloc,_,{put_map,_,{f,Fail}}}}|_], Fail) ->
- true;
-split_block_label_used([_|Is], Fail) ->
- split_block_label_used(Is, Fail);
-split_block_label_used([], _) -> false.
-
-dst_regs(Is) ->
- dst_regs(Is, []).
-
-dst_regs([{block,Bl}|Is], Acc) ->
- dst_regs(Bl, dst_regs(Is, Acc));
-dst_regs([{set,[D],_,{bif,_,{f,_}}}|Is], Acc) ->
- dst_regs(Is, [D|Acc]);
-dst_regs([{set,[D],_,{alloc,_,{gc_bif,_,{f,_}}}}|Is], Acc) ->
- dst_regs(Is, [D|Acc]);
-dst_regs([{protected,_,Bl,_}|Is], Acc) ->
- dst_regs(Bl, dst_regs(Is, Acc));
-dst_regs([_|Is], Acc) ->
- dst_regs(Is, Acc);
-dst_regs([], Acc) -> ordsets:from_list(Acc).
-
-all_killed([R|Rs], OldIs, Fail, St) ->
- case is_killed(R, OldIs, Fail, St) of
- false -> false;
- true -> all_killed(Rs, OldIs, Fail, St)
- end;
-all_killed([], _, _, _) -> true.
-
-none_used([R|Rs], OldIs, Fail, St) ->
- case is_not_used(R, OldIs, Fail, St) of
- false -> false;
- true -> none_used(Rs, OldIs, Fail, St)
- end;
-none_used([], _, _, _) -> true.
-
-bopt_tree_cg(Block0, Fail, St) ->
- Free = free_variables(Block0),
- Block = ssa_block(Block0),
-%% io:format("~p\n", [Block0]),
-%% io:format("~p\n", [Block]),
-%% io:format("~p\n", [gb_trees:to_list(Free)]),
- case bopt_tree(Block, Free, []) of
- {Pre0,[{_,Tree}]} ->
- Pre1 = update_fail_label(Pre0, Fail, []),
- Regs0 = init_regs(gb_trees:keys(Free)),
-%% io:format("~p\n", [dst_regs(Block0)]),
-%% io:format("~p\n", [Pre1]),
-%% io:format("~p\n", [Tree]),
-%% io:nl(),
- {Pre,Regs} = rename_regs(Pre1, Regs0),
-%% io:format("~p\n", [Regs0]),
-%% io:format("~p\n", [Pre]),
- bopt_cg(Tree, Fail, Regs, make_block(Pre), St);
- _Res ->
- throw(not_boolean_expr)
- end.
-
-bopt_tree([{set,[Dst],As0,{bif,'not',_}}|Is], Forest0, Pre) ->
- {[Arg],Forest1} = bopt_bool_args(As0, Forest0),
- Forest = gb_trees:enter(Dst, {'not',Arg}, Forest1),
- bopt_tree(Is, Forest, Pre);
-bopt_tree([{set,[Dst],As0,{bif,'and',_}}|Is], Forest0, Pre) ->
- {As,Forest1} = bopt_bool_args(As0, Forest0),
- Node = make_and_node(As),
- Forest = gb_trees:enter(Dst, Node, Forest1),
- bopt_tree(Is, Forest, Pre);
-bopt_tree([{set,[Dst],As0,{bif,'or',_}}|Is], Forest0, Pre) ->
- {As,Forest1} = bopt_bool_args(As0, Forest0),
- Node = make_or_node(As),
- Forest = gb_trees:enter(Dst, Node, Forest1),
- bopt_tree(Is, Forest, Pre);
-bopt_tree([{set,_,_,{bif,'xor',_}}|_], _, _) ->
- throw('xor');
-bopt_tree([{protected,[Dst],Code,_}|Is], Forest0, Pre) ->
- ProtForest0 = gb_trees:from_orddict([P || {_,any}=P <- gb_trees:to_list(Forest0)]),
- case bopt_tree(Code, ProtForest0, []) of
- {ProtPre,[{_,ProtTree}]} ->
- Prot = {prot,ProtPre,ProtTree},
- Forest = gb_trees:enter(Dst, Prot, Forest0),
- bopt_tree(Is, Forest, Pre);
- _Res ->
- throw(not_boolean_expr)
- end;
-bopt_tree([{set,[Dst],As,{bif,N,_}}=Bif|Is], Forest0, Pre) ->
- Ar = length(As),
- case safe_bool_op(N, Ar) of
- false ->
- bopt_good_args(As, Forest0),
- Forest = gb_trees:enter(Dst, any, Forest0),
- bopt_tree(Is, Forest, [Bif|Pre]);
- true ->
- bopt_good_args(As, Forest0),
- Test = bif_to_test(Dst, N, As),
- Forest = gb_trees:enter(Dst, Test, Forest0),
- bopt_tree(Is, Forest, Pre)
- end;
-bopt_tree([{set,[Dst],As,{alloc,_,{gc_bif,_,_}}}=Bif|Is], Forest0, Pre) ->
- bopt_good_args(As, Forest0),
- Forest = gb_trees:enter(Dst, any, Forest0),
- bopt_tree(Is, Forest, [Bif|Pre]);
-bopt_tree([], Forest, Pre) ->
- {reverse(Pre),[R || {_,V}=R <- gb_trees:to_list(Forest), V =/= any]}.
-
-safe_bool_op(N, Ar) ->
- erl_internal:new_type_test(N, Ar) orelse erl_internal:comp_op(N, Ar).
-
-bopt_bool_args([V0,V0], Forest0) ->
- {V,Forest} = bopt_bool_arg(V0, Forest0),
- {[V,V],Forest};
-bopt_bool_args(As, Forest) ->
- mapfoldl(fun bopt_bool_arg/2, Forest, As).
-
-bopt_bool_arg({T,_}=R, Forest) when T =:= x; T =:= y; T =:= tmp ->
- Val = case gb_trees:lookup(R, Forest) of
- {value,any} -> {test,is_eq_exact,fail,[R,{atom,true}]};
- {value,Val0} -> Val0;
- none -> throw(mixed)
- end,
- {Val,gb_trees:delete(R, Forest)};
-bopt_bool_arg(Term, Forest) ->
- {Term,Forest}.
-
-bopt_good_args([A|As], Regs) ->
- bopt_good_arg(A, Regs),
- bopt_good_args(As, Regs);
-bopt_good_args([], _) -> ok.
-
-bopt_good_arg({Tag,_}=X, Regs) when Tag =:= x; Tag =:= tmp ->
- case gb_trees:lookup(X, Regs) of
- {value,any} -> ok;
- {value,_} -> throw(mixed);
- none -> throw(protected_barrier)
- end;
-bopt_good_arg(_, _) -> ok.
-
-bif_to_test(_, N, As) ->
- beam_utils:bif_to_test(N, As, fail).
-
-make_and_node(Is) ->
- AndList0 = make_and_list(Is),
- case simplify_and_list(AndList0) of
- [] -> {atom,true};
- [Op] -> Op;
- AndList -> {'and',AndList}
- end.
-
-make_and_list([{'and',As}|Is]) ->
- make_and_list(As++Is);
-make_and_list([I|Is]) ->
- [I|make_and_list(Is)];
-make_and_list([]) -> [].
-
-simplify_and_list([{atom,true}|T]) ->
- simplify_and_list(T);
-simplify_and_list([{atom,false}=False|_]) ->
- [False];
-simplify_and_list([H|T]) ->
- [H|simplify_and_list(T)];
-simplify_and_list([]) -> [].
-
-make_or_node(Is) ->
- OrList0 = make_or_list(Is),
- case simplify_or_list(OrList0) of
- [] -> {atom,false};
- [Op] -> Op;
- OrList -> {'or',OrList}
- end.
-
-make_or_list([{'or',As}|Is]) ->
- make_or_list(As++Is);
-make_or_list([I|Is]) ->
- [I|make_or_list(Is)];
-make_or_list([]) -> [].
-
-simplify_or_list([{atom,false}|T]) ->
- simplify_or_list(T);
-simplify_or_list([{atom,true}=True|_]) ->
- [True];
-simplify_or_list([H|T]) ->
- [H|simplify_or_list(T)];
-simplify_or_list([]) -> [].
-
-%% Code generation for a boolean tree.
-
-bopt_cg({'not',Arg}, Fail, Rs, Acc, St) ->
- I = bopt_cg_not(Arg),
- bopt_cg(I, Fail, Rs, Acc, St);
-bopt_cg({'and',As}, Fail, Rs, Acc, St) ->
- bopt_cg_and(As, Fail, Rs, Acc, St);
-bopt_cg({'or',As}, Fail, Rs, Acc, St0) ->
- {Succ,St} = new_label(St0),
- bopt_cg_or(As, Succ, Fail, Rs, Acc, St);
-bopt_cg({test,N,fail,As0}, Fail, Rs, Acc, St) ->
- As = rename_sources(As0, Rs),
- Test = {test,N,{f,Fail},As},
- {[Test|Acc],St};
-bopt_cg({inverted_test,N,fail,As0}, Fail, Rs, Acc, St0) ->
- As = rename_sources(As0, Rs),
- {Lbl,St} = new_label(St0),
- {[{label,Lbl},{jump,{f,Fail}},{test,N,{f,Lbl},As}|Acc],St};
-bopt_cg({prot,Pre0,Tree}, Fail, Rs0, Acc, St0) ->
- Pre1 = update_fail_label(Pre0, Fail, []),
- {Pre,Rs} = rename_regs(Pre1, Rs0),
- bopt_cg(Tree, Fail, Rs, make_block(Pre, Acc), St0);
-bopt_cg({atom,true}, _Fail, _Rs, Acc, St) ->
- {Acc,St};
-bopt_cg({atom,false}, Fail, _Rs, Acc, St) ->
- {[{jump,{f,Fail}}|Acc],St};
-bopt_cg(_, _, _, _, _) ->
- throw(not_boolean_expr).
-
-bopt_cg_not({'and',As0}) ->
- As = [bopt_cg_not(A) || A <- As0],
- {'or',As};
-bopt_cg_not({'or',As0}) ->
- As = [bopt_cg_not(A) || A <- As0],
- {'and',As};
-bopt_cg_not({'not',Arg}) ->
- bopt_cg_not_not(Arg);
-bopt_cg_not({test,Test,Fail,As}) ->
- {inverted_test,Test,Fail,As};
-bopt_cg_not({atom,Bool}) when is_boolean(Bool) ->
- {atom,not Bool};
-bopt_cg_not(_) ->
- throw(not_boolean_expr).
-
-bopt_cg_not_not({'and',As}) ->
- {'and',[bopt_cg_not_not(A) || A <- As]};
-bopt_cg_not_not({'or',As}) ->
- {'or',[bopt_cg_not_not(A) || A <- As]};
-bopt_cg_not_not({'not',Arg}) ->
- bopt_cg_not(Arg);
-bopt_cg_not_not(Leaf) -> Leaf.
-
-bopt_cg_and([I|Is], Fail, Rs, Acc0, St0) ->
- {Acc,St} = bopt_cg(I, Fail, Rs, Acc0, St0),
- bopt_cg_and(Is, Fail, Rs, Acc, St);
-bopt_cg_and([], _, _, Acc, St) -> {Acc,St}.
-
-bopt_cg_or([I], Succ, Fail, Rs, Acc0, St0) ->
- {Acc,St} = bopt_cg(I, Fail, Rs, Acc0, St0),
- {[{label,Succ}|Acc],St};
-bopt_cg_or([I|Is], Succ, Fail, Rs, Acc0, St0) ->
- {Lbl,St1} = new_label(St0),
- {Acc,St} = bopt_cg(I, Lbl, Rs, Acc0, St1),
- bopt_cg_or(Is, Succ, Fail, Rs, [{label,Lbl},{jump,{f,Succ}}|Acc], St).
-
-new_label(#st{next=LabelNum}=St) when is_integer(LabelNum) ->
- {LabelNum,St#st{next=LabelNum+1}}.
-
-free_variables(Is) ->
- E = gb_sets:empty(),
- free_vars_1(Is, E, E, E).
-
-free_vars_1([{set,Ds,As,{bif,_,_}}|Is], F0, N0, A) ->
- F = gb_sets:union(F0, gb_sets:difference(var_list(As), N0)),
- N = gb_sets:union(N0, var_list(Ds)),
- free_vars_1(Is, F, N, A);
-free_vars_1([{set,Ds,As,{alloc,Regs,{gc_bif,_,_}}}|Is], F0, N0, A0) ->
- A = gb_sets:union(A0, gb_sets:from_list(free_vars_regs(Regs))),
- F = gb_sets:union(F0, gb_sets:difference(var_list(As), N0)),
- N = gb_sets:union(N0, var_list(Ds)),
- free_vars_1(Is, F, N, A);
-free_vars_1([{protected,_,Pa,_}|Is], F, N, A) ->
- free_vars_1(Pa++Is, F, N, A);
-free_vars_1([], F0, N, A) ->
- F = case gb_sets:is_empty(A) of
- true ->
- %% No GC BIFs.
- {x,X} = gb_sets:smallest(N),
- P = ordsets:from_list(free_vars_regs(X)),
- ordsets:union(gb_sets:to_list(F0), P);
- false ->
- %% At least one GC BIF.
- gb_sets:to_list(gb_sets:union(F0, gb_sets:difference(A, N)))
- end,
- gb_trees:from_orddict([{K,any} || K <- F]).
-
-var_list(Is) ->
- var_list_1(Is, gb_sets:empty()).
-
-var_list_1([{Tag,_}=X|Is], D) when Tag =:= x; Tag =:= y ->
- var_list_1(Is, gb_sets:add(X, D));
-var_list_1([_|Is], D) ->
- var_list_1(Is, D);
-var_list_1([], D) -> D.
-
-free_vars_regs(0) -> [];
-free_vars_regs(X) -> [{x,X-1}|free_vars_regs(X-1)].
-
-rename_regs(Is, Regs) ->
- rename_regs(Is, Regs, []).
-
-rename_regs([{set,[Dst0],Ss0,{alloc,_,Info}}|Is], Regs0, Acc) ->
- Live = live_regs(Regs0),
- Ss = rename_sources(Ss0, Regs0),
- Regs = put_reg(Dst0, Regs0),
- Dst = fetch_reg(Dst0, Regs),
- rename_regs(Is, Regs, [{set,[Dst],Ss,{alloc,Live,Info}}|Acc]);
-rename_regs([{set,[Dst0],Ss0,Info}|Is], Regs0, Acc) ->
- Ss = rename_sources(Ss0, Regs0),
- Regs = put_reg(Dst0, Regs0),
- Dst = fetch_reg(Dst0, Regs),
- rename_regs(Is, Regs, [{set,[Dst],Ss,Info}|Acc]);
-rename_regs([], Regs, Acc) -> {reverse(Acc),Regs}.
-
-rename_sources(Ss, Regs) ->
- map(fun({x,_}=R) -> fetch_reg(R, Regs);
- ({tmp,_}=R) -> fetch_reg(R, Regs);
- (E) -> E
- end, Ss).
-
-%%%
-%%% Keeping track of register assignments.
-%%%
-
-init_regs(Free) ->
- init_regs_1(Free, 0).
-
-init_regs_1([{x,I}=V|T], I) ->
- [{I,V}|init_regs_1(T, I+1)];
-init_regs_1([{x,X}|_]=T, I) when I < X ->
- [{I,reserved}|init_regs_1(T, I+1)];
-init_regs_1([{y,_}|_], _) -> [];
-init_regs_1([], _) -> [].
-
-put_reg(V, Rs) -> put_reg_1(V, Rs, 0).
-
-put_reg_1(V, [R|Rs], I) -> [R|put_reg_1(V, Rs, I+1)];
-put_reg_1(V, [], I) -> [{I,V}].
-
-fetch_reg(V, [{I,V}|_]) -> {x,I};
-fetch_reg(V, [_|SRs]) -> fetch_reg(V, SRs).
-
-live_regs([{_,reserved}|_]) ->
- %% We are not sure that this register is initialized, so we must
- %% abort the optimization.
- throw(gc_bif_alloc_failure);
-live_regs([{I,_}]) ->
- I+1;
-live_regs([{_,_}|Regs]) ->
- live_regs(Regs);
-live_regs([]) ->
- 0.
-
-
-%%%
-%%% Convert a block to Static Single Assignment (SSA) form.
-%%%
-
--record(ssa,
- {live=0, %Variable counter.
- sub=gb_trees:empty(), %Substitution table.
- prot=gb_sets:empty(), %Targets assigned by protecteds.
- in_prot=false %Inside a protected.
- }).
-
-ssa_block(Is0) ->
- {Is,_} = ssa_block_1(Is0, #ssa{}, []),
- Is.
-
-ssa_block_1([{protected,[_],Pa0,Pb}|Is], Sub0, Acc) ->
- {Pa,Sub1} = ssa_block_1(Pa0, Sub0#ssa{in_prot=true}, []),
- Dst = ssa_last_target(Pa),
- Sub = Sub1#ssa{prot=gb_sets:insert(Dst, Sub1#ssa.prot),
- in_prot=Sub0#ssa.in_prot},
- ssa_block_1(Is, Sub, [{protected,[Dst],Pa,Pb}|Acc]);
-ssa_block_1([{set,[Dst],As,Bif}|Is], Sub0, Acc0) ->
- Sub1 = ssa_in_use_list(As, Sub0),
- Sub = ssa_assign(Dst, Sub1),
- Acc = [{set,[ssa_sub(Dst, Sub)],ssa_sub_list(As, Sub0),Bif}|Acc0],
- ssa_block_1(Is, Sub, Acc);
-ssa_block_1([], Sub, Acc) -> {reverse(Acc),Sub}.
-
-ssa_in_use_list(As, Sub) ->
- foldl(fun ssa_in_use/2, Sub, As).
-
-ssa_in_use({x,_}=R, #ssa{sub=Sub0}=Ssa) ->
- case gb_trees:is_defined(R, Sub0) of
- true -> Ssa;
- false ->
- Sub = gb_trees:insert(R, R, Sub0),
- Ssa#ssa{sub=Sub}
- end;
-ssa_in_use(_, Ssa) -> Ssa.
-
-ssa_assign({x,_}=R, #ssa{sub=Sub0}=Ssa0) ->
- {NewReg,Ssa} = ssa_new_reg(Ssa0),
- case gb_trees:is_defined(R, Sub0) of
- false ->
- Sub = gb_trees:insert(R, NewReg, Sub0),
- Ssa#ssa{sub=Sub};
- true ->
- Sub1 = gb_trees:update(R, NewReg, Sub0),
- Sub = gb_trees:insert(NewReg, NewReg, Sub1),
- Ssa#ssa{sub=Sub}
- end.
-
-ssa_sub_list(List, Sub) ->
- [ssa_sub(E, Sub) || E <- List].
-
-ssa_sub(R0, #ssa{sub=Sub,prot=Prot,in_prot=InProt}) ->
- case gb_trees:lookup(R0, Sub) of
- none -> R0;
- {value,R} ->
- case InProt andalso gb_sets:is_element(R, Prot) of
- true ->
- throw(protected_violation);
- false ->
- R
- end
- end.
-
-ssa_new_reg(#ssa{live=Reg}=Ssa) ->
- {{tmp,Reg},Ssa#ssa{live=Reg+1}}.
-
-ssa_last_target([{set,[Dst],_,_}]) -> Dst;
-ssa_last_target([_|Is]) -> ssa_last_target(Is).
-
-%% is_killed(Register, [Instruction], FailLabel, State) -> true|false
-%% Determine whether a register is killed in the instruction sequence.
-%% The state is used to allow us to determine the kill state
-%% across branches.
-
-is_killed(R, Is, Label, #st{ll=Ll}) ->
- beam_utils:is_killed(R, Is, Ll) andalso
- beam_utils:is_killed_at(R, Label, Ll).
-
-%% is_not_used(Register, [Instruction], FailLabel, State) -> true|false
-%% Determine whether a register is never used in the instruction sequence
-%% (it could still referenced by an allocate instruction, meaning that
-%% it MUST be initialized).
-%% The state is used to allow us to determine the usage state
-%% across branches.
-
-is_not_used(R, Is, Label, #st{ll=Ll}) ->
- beam_utils:is_not_used(R, Is, Ll) andalso
- beam_utils:is_not_used_at(R, Label, Ll).
-
-%% initialized_regs([Instruction]) -> [Register])
-%% Given a REVERSED instruction sequence, return a list of the registers
-%% that are guaranteed to be initialized (not contain garbage).
-
-initialized_regs(Is) ->
- initialized_regs(Is, ordsets:new()).
-
-initialized_regs([{set,Dst,_Src,{alloc,Live,_}}|_], Regs0) ->
- Regs = add_init_regs(free_vars_regs(Live), Regs0),
- add_init_regs(Dst, Regs);
-initialized_regs([{set,Dst,Src,_}|Is], Regs) ->
- initialized_regs(Is, add_init_regs(Dst, add_init_regs(Src, Regs)));
-initialized_regs([{test,_,_,Src}|Is], Regs) ->
- initialized_regs(Is, add_init_regs(Src, Regs));
-initialized_regs([{block,Bl}|Is], Regs) ->
- initialized_regs(reverse(Bl, Is), Regs);
-initialized_regs([{bs_context_to_binary,Src}|Is], Regs) ->
- initialized_regs(Is, add_init_regs([Src], Regs));
-initialized_regs([{label,_},{func_info,_,_,Arity}|_], Regs) ->
- InitRegs = free_vars_regs(Arity),
- add_init_regs(InitRegs, Regs);
-initialized_regs([_|_], Regs) -> Regs.
-
-add_init_regs([{x,_}=X|T], Regs) ->
- add_init_regs(T, ordsets:add_element(X, Regs));
-add_init_regs([_|T], Regs) ->
- add_init_regs(T, Regs);
-add_init_regs([], Regs) -> Regs.
diff --git a/lib/compiler/src/beam_dead.erl b/lib/compiler/src/beam_dead.erl
index 3606af9d75..9087586b58 100644
--- a/lib/compiler/src/beam_dead.erl
+++ b/lib/compiler/src/beam_dead.erl
@@ -266,12 +266,30 @@ backward([{jump,{f,To0}},{move,Src,Reg}=Move|Is], D, Acc) ->
false -> backward([Move|Is], D, [Jump|Acc]);
true -> backward([Jump|Is], D, Acc)
end;
-backward([{jump,{f,To}}=J|[{bif,Op,_,Ops,Reg}|Is]=Is0], D, Acc) ->
+backward([{jump,{f,To}}=J|[{bif,Op,{f,BifFail},Ops,Reg}|Is]=Is0], D, Acc) ->
try replace_comp_op(To, Reg, Op, Ops, D) of
I -> backward(Is, D, I++Acc)
catch
- throw:not_possible -> backward(Is0, D, [J|Acc])
+ throw:not_possible ->
+ case To =:= BifFail of
+ true ->
+ %% The bif instruction is redundant. See the comment
+ %% in the next clause for why there is no need to
+ %% test for liveness of Reg at label To.
+ backward([J|Is], D, Acc);
+ false ->
+ backward(Is0, D, [J|Acc])
+ end
end;
+backward([{jump,{f,To}}=J|[{gc_bif,_,{f,To},_,_,_Dst}|Is]], D, Acc) ->
+ %% The gc_bif instruction is redundant, since either the gc_bif
+ %% instruction itself or the jump instruction will transfer control
+ %% to label To. Note that a gc_bif instruction does not assign its
+ %% destination register if the failure branch is taken; therefore,
+ %% the code at label To is not allowed to assume that the destination
+ %% register is initialized, and it is therefore no need to test
+ %% for liveness of the destination register at label To.
+ backward([J|Is], D, Acc);
backward([{test,bs_start_match2,F,Live,[R,_]=Args,Ctxt}|Is], D,
[{test,bs_match_string,F,[Ctxt,Bs]},
{test,bs_test_tail2,F,[Ctxt,0]}|Acc0]=Acc) ->
@@ -361,6 +379,14 @@ backward([{kill,_}=I|Is], D, [{line,_},Exit|_]=Acc) ->
false -> backward(Is, D, [I|Acc]);
true -> backward(Is, D, Acc)
end;
+backward([{bif,'or',{f,To0},[Dst,{atom,false}],Dst}=I|Is], D,
+ [{test,is_eq_exact,{f,To},[Dst,{atom,true}]}|_]=Acc) ->
+ case shortcut_label(To0, D) of
+ To ->
+ backward(Is, D, Acc);
+ _ ->
+ backward(Is, D, [I|Acc])
+ end;
backward([I|Is], D, Acc) ->
backward(Is, D, [I|Acc]);
backward([], _D, Acc) -> Acc.
@@ -379,6 +405,8 @@ shortcut_select_list([Lit,{f,To0}|T], Reg, D, Acc) ->
shortcut_select_list(T, Reg, D, [{f,To},Lit|Acc]);
shortcut_select_list([], _, _, Acc) -> reverse(Acc).
+shortcut_label(0, _) ->
+ 0;
shortcut_label(To0, D) ->
case beam_utils:code_at(To0, D) of
[{jump,{f,To}}|_] -> shortcut_label(To, D);
diff --git a/lib/compiler/src/beam_jump.erl b/lib/compiler/src/beam_jump.erl
index 5311ce7379..e096270d8c 100644
--- a/lib/compiler/src/beam_jump.erl
+++ b/lib/compiler/src/beam_jump.erl
@@ -23,7 +23,7 @@
-export([module/2,
is_unreachable_after/1,is_exit_instruction/1,
- remove_unused_labels/1,is_label_used_in/2]).
+ remove_unused_labels/1]).
%%% The following optimisations are done:
%%%
@@ -473,36 +473,6 @@ is_exit_instruction({try_case_end,_}) -> true;
is_exit_instruction({badmatch,_}) -> true;
is_exit_instruction(_) -> false.
-%% is_label_used_in(LabelNumber, [Instruction]) -> boolean()
-%% Check whether the label is used in the instruction sequence
-%% (including inside blocks).
-
-is_label_used_in(Lbl, Is) ->
- is_label_used_in_1(Is, Lbl, cerl_sets:new()).
-
-is_label_used_in_1([{block,Block}|Is], Lbl, Empty) ->
- lists:any(fun(I) -> is_label_used_in_block(I, Lbl) end, Block)
- orelse is_label_used_in_1(Is, Lbl, Empty);
-is_label_used_in_1([I|Is], Lbl, Empty) ->
- Used = ulbl(I, Empty),
- cerl_sets:is_element(Lbl, Used) orelse is_label_used_in_1(Is, Lbl, Empty);
-is_label_used_in_1([], _, _) -> false.
-
-is_label_used_in_block({set,_,_,Info}, Lbl) ->
- case Info of
- {bif,_,{f,F}} -> F =:= Lbl;
- {alloc,_,{gc_bif,_,{f,F}}} -> F =:= Lbl;
- {alloc,_,{put_map,_,{f,F}}} -> F =:= Lbl;
- {get_map_elements,{f,F}} -> F =:= Lbl;
- {try_catch,_,{f,F}} -> F =:= Lbl;
- {alloc,_,_} -> false;
- {put_tuple,_} -> false;
- {get_tuple_element,_} -> false;
- {set_tuple_element,_} -> false;
- {line,_} -> false;
- _ when is_atom(Info) -> false
- end.
-
%% remove_unused_labels(Instructions0) -> Instructions
%% Remove all unused labels. Also remove unreachable
%% instructions following labels that are removed.
diff --git a/lib/compiler/src/beam_utils.erl b/lib/compiler/src/beam_utils.erl
index 564a62a7f2..74e3d7e38a 100644
--- a/lib/compiler/src/beam_utils.erl
+++ b/lib/compiler/src/beam_utils.erl
@@ -22,7 +22,7 @@
-module(beam_utils).
-export([is_killed_block/2,is_killed/3,is_killed_at/3,
- is_not_used/3,is_not_used_at/3,
+ is_not_used/3,
empty_label_index/0,index_label/3,index_labels/1,
code_at/2,bif_to_test/3,is_pure_test/1,
live_opt/1,delete_live_annos/1,combine_heap_needs/2,
@@ -96,20 +96,6 @@ is_not_used(R, Is, D) ->
{_,_} -> true
end.
-%% is_not_used(Register, [Instruction], State) -> true|false
-%% Determine whether a register is never used in the instruction sequence
-%% (it could still be referenced by an allocate instruction, meaning that
-%% it MUST be initialized, but that its value does not matter).
-%% The state is used to allow us to determine the usage state
-%% across branches.
-
-is_not_used_at(R, Lbl, D) ->
- St = #live{lbl=D,res=gb_trees:empty()},
- case check_liveness_at(R, Lbl, St) of
- {used,_} -> false;
- {_,_} -> true
- end.
-
%% index_labels(FunctionIs) -> State
%% Index the instruction sequence so that we can quickly
%% look up the instruction following a specific label.
diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl
index e4fb703939..37da045d25 100644
--- a/lib/compiler/src/compile.erl
+++ b/lib/compiler/src/compile.erl
@@ -707,8 +707,6 @@ asm_passes() ->
{iff,dexcept,{listing,"except"}},
{unless,no_bs_opt,{pass,beam_bs}},
{iff,dbs,{listing,"bs"}},
- {unless,no_bopt,{pass,beam_bool}},
- {iff,dbool,{listing,"bool"}},
{unless,no_topt,{pass,beam_type}},
{iff,dtype,{listing,"type"}},
{pass,beam_split},
@@ -1780,7 +1778,6 @@ pre_load() ->
L = [beam_a,
beam_asm,
beam_block,
- beam_bool,
beam_bs,
beam_bsm,
beam_clean,
diff --git a/lib/compiler/src/compiler.app.src b/lib/compiler/src/compiler.app.src
index 20195ac36f..3cb991687b 100644
--- a/lib/compiler/src/compiler.app.src
+++ b/lib/compiler/src/compiler.app.src
@@ -24,7 +24,6 @@
beam_a,
beam_asm,
beam_block,
- beam_bool,
beam_bs,
beam_bsm,
beam_clean,
diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl
index 5d7fd37270..50d28c0a5f 100644
--- a/lib/compiler/src/sys_core_fold.erl
+++ b/lib/compiler/src/sys_core_fold.erl
@@ -373,7 +373,7 @@ expr(#c_case{}=Case0, Ctxt, Sub) ->
%% (in addition to any warnings that may have been emitted
%% according to the rules above).
%%
- case opt_bool_case(Case0) of
+ case opt_bool_case(Case0, Sub) of
#c_case{arg=Arg0,clauses=Cs0}=Case1 ->
Arg1 = body(Arg0, value, Sub),
LitExpr = cerl:is_literal(Arg1),
@@ -1554,9 +1554,11 @@ will_match(E, [P]) ->
will_match_1({false,_}) -> maybe;
will_match_1({true,_}) -> yes.
-%% opt_bool_case(CoreExpr) - CoreExpr'.
-%% Do various optimizations to case statement that has a
-%% boolean case expression.
+%% opt_bool_case(CoreExpr, Sub) - CoreExpr'.
+%%
+%% In bodies, do various optimizations to case statements that have
+%% boolean case expressions. We don't do the optimizations in guards,
+%% because they would thwart the optimization in v3_kernel.
%%
%% We start with some simple optimizations and normalization
%% to facilitate later optimizations.
@@ -1565,7 +1567,7 @@ will_match_1({true,_}) -> yes.
%% (or fail), we can remove any clause that cannot
%% possibly match 'true' or 'false'. Also, any clause
%% following both 'true' and 'false' clause can
-%% be removed. If successful, we will end up this:
+%% be removed. If successful, we will end up like this:
%%
%% case BoolExpr of case BoolExpr of
%% true -> false ->
@@ -1576,8 +1578,11 @@ will_match_1({true,_}) -> yes.
%%
%% We give up if there are clauses with guards, or if there
%% is a variable clause that matches anything.
-%%
-opt_bool_case(#c_case{arg=Arg}=Case0) ->
+
+opt_bool_case(#c_case{}=Case, #sub{in_guard=true}) ->
+ %% v3_kernel does a better job without "help".
+ Case;
+opt_bool_case(#c_case{arg=Arg}=Case0, #sub{in_guard=false}) ->
case is_bool_expr(Arg) of
false ->
Case0;
@@ -1589,8 +1594,7 @@ opt_bool_case(#c_case{arg=Arg}=Case0) ->
impossible ->
Case0
end
- end;
-opt_bool_case(Core) -> Core.
+ end.
opt_bool_clauses(#c_case{clauses=Cs}=Case) ->
Case#c_case{clauses=opt_bool_clauses(Cs, false, false)}.
@@ -1606,16 +1610,14 @@ opt_bool_clauses(Cs, true, true) ->
[]
end;
opt_bool_clauses([#c_clause{pats=[#c_literal{val=Lit}],
- guard=#c_literal{val=true},
- body=B}=C0|Cs], SeenT, SeenF) ->
+ guard=#c_literal{val=true}}=C|Cs], SeenT, SeenF) ->
case is_boolean(Lit) of
false ->
%% Not a boolean - this clause can't match.
- add_warning(C0, nomatch_clause_type),
+ add_warning(C, nomatch_clause_type),
opt_bool_clauses(Cs, SeenT, SeenF);
true ->
%% This clause will match.
- C = C0#c_clause{body=opt_bool_case(B)},
case {Lit,SeenT,SeenF} of
{false,_,false} ->
[C|opt_bool_clauses(Cs, SeenT, true)];
@@ -2238,14 +2240,14 @@ inverse_rel_op(_) -> no.
%% opt_bool_case_in_let(LetExpr) -> Core
-opt_bool_case_in_let(#c_let{vars=Vs,arg=Arg,body=B}=Let) ->
- opt_bool_case_in_let_1(Vs, Arg, B, Let).
+opt_bool_case_in_let(#c_let{vars=Vs,arg=Arg,body=B}=Let, Sub) ->
+ opt_bool_case_in_let_1(Vs, Arg, B, Let, Sub).
opt_bool_case_in_let_1([#c_var{name=V}], Arg,
- #c_case{arg=#c_var{name=V}}=Case0, Let) ->
+ #c_case{arg=#c_var{name=V}}=Case0, Let, Sub) ->
case is_simple_case_arg(Arg) of
true ->
- Case = opt_bool_case(Case0#c_case{arg=Arg}),
+ Case = opt_bool_case(Case0#c_case{arg=Arg}, Sub),
case core_lib:is_var_used(V, Case) of
false -> Case;
true -> Let
@@ -2253,7 +2255,7 @@ opt_bool_case_in_let_1([#c_var{name=V}], Arg,
false ->
Let
end;
-opt_bool_case_in_let_1(_, _, _, Let) -> Let.
+opt_bool_case_in_let_1(_, _, _, Let, _) -> Let.
%% is_simple_case_arg(Expr) -> true|false
%% Determine whether the Expr is simple enough to be worth
@@ -2386,9 +2388,7 @@ is_safe_bool_expr_list([], _, _) -> true.
%% as a let or a sequence, move the original let body into the complex
%% expression.
-simplify_let(#c_let{arg=Arg0}=Let0, Sub) ->
- Arg = opt_bool_case(Arg0),
- Let = Let0#c_let{arg=Arg},
+simplify_let(#c_let{arg=Arg}=Let, Sub) ->
move_let_into_expr(Let, Arg, Sub).
move_let_into_expr(#c_let{vars=InnerVs0,body=InnerBody0}=Inner,
@@ -2688,8 +2688,7 @@ opt_simple_let_2(Let0, Vs0, Arg0, Body, PrevBody, Ctxt, Sub) ->
#c_seq{arg=Arg,body=Body};
true ->
Let1 = Let0#c_let{vars=Vs,arg=Arg1,body=Body},
- Let2 = opt_bool_case_in_let(Let1),
- opt_case_in_let_arg(Let2, Ctxt, Sub)
+ opt_bool_case_in_let(Let1, Sub)
end
end.
@@ -2817,48 +2816,6 @@ move_case_into_arg(#c_case{arg=#c_seq{arg=OuterArg,body=InnerArg}=Outer,
move_case_into_arg(_, _) ->
impossible.
-%% In guards only, rewrite a case in a let argument like
-%%
-%% let <Var> = case <> of
-%% <> when AnyGuard -> Literal1;
-%% <> when AnyGuard -> Literal2
-%% end
-%% in LetBody
-%%
-%% to
-%%
-%% case <> of
-%% <> when AnyGuard ->
-%% let <Var> = Literal1 in LetBody
-%% <> when 'true' ->
-%% let <Var> = Literal2 in LetBody
-%% end
-%%
-%% In the worst case, the size of the code could increase.
-%% In practice, though, substituting the literals into
-%% LetBody and doing constant folding will decrease the code
-%% size. (Doing this transformation outside of guards could
-%% lead to a substantational increase in code size.)
-%%
-opt_case_in_let_arg(#c_let{arg=#c_case{}=Case}=Let, Ctxt,
- #sub{in_guard=true}=Sub) ->
- opt_case_in_let_arg_1(Let, Case, Ctxt, Sub);
-opt_case_in_let_arg(Let, _, _) -> Let.
-
-opt_case_in_let_arg_1(Let0, #c_case{arg=#c_values{es=[]},
- clauses=Cs}=Case0, _Ctxt, _Sub) ->
- Let = mark_compiler_generated(Let0),
- case Cs of
- [#c_clause{body=#c_literal{}=BodyA}=Ca0,
- #c_clause{body=#c_literal{}=BodyB}=Cb0] ->
- Ca = Ca0#c_clause{body=Let#c_let{arg=BodyA}},
- Cb = Cb0#c_clause{body=Let#c_let{arg=BodyB}},
- Case0#c_case{clauses=[Ca,Cb]};
- _ ->
- Let
- end;
-opt_case_in_let_arg_1(Let, _, _, _) -> Let.
-
is_any_var_used([#c_var{name=V}|Vs], Expr) ->
case core_lib:is_var_used(V, Expr) of
false -> is_any_var_used(Vs, Expr);
@@ -3289,13 +3246,6 @@ bsm_problem(Where, What) ->
%%% Handling of warnings.
%%%
-mark_compiler_generated(Term) ->
- cerl_trees:map(fun mark_compiler_generated_1/1, Term).
-
-mark_compiler_generated_1(#c_call{anno=Anno}=Term) ->
- Term#c_call{anno=[compiler_generated|Anno--[compiler_generated]]};
-mark_compiler_generated_1(Term) -> Term.
-
init_warnings() ->
put({?MODULE,warnings}, []).
diff --git a/lib/compiler/src/v3_codegen.erl b/lib/compiler/src/v3_codegen.erl
index c2e0c2bd1a..3627cdb7cd 100644
--- a/lib/compiler/src/v3_codegen.erl
+++ b/lib/compiler/src/v3_codegen.erl
@@ -363,7 +363,7 @@ bsm_rename_ctx(#l{ke={match,Ms0,Rs}}=L, Old, New, InProt) ->
bsm_rename_ctx(#l{ke={guard_match,Ms0,Rs}}=L, Old, New, InProt) ->
Ms = bsm_rename_ctx(Ms0, Old, New, InProt),
L#l{ke={guard_match,Ms,Rs}};
-bsm_rename_ctx(#l{ke={test,_,_}}=L, _, _, _) -> L;
+bsm_rename_ctx(#l{ke={test,_,_,_}}=L, _, _, _) -> L;
bsm_rename_ctx(#l{ke={bif,_,_,_}}=L, _, _, _) -> L;
bsm_rename_ctx(#l{ke={gc_bif,_,_,_}}=L, _, _, _) -> L;
bsm_rename_ctx(#l{ke={set,_,_}}=L, _, _, _) -> L;
@@ -1051,8 +1051,15 @@ guard_cg(#l{ke={protected,Ts,Rs},i=I,vdb=Pdb}, Fail, _Vdb, Bef, St) ->
protected_cg(Ts, Rs, Fail, I, Pdb, Bef, St);
guard_cg(#l{ke={block,Ts},i=I,vdb=Bdb}, Fail, _Vdb, Bef, St) ->
guard_cg_list(Ts, Fail, I, Bdb, Bef, St);
-guard_cg(#l{ke={test,Test,As},i=I,vdb=_Tdb}, Fail, Vdb, Bef, St) ->
- test_cg(Test, As, Fail, I, Vdb, Bef, St);
+guard_cg(#l{ke={test,Test,As,Inverted},i=I,vdb=_Tdb}, Fail, Vdb, Bef, St0) ->
+ case Inverted of
+ false ->
+ test_cg(Test, As, Fail, I, Vdb, Bef, St0);
+ true ->
+ {Psucc,St1} = new_label(St0),
+ {Is,Aft,St2} = test_cg(Test, As, Psucc, I, Vdb, Bef, St1),
+ {Is++[{jump,{f,Fail}},{label,Psucc}],Aft,St2}
+ end;
guard_cg(G, _Fail, Vdb, Bef, St) ->
%%ok = io:fwrite("cg ~w: ~p~n", [?LINE,{G,Fail,Vdb,Bef}]),
{Gis,Aft,St1} = cg(G, Vdb, Bef, St),
@@ -1103,6 +1110,13 @@ test_cg(is_map, [A], Fail, I, Vdb, Bef, St) ->
Arg = cg_reg_arg_prefer_y(A, Bef),
Aft = clear_dead(Bef, I, Vdb),
{[{test,is_map,{f,Fail},[Arg]}],Aft,St};
+test_cg(is_boolean, [{atom,Val}], Fail, I, Vdb, Bef, St) ->
+ Aft = clear_dead(Bef, I, Vdb),
+ Is = case is_boolean(Val) of
+ true -> [];
+ false -> [{jump,{f,Fail}}]
+ end,
+ {Is,Aft,St};
test_cg(Test, As, Fail, I, Vdb, Bef, St) ->
Args = cg_reg_args(As, Bef),
Aft = clear_dead(Bef, I, Vdb),
diff --git a/lib/compiler/src/v3_kernel.erl b/lib/compiler/src/v3_kernel.erl
index f8e99905b5..2bfa610628 100644
--- a/lib/compiler/src/v3_kernel.erl
+++ b/lib/compiler/src/v3_kernel.erl
@@ -82,7 +82,7 @@
-export([module/2,format_error/1]).
-import(lists, [map/2,foldl/3,foldr/3,mapfoldl/3,splitwith/2,member/2,
- keymember/3,keyfind/3,partition/2,droplast/1,last/1]).
+ keymember/3,keyfind/3,partition/2,droplast/1,last/1,sort/1]).
-import(ordsets, [add_element/2,del_element/2,union/2,union/1,subtract/2]).
-import(cerl, [c_tuple/1]).
@@ -190,9 +190,479 @@ body(Ce, Sub, St0) ->
guard(G0, Sub, St0) ->
{G1,St1} = wrap_guard(G0, St0),
{Ge0,Pre,St2} = expr(G1, Sub, St1),
- {Ge,St} = gexpr_test(Ge0, St2),
+ {Ge1,St3} = gexpr_test(Ge0, St2),
+ {Ge,St} = guard_opt(Ge1, St3),
{pre_seq(Pre, Ge),St}.
+%% guard_opt(Kexpr, State) -> {Kexpr,State}.
+%% Optimize the Kexpr for the guard. Instead of evaluating a boolean
+%% expression comparing it to 'true' in a final #k_test{},
+%% replace BIF calls with #k_test{} in the expression.
+%%
+%% As an example, take the guard:
+%%
+%% when is_integer(V0), is_atom(V1) ->
+%%
+%% The unoptimized Kexpr translated to pseudo BEAM assembly
+%% code would look like:
+%%
+%% bif is_integer V0 => Bool0
+%% bif is_atom V1 => Bool1
+%% bif and Bool0 Bool1 => Bool
+%% test Bool =:= true else goto Fail
+%% ...
+%% Fail:
+%% ...
+%%
+%% The optimized code would look like:
+%%
+%% test is_integer V0 else goto Fail
+%% test is_atom V1 else goto Fail
+%% ...
+%% Fail:
+%% ...
+%%
+%% An 'or' operation is only slightly more complicated:
+%%
+%% test is_integer V0 else goto NotFailedYet
+%% goto Success
+%%
+%% NotFailedYet:
+%% test is_atom V1 else goto Fail
+%%
+%% Success:
+%% ...
+%% Fail:
+%% ...
+
+guard_opt(G, St0) ->
+ {Root,Forest0,St1} = make_forest(G, St0),
+ {Exprs,Forest,St} = rewrite_bool(Root, Forest0, false, St1),
+ E = forest_pre_seq(Exprs, Forest),
+ {G#k_try{arg=E},St}.
+
+%% rewrite_bool(Kexpr, Forest, Inv, St) -> {[Kexpr],Forest,St}.
+%% Rewrite Kexpr to use #k_test{} operations instead of comparison
+%% and type test BIFs.
+%%
+%% If Kexpr is a #k_test{} operation, the call will always
+%% succeed. Otherwise, a 'not_possible' exception will be
+%% thrown if Kexpr cannot be rewritten.
+
+rewrite_bool(#k_test{op=#k_remote{mod=#k_atom{val=erlang},name=#k_atom{val='=:='}},
+ args=[#k_var{}=V,#k_atom{val=true}]}=Test, Forest0, Inv, St0) ->
+ try rewrite_bool_var(V, Forest0, Inv, St0) of
+ {_,_,_}=Res ->
+ Res
+ catch
+ throw:not_possible ->
+ {[Test],Forest0,St0}
+ end;
+rewrite_bool(#k_test{op=#k_remote{mod=#k_atom{val=erlang},name=#k_atom{val='=:='}},
+ args=[#k_var{}=V,#k_atom{val=false}]}=Test, Forest0, Inv, St0) ->
+ try rewrite_bool_var(V, Forest0, not Inv, St0) of
+ {_,_,_}=Res ->
+ Res
+ catch
+ throw:not_possible ->
+ {[Test],Forest0,St0}
+ end;
+rewrite_bool(#k_test{op=#k_remote{mod=#k_atom{val=erlang},name=#k_atom{val='=:='}},
+ args=[#k_atom{val=V1},#k_atom{val=V2}]}, Forest0, false, St0) ->
+ case V1 =:= V2 of
+ true ->
+ {[make_test(is_boolean, [#k_atom{val=true}])],Forest0,St0};
+ false ->
+ {[make_failing_test()],Forest0,St0}
+ end;
+rewrite_bool(#k_test{}=Test, Forest, false, St) ->
+ {[Test],Forest,St};
+rewrite_bool(#k_try{vars=[#k_var{name=X}],body=#k_var{name=X},
+ handler=#k_atom{val=false},ret=[]}=Prot,
+ Forest0, Inv, St0) ->
+ {Root,Forest1,St1} = make_forest(Prot, Forest0, St0),
+ {Exprs,Forest2,St} = rewrite_bool(Root, Forest1, Inv, St1),
+ InnerForest = maps:without(maps:keys(Forest0), Forest2),
+ Forest = maps:without(maps:keys(InnerForest), Forest2),
+ E = forest_pre_seq(Exprs, InnerForest),
+ {[Prot#k_try{arg=E}],Forest,St};
+rewrite_bool(#k_match{body=Body,ret=[]}, Forest, Inv, St) ->
+ rewrite_match(Body, Forest, Inv, St);
+rewrite_bool(Other, Forest, Inv, St) ->
+ case extract_bif(Other) of
+ {Name,Args} ->
+ rewrite_bif(Name, Args, Forest, Inv, St);
+ error ->
+ throw(not_possible)
+ end.
+
+%% rewrite_bool_var(Var, Forest, Inv, St) -> {[Kexpr],Forest,St}.
+%% Rewrite the boolean expression whose key in Forest is
+%% given by Var. Throw a 'not_possible' expression if something
+%% prevents the rewriting.
+
+rewrite_bool_var(Arg, Forest0, Inv, St) ->
+ {Expr,Forest} = forest_take_expr(Arg, Forest0),
+ rewrite_bool(Expr, Forest, Inv, St).
+
+%% rewrite_bool_args([Kexpr], Forest, Inv, St) -> {[[Kexpr]],Forest,St}.
+%% Rewrite each Kexpr in the list. The input Kexpr should be variables
+%% or boolean values. Throw a 'not_possible' expression if something
+%% prevents the rewriting.
+%%
+%% This function is suitable for handling the arguments for both
+%% 'and' and 'or'.
+
+rewrite_bool_args([#k_atom{val=B}=A|Vs], Forest0, false=Inv, St0) when is_boolean(B) ->
+ {Tail,Forest1,St1} = rewrite_bool_args(Vs, Forest0, Inv, St0),
+ Bif = make_bif('=:=', [A,#k_atom{val=true}]),
+ {Exprs,Forest,St} = rewrite_bool(Bif, Forest1, Inv, St1),
+ {[Exprs|Tail],Forest,St};
+rewrite_bool_args([#k_var{}=Var|Vs], Forest0, false=Inv, St0) ->
+ {Tail,Forest1,St1} = rewrite_bool_args(Vs, Forest0, Inv, St0),
+ {Exprs,Forest,St} =
+ case is_bool_expr(Var, Forest0) of
+ true ->
+ rewrite_bool_var(Var, Forest1, Inv, St1);
+ false ->
+ Bif = make_bif('=:=', [Var,#k_atom{val=true}]),
+ rewrite_bool(Bif, Forest1, Inv, St1)
+ end,
+ {[Exprs|Tail],Forest,St};
+rewrite_bool_args([_|_], _Forest, _Inv, _St) ->
+ throw(not_possible);
+rewrite_bool_args([], Forest, _Inv, St) ->
+ {[],Forest,St}.
+
+%% rewrite_bif(Name, [Kexpr], Forest, Inv, St) -> {[Kexpr],Forest,St}.
+%% Rewrite a BIF. Throw a 'not_possible' expression if something
+%% prevents the rewriting.
+
+rewrite_bif('or', Args, Forest, true, St) ->
+ rewrite_not_args('and', Args, Forest, St);
+rewrite_bif('and', Args, Forest, true, St) ->
+ rewrite_not_args('or', Args, Forest, St);
+rewrite_bif('and', [#k_atom{val=Val},Arg], Forest0, Inv, St0) ->
+ false = Inv, %Assertion.
+ case Val of
+ true ->
+ %% The result only depends on Arg.
+ rewrite_bool_var(Arg, Forest0, Inv, St0);
+ _ ->
+ %% Will fail. There is no need to evalute the expression
+ %% represented by Arg. Take it out from the forest and
+ %% discard the expression.
+ Failing = make_failing_test(),
+ try rewrite_bool_var(Arg, Forest0, Inv, St0) of
+ {_,Forest,St} ->
+ {[Failing],Forest,St}
+ catch
+ throw:not_possible ->
+ try forest_take_expr(Arg, Forest0) of
+ {_,Forest} ->
+ {[Failing],Forest,St0}
+ catch
+ throw:not_possible ->
+ %% Arg is probably a variable bound in an
+ %% outer scope.
+ {[Failing],Forest0,St0}
+ end
+ end
+ end;
+rewrite_bif('and', [Arg,#k_atom{}=Atom], Forest, Inv, St) ->
+ false = Inv, %Assertion.
+ rewrite_bif('and', [Atom,Arg], Forest, Inv, St);
+rewrite_bif('and', Args, Forest0, Inv, St0) ->
+ false = Inv, %Assertion.
+ {[Es1,Es2],Forest,St} = rewrite_bool_args(Args, Forest0, Inv, St0),
+ {Es1 ++ Es2,Forest,St};
+rewrite_bif('or', Args, Forest0, Inv, St0) ->
+ false = Inv, %Assertion.
+ {[First,Then],Forest,St} = rewrite_bool_args(Args, Forest0, Inv, St0),
+ Alt = make_alt(First, Then),
+ {[Alt],Forest,St};
+rewrite_bif('xor', [_,_], _Forest, _Inv, _St) ->
+ %% Rewriting 'xor' is not practical. Fortunately, 'xor' is
+ %% almost never used in practice.
+ throw(not_possible);
+rewrite_bif('not', [Arg], Forest0, Inv, St) ->
+ {Expr,Forest} = forest_take_expr(Arg, Forest0),
+ rewrite_bool(Expr, Forest, not Inv, St);
+rewrite_bif(Op, Args, Forest, Inv, St) ->
+ case is_test(Op, Args) of
+ true ->
+ rewrite_bool(make_test(Op, Args, Inv), Forest, false, St);
+ false ->
+ throw(not_possible)
+ end.
+
+rewrite_not_args(Op, [A0,B0], Forest0, St0) ->
+ {A,Forest1,St1} = rewrite_not_args_1(A0, Forest0, St0),
+ {B,Forest2,St2} = rewrite_not_args_1(B0, Forest1, St1),
+ rewrite_bif(Op, [A,B], Forest2, false, St2).
+
+rewrite_not_args_1(Arg, Forest, St) ->
+ Not = make_bif('not', [Arg]),
+ forest_add_expr(Not, Forest, St).
+
+%% rewrite_match(Kvar, TypeClause, Forest, Inv, St) ->
+%% {[Kexpr],Forest,St}.
+%% Try to rewrite a #k_match{} originating from an 'andalso' or an 'orelse'.
+
+rewrite_match(#k_alt{first=First,then=Then}, Forest, Inv, St) ->
+ case {First,Then} of
+ {#k_select{var=#k_var{name=V}=Var,types=[TypeClause]},#k_var{name=V}} ->
+ rewrite_match_1(Var, TypeClause, Forest, Inv, St);
+ {_,_} ->
+ throw(not_possible)
+ end.
+
+rewrite_match_1(Var, #k_type_clause{values=Cs0}, Forest0, Inv, St0) ->
+ Cs = sort([{Val,B} || #k_val_clause{val=#k_atom{val=Val},body=B} <- Cs0]),
+ case Cs of
+ [{false,False},{true,True}] ->
+ rewrite_match_2(Var, False, True, Forest0, Inv, St0);
+ _ ->
+ throw(not_possible)
+ end.
+
+rewrite_match_2(Var, False, #k_atom{val=true}, Forest0, Inv, St0) ->
+ %% Originates from an 'orelse'.
+ case False of
+ #k_atom{val=NotBool} when not is_boolean(NotBool) ->
+ rewrite_bool(Var, Forest0, Inv, St0);
+ _ ->
+ {CodeVar,Forest1,St1} = add_protected_expr(False, Forest0, St0),
+ rewrite_bif('or', [Var,CodeVar], Forest1, Inv, St1)
+ end;
+rewrite_match_2(Var, #k_atom{val=false}, True, Forest0, Inv, St0) ->
+ %% Originates from an 'andalso'.
+ {CodeVar,Forest1,St1} = add_protected_expr(True, Forest0, St0),
+ rewrite_bif('and', [Var,CodeVar], Forest1, Inv, St1);
+rewrite_match_2(_V, _, _, _Forest, _Inv, _St) ->
+ throw(not_possible).
+
+%% is_bool_expr(#k_var{}, Forest) -> true|false.
+%% Return true if the variable refers to a boolean expression
+%% that does not need an explicit '=:= true' test.
+
+is_bool_expr(V, Forest) ->
+ case forest_peek_expr(V, Forest) of
+ error ->
+ %% Defined outside of the guard. We can't know.
+ false;
+ Expr ->
+ case extract_bif(Expr) of
+ {Name,Args} ->
+ is_test(Name, Args) orelse
+ erl_internal:bool_op(Name, length(Args));
+ error ->
+ %% Not a BIF. Should be possible to rewrite
+ %% to a boolean. Definitely does not need
+ %% a '=:= true' test.
+ true
+ end
+ end.
+
+make_bif(Op, Args) ->
+ #k_bif{op=#k_remote{mod=#k_atom{val=erlang},
+ name=#k_atom{val=Op},
+ arity=length(Args)},
+ args=Args}.
+
+extract_bif(#k_bif{op=#k_remote{mod=#k_atom{val=erlang},
+ name=#k_atom{val=Name}},
+ args=Args}) ->
+ {Name,Args};
+extract_bif(_) ->
+ error.
+
+%% make_alt(First, Then) -> KMatch.
+%% Make a #k_alt{} within a #k_match{} to implement
+%% 'or' or 'orelse'.
+
+make_alt(First0, Then0) ->
+ First1 = pre_seq(droplast(First0), last(First0)),
+ Then1 = pre_seq(droplast(Then0), last(Then0)),
+ First2 = make_protected(First1),
+ Then2 = make_protected(Then1),
+ Body = #k_atom{val=ignored},
+ First3 = #k_guard_clause{guard=First2,body=Body},
+ Then3 = #k_guard_clause{guard=Then2,body=Body},
+ First = #k_guard{clauses=[First3]},
+ Then = #k_guard{clauses=[Then3]},
+ Alt = #k_alt{first=First,then=Then},
+ #k_match{vars=[],body=Alt}.
+
+add_protected_expr(#k_atom{}=Atom, Forest, St) ->
+ {Atom,Forest,St};
+add_protected_expr(#k_var{}=Var, Forest, St) ->
+ {Var,Forest,St};
+add_protected_expr(E0, Forest, St) ->
+ E = make_protected(E0),
+ forest_add_expr(E, Forest, St).
+
+make_protected(#k_try{}=Try) ->
+ Try;
+make_protected(B) ->
+ #k_try{arg=B,vars=[#k_var{name=''}],body=#k_var{name=''},
+ handler=#k_atom{val=false}}.
+
+make_failing_test() ->
+ make_test(is_boolean, [#k_atom{val=fail}]).
+
+make_test(Op, Args) ->
+ make_test(Op, Args, false).
+
+make_test(Op, Args, Inv) ->
+ Remote = #k_remote{mod=#k_atom{val=erlang},
+ name=#k_atom{val=Op},
+ arity=length(Args)},
+ #k_test{op=Remote,args=Args,inverted=Inv}.
+
+is_test(Op, Args) ->
+ A = length(Args),
+ erl_internal:new_type_test(Op, A) orelse erl_internal:comp_op(Op, A).
+
+%% make_forest(Kexpr, St) -> {RootKexpr,Forest,St}.
+%% Build a forest out of Kexpr. RootKexpr is the final expression
+%% nested inside Kexpr.
+
+make_forest(G, St) ->
+ make_forest_1(G, #{}, 0, St).
+
+%% make_forest(Kexpr, St) -> {RootKexpr,Forest,St}.
+%% Add to Forest from Kexpr. RootKexpr is the final expression
+%% nested inside Kexpr.
+
+make_forest(G, Forest0, St) ->
+ N = forest_next_index(Forest0),
+ make_forest_1(G, Forest0, N, St).
+
+make_forest_1(#k_try{arg=B}, Forest, I, St) ->
+ make_forest_1(B, Forest, I, St);
+make_forest_1(#iset{vars=[]}=Iset0, Forest, I, St0) ->
+ {UnrefVar,St} = new_var(St0),
+ Iset = Iset0#iset{vars=[UnrefVar]},
+ make_forest_1(Iset, Forest, I, St);
+make_forest_1(#iset{vars=[#k_var{name=V}],arg=Arg,body=B}, Forest0, I, St) ->
+ Forest = Forest0#{V => {I,Arg}, {untaken,V} => true},
+ make_forest_1(B, Forest, I+1, St);
+make_forest_1(Innermost, Forest, _I, St) ->
+ {Innermost,Forest,St}.
+
+%% forest_take_expr(Kexpr, Forest) -> {Expr,Forest}.
+%% If Kexpr is a variable, take out the expression corresponding
+%% to variable in Forest. Expressions that have been taken out
+%% of the forest will not be included the Kexpr returned
+%% by forest_pre_seq/2.
+%%
+%% Throw a 'not_possible' exception if Kexpr is not a variable or
+%% if the name of the variable is not a key in Forest.
+
+forest_take_expr(#k_var{name=V}, Forest0) ->
+ %% v3_core currently always generates guard expressions that can
+ %% be represented as a tree. Other code generators (such as LFE)
+ %% could generate guard expressions that can only be represented
+ %% as a DAG (i.e. some nodes are referenced more than once). To
+ %% handle DAGs, we must never remove a node from the forest, but
+ %% just remove the {untaken,V} marker. That will effectively convert
+ %% the DAG to a tree by duplicating the shared nodes and their
+ %% descendants.
+
+ case maps:find(V, Forest0) of
+ {ok,{_,Expr}} ->
+ Forest = maps:remove({untaken,V}, Forest0),
+ {Expr,Forest};
+ error ->
+ throw(not_possible)
+ end;
+forest_take_expr(_, _) ->
+ throw(not_possible).
+
+%% forest_peek_expr(Kvar, Forest) -> Kexpr | error.
+%% Return the expression corresponding to Kvar in Forest or
+%% return 'error' if there is a corresponding expression.
+
+forest_peek_expr(#k_var{name=V}, Forest0) ->
+ case maps:find(V, Forest0) of
+ {ok,{_,Expr}} -> Expr;
+ error -> error
+ end.
+
+%% forest_add_expr(Kexpr, Forest, St) -> {Kvar,Forest,St}.
+%% Add a new expression to Forest.
+
+forest_add_expr(Expr, Forest0, St0) ->
+ {#k_var{name=V}=Var,St} = new_var(St0),
+ N = forest_next_index(Forest0),
+ Forest = Forest0#{V => {N,Expr}},
+ {Var,Forest,St}.
+
+forest_next_index(Forest) ->
+ 1 + lists:max([N || {N,_} <- maps:values(Forest),
+ is_integer(N)] ++ [0]).
+
+%% forest_pre_seq([Kexpr], Forest) -> Kexpr.
+%% Package the list of Kexprs into a nested Kexpr, prepending all
+%% expressions in Forest that have not been taken out using
+%% forest_take_expr/2.
+
+forest_pre_seq(Exprs, Forest) ->
+ Es0 = [#k_var{name=V} || {untaken,V} <- maps:keys(Forest)],
+ Es = Es0 ++ Exprs,
+ Vs = extract_all_vars(Es, Forest, []),
+ Pre0 = sort([{maps:get(V, Forest),V} || V <- Vs]),
+ Pre = [#iset{vars=[#k_var{name=V}],arg=A} ||
+ {{_,A},V} <- Pre0],
+ pre_seq(Pre++droplast(Exprs), last(Exprs)).
+
+extract_all_vars(Es, Forest, Acc0) ->
+ case extract_var_list(Es) of
+ [] ->
+ Acc0;
+ [_|_]=Vs0 ->
+ Vs = [V || V <- Vs0, maps:is_key(V, Forest)],
+ NewVs = ordsets:subtract(Vs, Acc0),
+ NewEs = [begin
+ {_,E} = maps:get(V, Forest),
+ E
+ end || V <- NewVs],
+ Acc = union(NewVs, Acc0),
+ extract_all_vars(NewEs, Forest, Acc)
+ end.
+
+extract_vars(#iset{arg=A,body=B}) ->
+ union(extract_vars(A), extract_vars(B));
+extract_vars(#k_bif{args=Args}) ->
+ ordsets:from_list(lit_list_vars(Args));
+extract_vars(#k_call{}) ->
+ [];
+extract_vars(#k_test{args=Args}) ->
+ ordsets:from_list(lit_list_vars(Args));
+extract_vars(#k_match{body=Body}) ->
+ extract_vars(Body);
+extract_vars(#k_alt{first=First,then=Then}) ->
+ union(extract_vars(First), extract_vars(Then));
+extract_vars(#k_guard{clauses=Cs}) ->
+ extract_var_list(Cs);
+extract_vars(#k_guard_clause{guard=G}) ->
+ extract_vars(G);
+extract_vars(#k_select{var=Var,types=Types}) ->
+ union(ordsets:from_list(lit_vars(Var)),
+ extract_var_list(Types));
+extract_vars(#k_type_clause{values=Values}) ->
+ extract_var_list(Values);
+extract_vars(#k_val_clause{body=Body}) ->
+ extract_vars(Body);
+extract_vars(#k_try{arg=Arg}) ->
+ extract_vars(Arg);
+extract_vars(Lit) ->
+ ordsets:from_list(lit_vars(Lit)).
+
+extract_var_list(L) ->
+ union([extract_vars(E) || E <- L]).
+
%% Wrap the entire guard in a try/catch if needed.
wrap_guard(#c_try{}=Try, St) -> {Try,St};
diff --git a/lib/compiler/src/v3_kernel.hrl b/lib/compiler/src/v3_kernel.hrl
index 1169a69117..7cd30b25a8 100644
--- a/lib/compiler/src/v3_kernel.hrl
+++ b/lib/compiler/src/v3_kernel.hrl
@@ -58,7 +58,7 @@
-record(k_seq, {anno=[],arg,body}).
-record(k_put, {anno=[],arg,ret=[]}).
-record(k_bif, {anno=[],op,args,ret=[]}).
--record(k_test, {anno=[],op,args}).
+-record(k_test, {anno=[],op,args,inverted=false}).
-record(k_call, {anno=[],op,args,ret=[]}).
-record(k_enter, {anno=[],op,args}).
-record(k_receive, {anno=[],var,body,timeout,action,ret=[]}).
diff --git a/lib/compiler/src/v3_kernel_pp.erl b/lib/compiler/src/v3_kernel_pp.erl
index 45065b7e11..d5f6ee19c9 100644
--- a/lib/compiler/src/v3_kernel_pp.erl
+++ b/lib/compiler/src/v3_kernel_pp.erl
@@ -235,8 +235,13 @@ format_1(#k_bif{op=Op,args=As,ret=Rs}, Ctxt) ->
[Txt,format_args(As, Ctxt1),
format_ret(Rs, Ctxt1)
];
-format_1(#k_test{op=Op,args=As}, Ctxt) ->
- Txt = ["test (",format(Op, ctxt_bump_indent(Ctxt, 6)),$)],
+format_1(#k_test{op=Op,args=As,inverted=Inverted}, Ctxt) ->
+ Txt = case Inverted of
+ false ->
+ ["test (",format(Op, ctxt_bump_indent(Ctxt, 6)),$)];
+ true ->
+ ["inverted_test (",format(Op, ctxt_bump_indent(Ctxt, 6)),$)]
+ end,
Ctxt1 = ctxt_bump_indent(Ctxt, 2),
[Txt,format_args(As, Ctxt1)];
format_1(#k_put{arg=A,ret=Rs}, Ctxt) ->
diff --git a/lib/compiler/src/v3_life.erl b/lib/compiler/src/v3_life.erl
index 4337ec732c..0f2aeda87f 100644
--- a/lib/compiler/src/v3_life.erl
+++ b/lib/compiler/src/v3_life.erl
@@ -118,8 +118,8 @@ protected(#k_protected{anno=A,arg=Ts,ret=Rs}, I, Vdb) ->
%% expr(Kexpr, I, Vdb) -> Expr.
-expr(#k_test{anno=A,op=Op,args=As}, I, _Vdb) ->
- #l{ke={test,test_op(Op),atomic_list(As)},i=I,a=A#k.a};
+expr(#k_test{anno=A,op=Op,args=As,inverted=Inverted}, I, _Vdb) ->
+ #l{ke={test,test_op(Op),atomic_list(As),Inverted},i=I,a=A#k.a};
expr(#k_call{anno=A,op=Op,args=As,ret=Rs}, I, _Vdb) ->
#l{ke={call,call_op(Op),atomic_list(As),var_list(Rs)},i=I,a=A#k.a};
expr(#k_enter{anno=A,op=Op,args=As}, I, _Vdb) ->
diff --git a/lib/compiler/test/Makefile b/lib/compiler/test/Makefile
index de06e8760f..e338dbb4e3 100644
--- a/lib/compiler/test/Makefile
+++ b/lib/compiler/test/Makefile
@@ -9,7 +9,6 @@ MODULES= \
andor_SUITE \
apply_SUITE \
beam_block_SUITE \
- beam_bool_SUITE \
beam_validator_SUITE \
beam_disasm_SUITE \
beam_except_SUITE \
@@ -49,7 +48,6 @@ NO_OPT= \
andor \
apply \
beam_block \
- beam_bool \
beam_except \
beam_jump \
beam_reorder \
@@ -76,7 +74,6 @@ INLINE= \
andor \
apply \
beam_block \
- beam_bool \
beam_utils \
bif \
bs_bincomp \
@@ -96,6 +93,10 @@ INLINE= \
receive \
record
+CORE_MODULES = \
+ lfe_andor_SUITE \
+ lfe_guard_SUITE
+
NO_OPT_MODULES= $(NO_OPT:%=%_no_opt_SUITE)
NO_OPT_ERL_FILES= $(NO_OPT_MODULES:%=%.erl)
POST_OPT_MODULES= $(NO_OPT:%=%_post_opt_SUITE)
@@ -104,6 +105,8 @@ INLINE_MODULES= $(INLINE:%=%_inline_SUITE)
INLINE_ERL_FILES= $(INLINE_MODULES:%=%.erl)
ERL_FILES= $(MODULES:%=%.erl)
+CORE_FILES= $(CORE_MODULES:%=%.core)
+ERL_DUMMY_FILES= $(CORE_MODULES:%=%.erl)
##TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
##INSTALL_PROGS= $(TARGET_FILES)
@@ -137,6 +140,8 @@ make_emakefile: $(NO_OPT_ERL_FILES) $(POST_OPT_ERL_FILES) $(INLINE_ERL_FILES)
-o$(EBIN) $(POST_OPT_MODULES) >> $(EMAKEFILE)
$(ERL_TOP)/make/make_emakefile +inline $(ERL_COMPILE_FLAGS) \
-o$(EBIN) $(INLINE_MODULES) >> $(EMAKEFILE)
+ $(ERL_TOP)/make/make_emakefile +from_core $(ERL_COMPILE_FLAGS) \
+ -o$(EBIN) $(CORE_MODULES) >> $(EMAKEFILE)
tests debug opt: make_emakefile
erl $(ERL_MAKE_FLAGS) -make
@@ -174,6 +179,12 @@ release_tests_spec: make_emakefile
$(EMAKEFILE) $(ERL_FILES) "$(RELSYSDIR)"
$(INSTALL_DATA) $(NO_OPT_ERL_FILES) $(POST_OPT_ERL_FILES) \
$(INLINE_ERL_FILES) "$(RELSYSDIR)"
+ $(INSTALL_DATA) $(CORE_FILES) "$(RELSYSDIR)"
+ for file in $(ERL_DUMMY_FILES); do \
+ module=`basename $$file .erl`; \
+ echo "-module($$module). %% dummy .erl file" >$$file; \
+ done
+ $(INSTALL_DATA) $(ERL_DUMMY_FILES) "$(RELSYSDIR)"
chmod -R u+w "$(RELSYSDIR)"
@tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -)
diff --git a/lib/compiler/test/beam_bool_SUITE.erl b/lib/compiler/test/beam_bool_SUITE.erl
deleted file mode 100644
index e585eaedb5..0000000000
--- a/lib/compiler/test/beam_bool_SUITE.erl
+++ /dev/null
@@ -1,197 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2015-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
--module(beam_bool_SUITE).
-
--export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1,
- init_per_group/2,end_per_group/2,
- before_and_inside_if/1,
- scotland/1,y_registers/1,protected/1,
- maps/1]).
-
-suite() ->
- [{ct_hooks,[ts_install_cth]}].
-
-all() ->
- test_lib:recompile(?MODULE),
- [{group,p}].
-
-groups() ->
- [{p,[parallel],
- [before_and_inside_if,
- scotland,
- y_registers,
- protected,
- maps
- ]}].
-
-init_per_suite(Config) ->
- Config.
-
-end_per_suite(_Config) ->
- ok.
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-before_and_inside_if(_Config) ->
- no = before_and_inside_if([a], [b], delete),
- no = before_and_inside_if([a], [b], x),
- no = before_and_inside_if([a], [], delete),
- no = before_and_inside_if([a], [], x),
- no = before_and_inside_if([], [], delete),
- yes = before_and_inside_if([], [], x),
- yes = before_and_inside_if([], [b], delete),
- yes = before_and_inside_if([], [b], x),
-
- {ch1,ch2} = before_and_inside_if_2([a], [b], blah),
- {ch1,ch2} = before_and_inside_if_2([a], [b], xx),
- {ch1,ch2} = before_and_inside_if_2([a], [], blah),
- {ch1,ch2} = before_and_inside_if_2([a], [], xx),
- {no,no} = before_and_inside_if_2([], [b], blah),
- {no,no} = before_and_inside_if_2([], [b], xx),
- {ch1,no} = before_and_inside_if_2([], [], blah),
- {no,ch2} = before_and_inside_if_2([], [], xx),
- ok.
-
-%% Thanks to Simon Cornish and Kostis Sagonas.
-%% Used to crash beam_bool.
-before_and_inside_if(XDo1, XDo2, Do3) ->
- Do1 = (XDo1 =/= []),
- Do2 = (XDo2 =/= []),
- if
- %% This expression occurs in a try/catch (protected)
- %% block, which cannot refer to variables outside of
- %% the block that are boolean expressions.
- Do1 =:= true;
- Do1 =:= false, Do2 =:= false, Do3 =:= delete ->
- no;
- true ->
- yes
- end.
-
-%% Thanks to Simon Cornish.
-%% Used to generate code that would not set {y,0} on
-%% all paths before its use (and therefore fail
-%% validation by the beam_validator).
-before_and_inside_if_2(XDo1, XDo2, Do3) ->
- Do1 = (XDo1 =/= []),
- Do2 = (XDo2 =/= []),
- CH1 = if Do1 == true;
- Do1 == false,Do2==false,Do3 == blah ->
- ch1;
- true ->
- no
- end,
- CH2 = if Do1 == true;
- Do1 == false,Do2==false,Do3 == xx ->
- ch2;
- true ->
- no
- end,
- {CH1,CH2}.
-
-
-%% beam_bool would remove the initialization of {y,0}.
-%% (Thanks to Thomas Arts and QuickCheck.)
-
-scotland(_Config) ->
- million = do_scotland(placed),
- {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(false)),
- {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(true)),
- {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(echo)),
- ok.
-
-do_scotland(Echo) ->
- found(case Echo of
- Echo when true; Echo, Echo, Echo ->
- Echo;
- echo ->
- []
- end,
- Echo = placed).
-
-found(_, _) -> million.
-
-
-%% ERL-143: beam_bool could not handle Y registers as a destination.
-y_registers(_Config) ->
- {'EXIT',{badarith,[_|_]}} = (catch baker(valentine)),
- {'EXIT',{badarith,[_|_]}} = (catch baker(clementine)),
-
- {not_ok,true} = potter([]),
- {ok,false} = potter([{encoding,any}]),
-
- ok.
-
-%% Thanks to Quickcheck.
-baker(Baker) ->
- (valentine == Baker) +
- case Baker of
- Baker when Baker; Baker ->
- Baker;
- Baker ->
- []
- end.
-
-%% Thanks to Jose Valim.
-potter(Modes) ->
- Raw = lists:keyfind(encoding, 1, Modes) == false,
- Final = case Raw of
- X when X == false; X == nil -> ok;
- _ -> not_ok
- end,
- {Final,Raw}.
-
-protected(_Config) ->
- {'EXIT',{if_clause,_}} = (catch photographs({1, surprise, true}, opinions)),
-
- {{true}} = welcome({perfect, true}),
- {'EXIT',{if_clause,_}} = (catch welcome({perfect, false})),
- ok.
-
-photographs({_Violation, surprise, Deep}, opinions) ->
- {if
- 0; "here", Deep ->
- Deep = Deep
- end}.
-
-welcome({perfect, Profit}) ->
- if
- Profit, Profit, Profit; 0 ->
- {id({Profit})}
- end.
-
-maps(_Config) ->
- ok = evidence(#{0 => 42}).
-
-%% Cover handling of put_map in in split_block_label_used/2.
-evidence(#{0 := Charge}) when 0; #{[] => Charge} == #{[] => 42} ->
- ok.
-
-
-%%%
-%%% Common utilities.
-%%%
-
-id(I) ->
- I.
diff --git a/lib/compiler/test/bs_match_SUITE.erl b/lib/compiler/test/bs_match_SUITE.erl
index 6742571b86..89f851ac3b 100644
--- a/lib/compiler/test/bs_match_SUITE.erl
+++ b/lib/compiler/test/bs_match_SUITE.erl
@@ -887,28 +887,41 @@ matching_and_andalso(Config) when is_list(Config) ->
{'EXIT',{function_clause,_}} = (catch matching_and_andalso_1(<<1,2,3>>, blurf)),
{'EXIT',{function_clause,_}} = (catch matching_and_andalso_1(<<1,2,3>>, 19)),
- {"abc",<<"xyz">>} = matching_and_andalso_2("abc", <<"-xyz">>),
- {"abc",<<"">>} = matching_and_andalso_2("abc", <<($a-1)>>),
- {"abc",<<"">>} = matching_and_andalso_2("abc", <<($z+1)>>),
- {"abc",<<"">>} = matching_and_andalso_2("abc", <<($A-1)>>),
- {"abc",<<"">>} = matching_and_andalso_2("abc", <<($Z+1)>>),
- error = matching_and_andalso_2([], <<>>),
- error = matching_and_andalso_2([], <<$A>>),
- error = matching_and_andalso_2([], <<$Z>>),
- error = matching_and_andalso_2([], <<$a>>),
- error = matching_and_andalso_2([], <<$z>>),
+ {"abc",<<"xyz">>} = matching_and_andalso_23("abc", <<"-xyz">>),
+ {"abc",<<"">>} = matching_and_andalso_23("abc", <<($a-1)>>),
+ {"abc",<<"">>} = matching_and_andalso_23("abc", <<($z+1)>>),
+ {"abc",<<"">>} = matching_and_andalso_23("abc", <<($A-1)>>),
+ {"abc",<<"">>} = matching_and_andalso_23("abc", <<($Z+1)>>),
+ error = matching_and_andalso_23([], <<>>),
+ error = matching_and_andalso_23([], <<$A>>),
+ error = matching_and_andalso_23([], <<$Z>>),
+ error = matching_and_andalso_23([], <<$a>>),
+ error = matching_and_andalso_23([], <<$z>>),
ok.
matching_and_andalso_1(<<Bitmap/binary>>, K)
when is_integer(K) andalso size(Bitmap) >= K andalso 0 < K ->
ok.
+matching_and_andalso_23(Datetime, Bin) ->
+ Res = matching_and_andalso_2(Datetime, Bin),
+ Res = matching_and_andalso_3(Datetime, Bin),
+ Res.
+
matching_and_andalso_2(Datetime, <<H,T/binary>>)
when not ((H >= $a) andalso (H =< $z)) andalso
not ((H >= $A) andalso (H =< $Z)) ->
{Datetime,T};
matching_and_andalso_2(_, _) -> error.
+%% Contrived example to ensure we cover the handling of 'call' instructions
+%% in v3_codegen:bsm_rename_ctx/4.
+matching_and_andalso_3(Datetime, <<H,T/binary>>)
+ when not ((abs(H) >= $a) andalso (abs(H) =< $z)) andalso
+ not ((abs(H) >= $A) andalso (abs(H) =< $Z)) ->
+ {Datetime,T};
+matching_and_andalso_3(_, _) -> error.
+
%% Thanks to Tomas Stejskal.
otp_7188(Config) when is_list(Config) ->
MP3 = <<84,65,71,68,117,154,105,232,107,121,0,0,0,0,0,0,0,0,0,0,
diff --git a/lib/compiler/test/compile_SUITE.erl b/lib/compiler/test/compile_SUITE.erl
index 2953a901b5..e2988b18dc 100644
--- a/lib/compiler/test/compile_SUITE.erl
+++ b/lib/compiler/test/compile_SUITE.erl
@@ -32,7 +32,7 @@
other_output/1, kernel_listing/1, encrypted_abstr/1,
strict_record/1,
cover/1, env/1, core/1,
- core_roundtrip/1, asm/1,
+ core_roundtrip/1, asm/1, optimized_guards/1,
sys_pre_attributes/1, dialyzer/1,
warnings/1, pre_load_check/1, env_compiler_options/1
]).
@@ -49,7 +49,7 @@ all() ->
binary, makedep, cond_and_ifdef, listings, listings_big,
other_output, kernel_listing, encrypted_abstr,
strict_record,
- cover, env, core, core_roundtrip, asm,
+ cover, env, core, core_roundtrip, asm, optimized_guards,
sys_pre_attributes, dialyzer, warnings, pre_load_check,
env_compiler_options].
@@ -342,7 +342,6 @@ do_file_listings(DataDir, PrivDir, [File|Files]) ->
do_listing(Simple, TargetDir, dblk, ".block"),
do_listing(Simple, TargetDir, dexcept, ".except"),
do_listing(Simple, TargetDir, dbs, ".bs"),
- do_listing(Simple, TargetDir, dbool, ".bool"),
do_listing(Simple, TargetDir, dtype, ".type"),
do_listing(Simple, TargetDir, ddead, ".dead"),
do_listing(Simple, TargetDir, djmp, ".jump"),
@@ -927,6 +926,96 @@ do_asm(Beam, Outdir) ->
error
end.
+%% Make sure that guards are fully optimized. Guards should
+%% should use 'test' instructions, not 'bif' instructions.
+
+optimized_guards(_Config) ->
+ TestBeams = get_unique_beam_files(),
+ test_lib:p_run(fun(F) -> do_opt_guards(F) end, TestBeams).
+
+do_opt_guards(Beam) ->
+ {ok,{M,[{abstract_code,{raw_abstract_v1,A}}]}} =
+ beam_lib:chunks(Beam, [abstract_code]),
+ try
+ {ok,M,Asm} = compile:forms(A, ['S']),
+ do_opt_guards_mod(Asm)
+ catch Class:Error ->
+ io:format("~p: ~p ~p\n~p\n",
+ [M,Class,Error,erlang:get_stacktrace()]),
+ error
+ end.
+
+do_opt_guards_mod({Mod,_Exp,_Attr,Asm,_NumLabels}) ->
+ case do_opt_guards_fs(Mod, Asm) of
+ [] ->
+ ok;
+ [_|_]=Bifs ->
+ io:format("ERRORS FOR ~p:\n~p\n", [Mod,Bifs]),
+ error
+ end.
+
+do_opt_guards_fs(Mod, [{function,Name,Arity,_,Is}|Fs]) ->
+ Bifs0 = do_opt_guards_fun(Is),
+
+ %% The compiler does not attempt to optimize 'xor'.
+ %% Therefore, ignore all functions that use 'xor' in
+ %% a guard.
+ Bifs = case lists:any(fun({bif,'xor',_,_,_}) -> true;
+ (_) -> false
+ end, Bifs0) of
+ true -> [];
+ false -> Bifs0
+ end,
+
+ %% Filter out the allowed exceptions.
+ FA = {Name,Arity},
+ case {Bifs,is_exception(Mod, FA)} of
+ {[_|_],true} ->
+ io:format("~p:~p/~p IGNORED:\n~p\n",
+ [Mod,Name,Arity,Bifs]),
+ do_opt_guards_fs(Mod, Fs);
+ {[_|_],false} ->
+ [{FA,Bifs}|do_opt_guards_fs(Mod, Fs)];
+ {[],false} ->
+ do_opt_guards_fs(Mod, Fs);
+ {[],true} ->
+ io:format("Redundant exception for ~p:~p/~p\n",
+ [Mod,Name,Arity]),
+ error(redundant)
+ end;
+do_opt_guards_fs(_, []) -> [].
+
+do_opt_guards_fun([{bif,Name,{f,F},As,_}=I|Is]) when F =/= 0 ->
+ Arity = length(As),
+ case erl_internal:comp_op(Name, Arity) orelse
+ erl_internal:bool_op(Name, Arity) orelse
+ erl_internal:new_type_test(Name, Arity) of
+ true ->
+ [I|do_opt_guards_fun(Is)];
+ false ->
+ do_opt_guards_fun(Is)
+ end;
+do_opt_guards_fun([_|Is]) ->
+ do_opt_guards_fun(Is);
+do_opt_guards_fun([]) -> [].
+
+is_exception(bs_match_SUITE, {matching_and_andalso_2,2}) -> true;
+is_exception(bs_match_SUITE, {matching_and_andalso_3,2}) -> true;
+is_exception(guard_SUITE, {'-complex_not/1-fun-4-',1}) -> true;
+is_exception(guard_SUITE, {'-complex_not/1-fun-5-',1}) -> true;
+is_exception(guard_SUITE, {basic_andalso_orelse,1}) -> true;
+is_exception(guard_SUITE, {bad_guards,1}) -> true;
+is_exception(guard_SUITE, {bad_guards_2,2}) -> true;
+is_exception(guard_SUITE, {bad_guards_3,2}) -> true;
+is_exception(guard_SUITE, {cqlc,4}) -> true;
+is_exception(guard_SUITE, {csemi7,3}) -> true;
+is_exception(guard_SUITE, {misc,1}) -> true;
+is_exception(guard_SUITE, {nested_not_2b,4}) -> true;
+is_exception(guard_SUITE, {tricky_1,2}) -> true;
+is_exception(map_SUITE, {map_guard_update,2}) -> true;
+is_exception(map_SUITE, {map_guard_update_variables,3}) -> true;
+is_exception(_, _) -> false.
+
sys_pre_attributes(Config) ->
DataDir = proplists:get_value(data_dir, Config),
File = filename:join(DataDir, "attributes.erl"),
@@ -1152,8 +1241,15 @@ get_unique_beam_files() ->
get_unique_files(Ext) ->
Wc = filename:join(filename:dirname(code:which(?MODULE)), "*"++Ext),
- [F || F <- filelib:wildcard(Wc), not is_cloned(F, Ext)].
+ [F || F <- filelib:wildcard(Wc),
+ not is_cloned(F, Ext), not is_lfe_module(F, Ext)].
is_cloned(File, Ext) ->
Mod = list_to_atom(filename:basename(File, Ext)),
test_lib:is_cloned_mod(Mod).
+
+is_lfe_module(File, Ext) ->
+ case filename:basename(File, Ext) of
+ "lfe_" ++ _ -> true;
+ _ -> false
+ end.
diff --git a/lib/compiler/test/core_SUITE.erl b/lib/compiler/test/core_SUITE.erl
index b768f49e2c..f8839da42f 100644
--- a/lib/compiler/test/core_SUITE.erl
+++ b/lib/compiler/test/core_SUITE.erl
@@ -26,8 +26,9 @@
seq_in_guard/1,make_effect_seq/1,eval_is_boolean/1,
unsafe_case/1,nomatch_shadow/1,reversed_annos/1,
map_core_test/1,eval_case/1,bad_boolean_guard/1,
- bs_shadowed_size_var/1
- ]).
+ bs_shadowed_size_var/1,
+ cover_v3_kernel_1/1,cover_v3_kernel_2/1,cover_v3_kernel_3/1,
+ cover_v3_kernel_4/1,cover_v3_kernel_5/1]).
-include_lib("common_test/include/ct.hrl").
@@ -53,8 +54,10 @@ groups() ->
[dehydrated_itracer,nested_tries,seq_in_guard,make_effect_seq,
eval_is_boolean,unsafe_case,nomatch_shadow,reversed_annos,
map_core_test,eval_case,bad_boolean_guard,
- bs_shadowed_size_var
- ]}].
+ bs_shadowed_size_var,
+ cover_v3_kernel_1,cover_v3_kernel_2,cover_v3_kernel_3,
+ cover_v3_kernel_4,cover_v3_kernel_5
+ ]}].
init_per_suite(Config) ->
@@ -64,10 +67,10 @@ end_per_suite(_Config) ->
ok.
init_per_group(_GroupName, Config) ->
- Config.
+ Config.
end_per_group(_GroupName, Config) ->
- Config.
+ Config.
?comp(dehydrated_itracer).
@@ -82,6 +85,11 @@ end_per_group(_GroupName, Config) ->
?comp(eval_case).
?comp(bad_boolean_guard).
?comp(bs_shadowed_size_var).
+?comp(cover_v3_kernel_1).
+?comp(cover_v3_kernel_2).
+?comp(cover_v3_kernel_3).
+?comp(cover_v3_kernel_4).
+?comp(cover_v3_kernel_5).
try_it(Mod, Conf) ->
diff --git a/lib/compiler/test/core_SUITE_data/cover_v3_kernel_1.core b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_1.core
new file mode 100644
index 0000000000..9e5788796f
--- /dev/null
+++ b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_1.core
@@ -0,0 +1,147 @@
+module 'cover_v3_kernel_1' ['cover_v3_kernel_1'/0,
+ 'module_info'/0,
+ 'module_info'/1]
+ attributes []
+'cover_v3_kernel_1'/0 =
+ %% Line 4
+ fun () ->
+ case <> of
+ <> when 'true' ->
+ %% Line 5
+ case apply 'bad_and_args'/1
+ ('x') of
+ <'error'> when 'true' ->
+ %% Line 7
+ case apply 'bad_and_args'/2
+ (1, 2) of
+ <'error'> when 'true' ->
+ %% Line 8
+ case apply 'bad_and_args'/2
+ (1, 'true') of
+ <'error'> when 'true' ->
+ %% Line 9
+ case apply 'bad_and_args'/2
+ ('true', 42) of
+ <'error'> when 'true' ->
+ %% Line 10
+ case apply 'bad_and_args'/2
+ ('true', 'false') of
+ <'error'> when 'true' ->
+ %% Line 11
+ case apply 'bad_and_args'/2
+ ('false', 'true') of
+ <'error'> when 'true' ->
+ %% Line 12
+ case apply 'bad_and_args'/2
+ ('true', 'true') of
+ <'ok'> when 'true' ->
+ %% Line 14
+ 'ok'
+ ( <_@c6> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_@c6})
+ -| ['compiler_generated'] )
+ end
+ ( <_@c5> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_@c5})
+ -| ['compiler_generated'] )
+ end
+ ( <_@c4> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_@c4})
+ -| ['compiler_generated'] )
+ end
+ ( <_@c3> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_@c3})
+ -| ['compiler_generated'] )
+ end
+ ( <_@c2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_@c2})
+ -| ['compiler_generated'] )
+ end
+ ( <_@c1> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_@c1})
+ -| ['compiler_generated'] )
+ end
+ ( <_@c0> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_@c0})
+ -| ['compiler_generated'] )
+ end
+ ( <> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause'})
+ -| [{'function_name',{'cover_v3_kernel_1',0}}] )
+ -| ['compiler_generated'] )
+ end
+'bad_and_args'/1 =
+ %% Line 16
+ fun (_@c0) ->
+ case _@c0 of
+ <A>
+ when try
+ call 'erlang':'and'(A, 42)
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ %% Line 17
+ <_@c4> when 'true' ->
+ 'error'
+ ( <_@c3> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_@c3})
+ -| [{'function_name',{'bad_and_args',1}}] )
+ -| ['compiler_generated'] )
+ end
+'bad_and_args'/2 =
+ %% Line 19
+ fun (_@c1,_@c0) ->
+ case <_@c1,_@c0> of
+ <X,Y>
+ when try
+ call 'erlang':'and'(X, Y)
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ %% Line 20
+ <_@c6,_@c7> when 'true' ->
+ 'error'
+ ( <_@c5,_@c4> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_@c5,_@c4})
+ -| [{'function_name',{'bad_and_args',2}}] )
+ -| ['compiler_generated'] )
+ end
+'module_info'/0 =
+ fun () ->
+ case <> of
+ <> when 'true' ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_1')
+ ( <> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause'})
+ -| [{'function_name',{'module_info',0}}] )
+ -| ['compiler_generated'] )
+ end
+'module_info'/1 =
+ fun (_@c0) ->
+ case _@c0 of
+ <X> when 'true' ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_1', X)
+ ( <_@c1> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_@c1})
+ -| [{'function_name',{'module_info',1}}] )
+ -| ['compiler_generated'] )
+ end
+end
diff --git a/lib/compiler/test/core_SUITE_data/cover_v3_kernel_2.core b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_2.core
new file mode 100644
index 0000000000..165aacd691
--- /dev/null
+++ b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_2.core
@@ -0,0 +1,98 @@
+module 'cover_v3_kernel_2' ['cover_v3_kernel_2'/0,
+ 'module_info'/0,
+ 'module_info'/1]
+ attributes []
+'cover_v3_kernel_2'/0 =
+ %% Line 4
+ fun () ->
+ case <> of
+ <> when 'true' ->
+ %% Line 5
+ case apply 'strange_case'/1
+ ('a') of
+ <'ok'> when 'true' ->
+ %% Line 6
+ case apply 'strange_case'/1
+ ('b') of
+ <'ok'> when 'true' ->
+ %% Line 7
+ case apply 'strange_case'/1
+ ('c') of
+ <'error'> when 'true' ->
+ %% Line 8
+ case apply 'strange_case'/1
+ (42) of
+ <'error'> when 'true' ->
+ %% Line 9
+ 'ok'
+ ( <_cor3> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor3})
+ -| ['compiler_generated'] )
+ end
+ ( <_cor2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor2})
+ -| ['compiler_generated'] )
+ end
+ ( <_cor1> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor1})
+ -| ['compiler_generated'] )
+ end
+ ( <_cor0> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor0})
+ -| ['compiler_generated'] )
+ end
+ ( <> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause'})
+ -| [{'function_name',{'cover_v3_kernel_2',0}}] )
+ -| ['compiler_generated'] )
+ end
+'strange_case'/1 =
+ %% Line 12
+ fun (_cor0) ->
+ case _cor0 of
+ <X> when
+ case X of
+ <'a'> when 'true' -> 'true'
+ <'b'> when 'true' -> 'true'
+ <Other> when 'true' -> 'false'
+ end ->
+ 'ok'
+ %% Line 13
+ <_cor4> when 'true' ->
+ 'error'
+ ( <_cor3> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_cor3})
+ -| [{'function_name',{'strange_case',1}}] )
+ -| ['compiler_generated'] )
+ end
+'module_info'/0 =
+ fun () ->
+ case <> of
+ <> when 'true' ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_2')
+ ( <> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause'})
+ -| [{'function_name',{'module_info',0}}] )
+ -| ['compiler_generated'] )
+ end
+'module_info'/1 =
+ fun (_cor0) ->
+ case _cor0 of
+ <X> when 'true' ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_2', X)
+ ( <_cor1> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_cor1})
+ -| [{'function_name',{'module_info',1}}] )
+ -| ['compiler_generated'] )
+ end
+end
diff --git a/lib/compiler/test/core_SUITE_data/cover_v3_kernel_3.core b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_3.core
new file mode 100644
index 0000000000..88a9edc354
--- /dev/null
+++ b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_3.core
@@ -0,0 +1,98 @@
+module 'cover_v3_kernel_3' ['cover_v3_kernel_3'/0,
+ 'module_info'/0,
+ 'module_info'/1]
+ attributes []
+'cover_v3_kernel_3'/0 =
+ %% Line 4
+ fun () ->
+ case <> of
+ <> when 'true' ->
+ %% Line 5
+ case apply 'strange_case'/1
+ (1) of
+ <'ok'> when 'true' ->
+ %% Line 6
+ case apply 'strange_case'/1
+ (2) of
+ <'ok'> when 'true' ->
+ %% Line 7
+ case apply 'strange_case'/1
+ (42) of
+ <'error'> when 'true' ->
+ %% Line 8
+ case apply 'strange_case'/1
+ ('atom') of
+ <'error'> when 'true' ->
+ %% Line 9
+ 'ok'
+ ( <_cor3> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor3})
+ -| ['compiler_generated'] )
+ end
+ ( <_cor2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor2})
+ -| ['compiler_generated'] )
+ end
+ ( <_cor1> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor1})
+ -| ['compiler_generated'] )
+ end
+ ( <_cor0> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor0})
+ -| ['compiler_generated'] )
+ end
+ ( <> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause'})
+ -| [{'function_name',{'cover_v3_kernel_3',0}}] )
+ -| ['compiler_generated'] )
+ end
+'strange_case'/1 =
+ %% Line 12
+ fun (_cor0) ->
+ case _cor0 of
+ <X> when
+ case X of
+ <1> when 'true' -> 'true'
+ <2> when 'true' -> 'true'
+ <Other> when 'true' -> 'false'
+ end ->
+ 'ok'
+ %% Line 13
+ <_cor4> when 'true' ->
+ 'error'
+ ( <_cor3> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_cor3})
+ -| [{'function_name',{'strange_case',1}}] )
+ -| ['compiler_generated'] )
+ end
+'module_info'/0 =
+ fun () ->
+ case <> of
+ <> when 'true' ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_3')
+ ( <> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause'})
+ -| [{'function_name',{'module_info',0}}] )
+ -| ['compiler_generated'] )
+ end
+'module_info'/1 =
+ fun (_cor0) ->
+ case _cor0 of
+ <X> when 'true' ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_3', X)
+ ( <_cor1> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_cor1})
+ -| [{'function_name',{'module_info',1}}] )
+ -| ['compiler_generated'] )
+ end
+end
diff --git a/lib/compiler/test/core_SUITE_data/cover_v3_kernel_4.core b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_4.core
new file mode 100644
index 0000000000..905e236f26
--- /dev/null
+++ b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_4.core
@@ -0,0 +1,82 @@
+module 'cover_v3_kernel_4' ['cover_v3_kernel_4'/0,
+ 'module_info'/0,
+ 'module_info'/1]
+ attributes []
+'cover_v3_kernel_4'/0 =
+ %% Line 4
+ fun () ->
+ %% Line 5
+ case apply 'turned_case'/1
+ (20) of
+ <'ok'> when 'true' ->
+ %% Line 6
+ case apply 'turned_case'/1
+ (0) of
+ <'error'> when 'true' ->
+ %% Line 7
+ 'ok'
+ ( <_@c1> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_@c1})
+ -| ['compiler_generated'] )
+ end
+ ( <_@c0> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_@c0})
+ -| ['compiler_generated'] )
+ end
+'turned_case'/1 =
+ %% Line 9
+ fun (_@c0) ->
+ let <True> =
+ apply %% Line 10
+ 'id'/1
+ (%% Line 10
+ 'true')
+ in %% Line 11
+ case <> of
+ %% Line 12
+ <>
+ when try
+ ( let <_@c4> =
+ case call 'erlang':'<'
+ (_@c0, 10) of
+ ( <( 'false'
+ -| ['compiler_generated'] )> when 'true' ->
+ True
+ -| ['compiler_generated'] )
+ ( <( 'true'
+ -| ['compiler_generated'] )> when 'true' ->
+ 'false'
+ -| ['compiler_generated'] )
+ ( <_@c2> when 'true' ->
+ _@c2
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (( _@c4
+ -| ['compiler_generated'] ), 'true')
+ -| ['compiler_generated'] )
+ -| ['compiler_generated'] )
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ %% Line 13
+ <> when 'true' ->
+ 'error'
+ end
+'id'/1 =
+ %% Line 16
+ fun (_@c0) ->
+ _@c0
+'module_info'/0 =
+ fun () ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_4')
+'module_info'/1 =
+ fun (_@c0) ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_4', _@c0)
+end \ No newline at end of file
diff --git a/lib/compiler/test/core_SUITE_data/cover_v3_kernel_5.core b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_5.core
new file mode 100644
index 0000000000..48c1bb84e6
--- /dev/null
+++ b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_5.core
@@ -0,0 +1,98 @@
+module 'cover_v3_kernel_5' ['cover_v3_kernel_5'/0,
+ 'module_info'/0,
+ 'module_info'/1]
+ attributes []
+'cover_v3_kernel_5'/0 =
+ %% Line 4
+ fun () ->
+ case <> of
+ <> when 'true' ->
+ %% Line 5
+ case apply 'strange_case'/1
+ (1) of
+ <'ok'> when 'true' ->
+ %% Line 6
+ case apply 'strange_case'/1
+ (2) of
+ <'ok'> when 'true' ->
+ %% Line 7
+ case apply 'strange_case'/1
+ (42) of
+ <'error'> when 'true' ->
+ %% Line 8
+ case apply 'strange_case'/1
+ ('atom') of
+ <'error'> when 'true' ->
+ %% Line 9
+ 'ok'
+ ( <_cor3> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor3})
+ -| ['compiler_generated'] )
+ end
+ ( <_cor2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor2})
+ -| ['compiler_generated'] )
+ end
+ ( <_cor1> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor1})
+ -| ['compiler_generated'] )
+ end
+ ( <_cor0> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor0})
+ -| ['compiler_generated'] )
+ end
+ ( <> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause'})
+ -| [{'function_name',{'cover_v3_kernel_5',0}}] )
+ -| ['compiler_generated'] )
+ end
+'strange_case'/1 =
+ %% Line 12
+ fun (_cor0) ->
+ case _cor0 of
+ <X> when
+ case X of
+ <1> when 'true' -> 'true'
+ <2> when 'true' -> 'true'
+ <Other> when 'true' -> X
+ end ->
+ 'ok'
+ %% Line 13
+ <_cor4> when 'true' ->
+ 'error'
+ ( <_cor3> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_cor3})
+ -| [{'function_name',{'strange_case',1}}] )
+ -| ['compiler_generated'] )
+ end
+'module_info'/0 =
+ fun () ->
+ case <> of
+ <> when 'true' ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_5')
+ ( <> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause'})
+ -| [{'function_name',{'module_info',0}}] )
+ -| ['compiler_generated'] )
+ end
+'module_info'/1 =
+ fun (_cor0) ->
+ case _cor0 of
+ <X> when 'true' ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_5', X)
+ ( <_cor1> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_cor1})
+ -| [{'function_name',{'module_info',1}}] )
+ -| ['compiler_generated'] )
+ end
+end
diff --git a/lib/compiler/test/guard_SUITE.erl b/lib/compiler/test/guard_SUITE.erl
index 11d4038b06..a662d85272 100644
--- a/lib/compiler/test/guard_SUITE.erl
+++ b/lib/compiler/test/guard_SUITE.erl
@@ -35,7 +35,7 @@
basic_andalso_orelse/1,traverse_dcd/1,
check_qlc_hrl/1,andalso_semi/1,t_tuple_size/1,binary_part/1,
bad_constants/1,bad_guards/1,
- guard_in_catch/1]).
+ guard_in_catch/1,beam_bool_SUITE/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
@@ -54,7 +54,7 @@ groups() ->
rel_ops,rel_op_combinations,
literal_type_tests,basic_andalso_orelse,traverse_dcd,
check_qlc_hrl,andalso_semi,t_tuple_size,binary_part,
- bad_constants,bad_guards,guard_in_catch]}].
+ bad_constants,bad_guards,guard_in_catch,beam_bool_SUITE]}].
init_per_suite(Config) ->
Config.
@@ -2050,6 +2050,155 @@ do_guard_in_catch_bin(From) ->
saint
end.
+%%%
+%%% The beam_bool pass has been eliminated. Here are the tests from
+%%% beam_bool_SUITE.
+%%%
+
+beam_bool_SUITE(_Config) ->
+ before_and_inside_if(),
+ scotland(),
+ y_registers(),
+ protected(),
+ maps(),
+ ok.
+
+before_and_inside_if() ->
+ no = before_and_inside_if([a], [b], delete),
+ no = before_and_inside_if([a], [b], x),
+ no = before_and_inside_if([a], [], delete),
+ no = before_and_inside_if([a], [], x),
+ no = before_and_inside_if([], [], delete),
+ yes = before_and_inside_if([], [], x),
+ yes = before_and_inside_if([], [b], delete),
+ yes = before_and_inside_if([], [b], x),
+
+ {ch1,ch2} = before_and_inside_if_2([a], [b], blah),
+ {ch1,ch2} = before_and_inside_if_2([a], [b], xx),
+ {ch1,ch2} = before_and_inside_if_2([a], [], blah),
+ {ch1,ch2} = before_and_inside_if_2([a], [], xx),
+ {no,no} = before_and_inside_if_2([], [b], blah),
+ {no,no} = before_and_inside_if_2([], [b], xx),
+ {ch1,no} = before_and_inside_if_2([], [], blah),
+ {no,ch2} = before_and_inside_if_2([], [], xx),
+ ok.
+
+%% Thanks to Simon Cornish and Kostis Sagonas.
+%% Used to crash beam_bool.
+before_and_inside_if(XDo1, XDo2, Do3) ->
+ Do1 = (XDo1 =/= []),
+ Do2 = (XDo2 =/= []),
+ if
+ %% This expression occurs in a try/catch (protected)
+ %% block, which cannot refer to variables outside of
+ %% the block that are boolean expressions.
+ Do1 =:= true;
+ Do1 =:= false, Do2 =:= false, Do3 =:= delete ->
+ no;
+ true ->
+ yes
+ end.
+
+%% Thanks to Simon Cornish.
+%% Used to generate code that would not set {y,0} on
+%% all paths before its use (and therefore fail
+%% validation by the beam_validator).
+before_and_inside_if_2(XDo1, XDo2, Do3) ->
+ Do1 = (XDo1 =/= []),
+ Do2 = (XDo2 =/= []),
+ CH1 = if Do1 == true;
+ Do1 == false,Do2==false,Do3 == blah ->
+ ch1;
+ true ->
+ no
+ end,
+ CH2 = if Do1 == true;
+ Do1 == false,Do2==false,Do3 == xx ->
+ ch2;
+ true ->
+ no
+ end,
+ {CH1,CH2}.
+
+
+%% beam_bool would remove the initialization of {y,0}.
+%% (Thanks to Thomas Arts and QuickCheck.)
+
+scotland() ->
+ million = do_scotland(placed),
+ {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(false)),
+ {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(true)),
+ {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(echo)),
+ ok.
+
+do_scotland(Echo) ->
+ found(case Echo of
+ Echo when true; Echo, Echo, Echo ->
+ Echo;
+ echo ->
+ []
+ end,
+ Echo = placed).
+
+found(_, _) -> million.
+
+
+%% ERL-143: beam_bool could not handle Y registers as a destination.
+y_registers() ->
+ {'EXIT',{badarith,[_|_]}} = (catch baker(valentine)),
+ {'EXIT',{badarith,[_|_]}} = (catch baker(clementine)),
+
+ {not_ok,true} = potter([]),
+ {ok,false} = potter([{encoding,any}]),
+
+ ok.
+
+%% Thanks to Quickcheck.
+baker(Baker) ->
+ (valentine == Baker) +
+ case Baker of
+ Baker when Baker; Baker ->
+ Baker;
+ Baker ->
+ []
+ end.
+
+%% Thanks to Jose Valim.
+potter(Modes) ->
+ Raw = lists:keyfind(encoding, 1, Modes) == false,
+ Final = case Raw of
+ X when X == false; X == nil -> ok;
+ _ -> not_ok
+ end,
+ {Final,Raw}.
+
+protected() ->
+ {'EXIT',{if_clause,_}} = (catch photographs({1, surprise, true}, opinions)),
+
+ {{true}} = welcome({perfect, true}),
+ {'EXIT',{if_clause,_}} = (catch welcome({perfect, false})),
+ ok.
+
+photographs({_Violation, surprise, Deep}, opinions) ->
+ {if
+ 0; "here", Deep ->
+ Deep = Deep
+ end}.
+
+welcome({perfect, Profit}) ->
+ if
+ Profit, Profit, Profit; 0 ->
+ {id({Profit})}
+ end.
+
+maps() ->
+ ok = evidence(#{0 => 42}).
+
+%% Cover handling of put_map in in split_block_label_used/2.
+evidence(#{0 := Charge}) when 0; #{[] => Charge} == #{[] => 42} ->
+ ok.
+
+
%% Call this function to turn off constant propagation.
id(I) -> I.
diff --git a/lib/compiler/test/lfe-core.patch b/lib/compiler/test/lfe-core.patch
new file mode 100644
index 0000000000..756d131e2c
--- /dev/null
+++ b/lib/compiler/test/lfe-core.patch
@@ -0,0 +1,97 @@
+Date: Sun, 13 Nov 2016 10:11:11 +0100
+Subject: [PATCH] Fix invalid variable names
+
+---
+ test/lfe_andor_SUITE.core | 16 ++++++++--------
+ test/lfe_guard_SUITE.core | 14 +++++++-------
+ 2 files changed, 15 insertions(+), 15 deletions(-)
+
+diff --git a/test/lfe_andor_SUITE.core b/test/lfe_andor_SUITE.core
+index 96ff765..df58b39 100644
+--- a/test/lfe_andor_SUITE.core
++++ b/test/lfe_andor_SUITE.core
+@@ -288,19 +288,19 @@ module 'lfe_andor_SUITE' ['$handle_undefined_function'/2,
+ 'lc$^0'/1 =
+ fun (_2) ->
+ case <_2> of
+- <[_x|_|-0-|]> when 'true' ->
++ <[_x|_lfe0]> when 'true' ->
+ letrec
+ 'lc$^1'/1 =
+ fun (_3) ->
+ case <_3> of
+- <[_y|_|-1-|]> when 'true' ->
++ <[_y|_lfe1]> when 'true' ->
+ let <_4> =
+ apply 'lc$^1'/1
+- (_|-1-|)
++ (_lfe1)
+ in [{_x,_y}|_4]
+ <[]> when 'true' ->
+ apply 'lc$^0'/1
+- (_|-0-|)
++ (_lfe0)
+ ( <_5> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_5})
+@@ -455,19 +455,19 @@ module 'lfe_andor_SUITE' ['$handle_undefined_function'/2,
+ 'lc$^2'/1 =
+ fun (_2) ->
+ case <_2> of
+- <[_x|_|-2-|]> when 'true' ->
++ <[_x|_lfe2]> when 'true' ->
+ letrec
+ 'lc$^3'/1 =
+ fun (_3) ->
+ case <_3> of
+- <[_y|_|-3-|]> when 'true' ->
++ <[_y|_lfe3]> when 'true' ->
+ let <_4> =
+ apply 'lc$^3'/1
+- (_|-3-|)
++ (_lfe3)
+ in [{_x,_y}|_4]
+ <[]> when 'true' ->
+ apply 'lc$^2'/1
+- (_|-2-|)
++ (_lfe2)
+ ( <_5> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_5})
+diff --git a/test/lfe_guard_SUITE.core b/test/lfe_guard_SUITE.core
+index 38f1d99..920be82 100644
+--- a/test/lfe_guard_SUITE.core
++++ b/test/lfe_guard_SUITE.core
+@@ -2857,22 +2857,22 @@ module 'lfe_guard_SUITE' ['$handle_undefined_function'/2,
+ 'false' ->
+ case <_t> of
+ <{_a,_b,_c,_d}> when 'true' ->
+- let <_|-0-|> =
++ let <_lfe0> =
+ <_a>
+- in let <_|-1-|> =
++ in let <_lfe1> =
+ <_b>
+- in let <_|-2-|> =
++ in let <_lfe2> =
+ <_c>
+- in let <_|-3-|> =
++ in let <_lfe3> =
+ <_d>
+ in let <_4> =
+ let <_3> =
+ call 'erlang':'+'
+- (_|-0-|, _|-1-|)
++ (_lfe0, _lfe1)
+ in call 'erlang':'+'
+- (_3, _|-2-|)
++ (_3, _lfe2)
+ in call 'erlang':'+'
+- (_4, _|-3-|)
++ (_4, _lfe3)
+ ( <_5> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_5}})
+--
+2.7.4 (Apple Git-66)
+
diff --git a/lib/compiler/test/lfe-source.patch b/lib/compiler/test/lfe-source.patch
new file mode 100644
index 0000000000..cbd6748bc9
--- /dev/null
+++ b/lib/compiler/test/lfe-source.patch
@@ -0,0 +1,117 @@
+Date: Sun, 13 Nov 2016 09:40:36 +0100
+Subject: [PATCH] Rename and fix up LFE test suites
+
+---
+ test/{andor_SUITE.lfe => lfe_andor_SUITE.lfe} | 16 ++++++++--------
+ test/{guard_SUITE.lfe => lfe_guard_SUITE.lfe} | 8 ++++----
+ 2 files changed, 12 insertions(+), 12 deletions(-)
+ rename test/{andor_SUITE.lfe => lfe_andor_SUITE.lfe} (97%)
+ rename test/{guard_SUITE.lfe => lfe_guard_SUITE.lfe} (99%)
+
+diff --git a/test/andor_SUITE.lfe b/test/lfe_andor_SUITE.lfe
+similarity index 97%
+rename from test/andor_SUITE.lfe
+rename to test/lfe_andor_SUITE.lfe
+index 64feddd..1802b3f 100644
+--- a/test/andor_SUITE.lfe
++++ b/test/lfe_andor_SUITE.lfe
+@@ -26,14 +26,14 @@
+
+ (include-file "test_server.lfe")
+
+-(defmodule andor_SUITE
++(defmodule lfe_andor_SUITE
+ (export (all 0) (suite 0) (groups 0) (init_per_suite 1) (end_per_suite 1)
+ (init_per_group 2) (end_per_group 2)
+ (t_case 1) (t_and_or 1) (t_andalso 1) (t_orelse 1) (inside 1)
+ (overlap 1) (combined 1) (in_case 1) (before_and_inside_if 1)
+ ))
+
+-(defmacro MODULE () `'andor_SUITE)
++(defmacro MODULE () `'lfe_andor_SUITE)
+
+ (defun all ()
+ ;; (: test_lib recompile (MODULE))
+@@ -206,7 +206,7 @@
+
+ (defun t-andalso-1
+ ([(tuple x y)]
+- (: lfe_io format '"(andalso ~w ~w): " (list x y))
++ (: io format '"(andalso ~w ~w): " (list x y))
+ (let* ((v0 (andalso (echo x) (echo y)))
+ (v1 (when (=:= v0 v1))
+ (eif (andalso x y) 'true 'true 'false)))
+@@ -248,7 +248,7 @@
+
+ (defun t-orelse-1
+ ([(tuple x y)]
+- (: lfe_io format '"(orelse ~w ~w): " (list x y))
++ (: io format '"(orelse ~w ~w): " (list x y))
+ (let* ((v0 (orelse (echo x) (echo y)))
+ (v1 (when (=:= v0 v1))
+ (eif (orelse x y) 'true 'true 'false)))
+@@ -289,7 +289,7 @@
+ (when (=:= r1 r2) (=:= xm xm2) (=:= ym ym2) (=:= x x2)
+ (=:= y y2) (=:= w w2) (=:= h h2))
+ (inside-guard xm ym x y w h)))
+- (: lfe_io fwrite
++ (: io fwrite
+ '"(andalso (=< ~p ~p) (< ~p ~p) (=< ~p ~p) (< ~p ~p)) ==> ~p\n"
+ (list x xm xm (+ x w) y ym ym (+ y h) r1)))
+ r1))
+@@ -499,12 +499,12 @@
+ ;; Utilities
+
+ (defun check (v1 v0)
+- (eif (/= v1 v0) (progn (: lfe_io fwrite '"error: ~w.\n" (list v1))
++ (eif (/= v1 v0) (progn (: io fwrite '"error: ~w.\n" (list v1))
+ (exit 'suite_failed))
+- 'true (: lfe_io fwrite '"ok: ~w.\n" (list v1))))
++ 'true (: io fwrite '"ok: ~w.\n" (list v1))))
+
+ (defun echo (x)
+- (: lfe_io fwrite '"(eval ~w); " (list x))
++ (: io fwrite '"(eval ~w); " (list x))
+ x)
+
+ ;; Call this function to turn off constant propagation.
+diff --git a/test/guard_SUITE.lfe b/test/lfe_guard_SUITE.lfe
+similarity index 99%
+rename from test/guard_SUITE.lfe
+rename to test/lfe_guard_SUITE.lfe
+index 33b1344..2eeb1a6 100644
+--- a/test/guard_SUITE.lfe
++++ b/test/lfe_guard_SUITE.lfe
+@@ -26,7 +26,7 @@
+
+ (include-file "test_server.lfe")
+
+-(defmodule guard_SUITE
++(defmodule lfe_guard_SUITE
+ (export (all 0) (suite 0) (groups 0) (init_per_suite 1) (end_per_suite 1)
+ (init_per_group 2) (end_per_group 2)
+ (misc 1) (const_cond 1) (basic_not 1) (complex_not 1) (nested_nots 1)
+@@ -42,7 +42,7 @@
+ (check_qlc_hrl 1) (andalso_semi 1) (t_tuple_size 1) (binary_part 1)
+ ))
+
+-(defmacro MODULE () `'guard_SUITE)
++(defmacro MODULE () `'lfe_guard_SUITE)
+
+ (defun all ()
+ ;; (: test_lib recompile (MODULE))
+@@ -764,9 +764,9 @@
+
+ (defun is_function_2
+ ([config] (when (is_list config))
+- (line (test-pat 'true (is_function (id (function guard_SUITE all 1)) 1)))
++ (line (test-pat 'true (is_function (id (function lfe_guard_SUITE all 1)) 1)))
+ (line (test-pat 'true (is_function (id (lambda () 'ok)) 0)))
+- (line (test-pat 'false (is_function (id (function guard_SUITE all 1)) 0)))
++ (line (test-pat 'false (is_function (id (function lfe_guard_SUITE all 1)) 0)))
+ (line (test-pat 'false (is_function (id (lambda () 'ok)) 1)))
+
+ (let ((F (lambda (_) 'ok)))
+--
+2.7.4 (Apple Git-66)
+
diff --git a/lib/compiler/test/lfe.readme b/lib/compiler/test/lfe.readme
new file mode 100644
index 0000000000..2fc88e0252
--- /dev/null
+++ b/lib/compiler/test/lfe.readme
@@ -0,0 +1,31 @@
+Creating the LFE-derived test suites
+====================================
+
+Here is how to create `lfe_andor_SUITE.core` and `lfe_guard_SUITE.core`
+files.
+
+First clone and build LFE.
+
+ git clone https://github.com/rvirding/lfe.git
+ cd lfe
+ git checkout v1.2.0
+ MAKEFLAGS='' make compile
+ export PATH=$(pwd)/bin:$PATH
+
+Apply the source patch to rename and fix up the LFE source code:
+
+ cd test
+ git apply $ERL_TOP/lib/compiler/test/lfe-source.patch
+ git reset --hard HEAD
+
+Compile the modules to Core Erlang:
+
+ lfec +to-core0 lfe*.lfe
+
+Apply the core patch to correct some invalid variable names:
+
+ git apply $ERL_TOP/lib/compiler/test/lfe-core.patch
+
+Copy the patched .core file to the test suite:
+
+ cp lfe*.core $ERL_TOP/lib/compiler/test
diff --git a/lib/compiler/test/lfe_andor_SUITE.core b/lib/compiler/test/lfe_andor_SUITE.core
new file mode 100644
index 0000000000..df58b39ae6
--- /dev/null
+++ b/lib/compiler/test/lfe_andor_SUITE.core
@@ -0,0 +1,2014 @@
+module 'lfe_andor_SUITE' ['$handle_undefined_function'/2,
+ 'LFE-EXPAND-EXPORTED-MACRO'/3,
+ 'all'/0,
+ 'before_and_inside_if'/1,
+ 'combined'/1,
+ 'end_per_group'/2,
+ 'end_per_suite'/1,
+ 'groups'/0,
+ 'in_case'/1,
+ 'init_per_group'/2,
+ 'init_per_suite'/1,
+ 'inside'/1,
+ 'module_info'/0,
+ 'module_info'/1,
+ 'overlap'/1,
+ 'suite'/0,
+ 't_and_or'/1,
+ 't_andalso'/1,
+ 't_case'/1,
+ 't_orelse'/1]
+ attributes []
+'all'/0 =
+ %% Line 38
+ fun () ->
+ ['t_case'|['t_and_or'|['t_andalso'|['t_orelse'|['inside'|['overlap'|['combined'|['in_case'|['before_and_inside_if']]]]]]]]]
+'suite'/0 =
+ %% Line 44
+ fun () ->
+ []
+'groups'/0 =
+ %% Line 46
+ fun () ->
+ []
+'init_per_suite'/1 =
+ %% Line 48
+ fun (_config) ->
+ _config
+'end_per_suite'/1 =
+ %% Line 50
+ fun (_config) ->
+ 'ok'
+'init_per_group'/2 =
+ %% Line 52
+ fun (_name,_config) ->
+ _config
+'end_per_group'/2 =
+ %% Line 54
+ fun (_name,_config) ->
+ _config
+'t_case'/1 =
+ %% Line 56
+ fun (_0) ->
+ case <_0> of
+ <'suite'> when 'true' ->
+ []
+ <'doc'> when 'true' ->
+ [84|[101|[115|[116|[32|[105|[110|[32|[99|[97|[115|[101|[46]]]]]]]]]]]]]
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_andor_SUITE',['test-pat'|[['quote'|['less']]|[['t-case-a'|[1|[2]]]]]]})
+ let <_val> =
+ <apply 't-case-a'/2
+ (1, 2)>
+ in case <_val> of
+ <'less'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_25> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_25})
+ -| [{'function_name',{'t_case',1}}] )
+ -| ['compiler_generated'] )
+ end
+'t-case-a'/2 =
+ %% Line 94
+ fun (_a,_b) ->
+ case call 'erlang':'<'
+ (_a, _b) of
+ <[_0|_1]> when 'true' ->
+ 'ok'
+ <'true'> when 'true' ->
+ 'less'
+ <'false'> when 'true' ->
+ 'not_less'
+ <{'a','b','c'}> when 'true' ->
+ 'ok'
+ <_2> when 'true' ->
+ 'ok'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'t-case-b'/2 =
+ %% Line 102
+ fun (_a,_b) ->
+ case call 'erlang':'=:='
+ (_a, _b) of
+ <'blurf'> when 'true' ->
+ 'ok'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'t-case-c'/2 =
+ %% Line 106
+ fun (_a,_b) ->
+ case let <_0> =
+ call 'erlang':'=:='
+ (_a, _b)
+ in call 'erlang':'not'
+ (_0) of
+ <'true'> when 'true' ->
+ 'ne'
+ <'false'> when 'true' ->
+ 'eq'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'t-case-d'/3 =
+ %% Line 111
+ fun (_a,_b,_x) ->
+ case let <_0> =
+ call 'erlang':'=:='
+ (_a, _b)
+ in call 'erlang':'and'
+ (_0, _x) of
+ <'true'> when 'true' ->
+ 't'
+ <'false'> when 'true' ->
+ 'f'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'t-case-e'/2 =
+ %% Line 116
+ fun (_a,_b) ->
+ case call 'erlang':'=:='
+ (_a, _b) of
+ <_bool>
+ when try
+ let <_0> =
+ call 'erlang':'is_tuple'
+ (_a)
+ in _0
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ apply 'id'/1
+ (_bool)
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'t-case-xy'/3 =
+ %% Line 120
+ fun (_x,_y,_z) ->
+ let <_r0> =
+ <apply 't-case-x'/3
+ (_x, _y, _z)>
+ in case <apply 't-case-y'/3
+ (_x, _y, _z)> of
+ <_res>
+ when try
+ let <_0> =
+ call 'erlang':'=:='
+ (_res, _r0)
+ in _0
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ _res
+ ( <_1> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_1}})
+ -| ['compiler_generated'] )
+ end
+'t-case-x'/3 =
+ %% Line 125
+ fun (_x,_y,_z) ->
+ case let <_0> =
+ call 'erlang':'abs'
+ (_x)
+ in call 'erlang':'=:='
+ (_0, 42) of
+ <'true'> when 'true' ->
+ call 'erlang':'=:='
+ (_y, 100)
+ <'false'> when 'true' ->
+ call 'erlang':'=:='
+ (_z, 700)
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'t-case-y'/3 =
+ %% Line 130
+ fun (_x,_y,_z) ->
+ case let <_0> =
+ call 'erlang':'abs'
+ (_x)
+ in call 'erlang':'=:='
+ (_0, 42) of
+ <'false'> when 'true' ->
+ call 'erlang':'=:='
+ (_z, 700)
+ <'true'> when 'true' ->
+ call 'erlang':'=:='
+ (_y, 100)
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'t_and_or'/1 =
+ %% Line 135
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_andor_SUITE',['test-pat'|[['quote'|['true']]|[['and'|[['quote'|['true']]|[['quote'|['true']]]]]]]]})
+ let <_val> =
+ <call 'erlang':'and'
+ ('true', 'true')>
+ in case <_val> of
+ <'true'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_42> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_42})
+ -| [{'function_name',{'t_and_or',1}}] )
+ -| ['compiler_generated'] )
+ end
+'t_andalso'/1 =
+ %% Line 172
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do let <_bs> =
+ <['true'|['false']]>
+ in let <_ps> =
+ <letrec
+ 'lc$^0'/1 =
+ fun (_2) ->
+ case <_2> of
+ <[_x|_lfe0]> when 'true' ->
+ letrec
+ 'lc$^1'/1 =
+ fun (_3) ->
+ case <_3> of
+ <[_y|_lfe1]> when 'true' ->
+ let <_4> =
+ apply 'lc$^1'/1
+ (_lfe1)
+ in [{_x,_y}|_4]
+ <[]> when 'true' ->
+ apply 'lc$^0'/1
+ (_lfe0)
+ ( <_5> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_5})
+ -| [{'function_name',{'t_andalso',1}}] )
+ -| ['compiler_generated'] )
+ end
+ in apply 'lc$^1'/1
+ (_bs)
+ <[]> when 'true' ->
+ []
+ ( <_6> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_6})
+ -| [{'function_name',{'t_andalso',1}}] )
+ -| ['compiler_generated'] )
+ end
+ in apply 'lc$^0'/1
+ (_bs)>
+ in let <_7> =
+ fun (_p) ->
+ apply 't-andalso-1'/1
+ (_p)
+ in call 'lists':'foreach'
+ (_7, _ps)
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_andor_SUITE',['test-pat'|[['quote'|['true']]|[['andalso'|[['quote'|['true']]|[['quote'|['true']]]]]]]]})
+ let <_val> =
+ <case 'true' of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end>
+ in case <_val> of
+ <'true'> when 'true' ->
+ _val
+ ( <_8> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_8}})
+ -| ['compiler_generated'] )
+ end
+ ( <_57> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_57})
+ -| [{'function_name',{'t_andalso',1}}] )
+ -| ['compiler_generated'] )
+ end
+'t-andalso-1'/1 =
+ %% Line 207
+ fun (_0) ->
+ case <_0> of
+ <{_x,_y}> when 'true' ->
+ do call 'io':'format'
+ ([40|[97|[110|[100|[97|[108|[115|[111|[32|[126|[119|[32|[126|[119|[41|[58|[32]]]]]]]]]]]]]]]]], [_x,_y])
+ let <_v0> =
+ <case apply 'echo'/1
+ (_x) of
+ <'true'> when 'true' ->
+ apply 'echo'/1
+ (_y)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end>
+ in case <case 1 of
+ <_1>
+ when try
+ let <_3> =
+ let <_2> =
+ case _x of
+ <'true'> when 'true' ->
+ _y
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_2, 'true')
+ -| ['compiler_generated'] )
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_4>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <_v1>
+ when try
+ let <_5> =
+ call 'erlang':'=:='
+ (_v0, _v1)
+ in _5
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_6> =
+ call 'erlang':'and'
+ (_x, _y)
+ in apply 'check'/2
+ (_v1, _6)
+ ( <_7> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_7}})
+ -| ['compiler_generated'] )
+ end
+ ( <_8> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_8})
+ -| [{'function_name',{'t-andalso-1',1}}] )
+ -| ['compiler_generated'] )
+ end
+'t_orelse'/1 =
+ %% Line 215
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do let <_bs> =
+ <['true'|['false']]>
+ in let <_ps> =
+ <letrec
+ 'lc$^2'/1 =
+ fun (_2) ->
+ case <_2> of
+ <[_x|_lfe2]> when 'true' ->
+ letrec
+ 'lc$^3'/1 =
+ fun (_3) ->
+ case <_3> of
+ <[_y|_lfe3]> when 'true' ->
+ let <_4> =
+ apply 'lc$^3'/1
+ (_lfe3)
+ in [{_x,_y}|_4]
+ <[]> when 'true' ->
+ apply 'lc$^2'/1
+ (_lfe2)
+ ( <_5> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_5})
+ -| [{'function_name',{'t_orelse',1}}] )
+ -| ['compiler_generated'] )
+ end
+ in apply 'lc$^3'/1
+ (_bs)
+ <[]> when 'true' ->
+ []
+ ( <_6> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_6})
+ -| [{'function_name',{'t_orelse',1}}] )
+ -| ['compiler_generated'] )
+ end
+ in apply 'lc$^2'/1
+ (_bs)>
+ in let <_7> =
+ fun (_p) ->
+ apply 't-orelse-1'/1
+ (_p)
+ in call 'lists':'foreach'
+ (_7, _ps)
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_andor_SUITE',['test-pat'|[['quote'|['true']]|[['orelse'|[['quote'|['true']]|[['quote'|['true']]]]]]]]})
+ let <_val> =
+ <case 'true' of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ 'true'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end>
+ in case <_val> of
+ <'true'> when 'true' ->
+ _val
+ ( <_8> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_8}})
+ -| ['compiler_generated'] )
+ end
+ ( <_57> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_57})
+ -| [{'function_name',{'t_orelse',1}}] )
+ -| ['compiler_generated'] )
+ end
+'t-orelse-1'/1 =
+ %% Line 249
+ fun (_0) ->
+ case <_0> of
+ <{_x,_y}> when 'true' ->
+ do call 'io':'format'
+ ([40|[111|[114|[101|[108|[115|[101|[32|[126|[119|[32|[126|[119|[41|[58|[32]]]]]]]]]]]]]]]], [_x,_y])
+ let <_v0> =
+ <case apply 'echo'/1
+ (_x) of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ apply 'echo'/1
+ (_y)
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end>
+ in case <case 1 of
+ <_1>
+ when try
+ let <_3> =
+ let <_2> =
+ case _x of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ _y
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_2, 'true')
+ -| ['compiler_generated'] )
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_4>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <_v1>
+ when try
+ let <_5> =
+ call 'erlang':'=:='
+ (_v0, _v1)
+ in _5
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_6> =
+ call 'erlang':'or'
+ (_x, _y)
+ in apply 'check'/2
+ (_v1, _6)
+ ( <_7> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_7}})
+ -| ['compiler_generated'] )
+ end
+ ( <_8> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_8})
+ -| [{'function_name',{'t-orelse-1',1}}] )
+ -| ['compiler_generated'] )
+ end
+'inside'/1 =
+ %% Line 257
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_andor_SUITE',['test-pat'|[['quote'|['true']]|[['inside'|[-8|[1]]]]]]})
+ let <_val> =
+ <apply 'inside'/2
+ (-8, 1)>
+ in case <_val> of
+ <'true'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_12> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_12})
+ -| [{'function_name',{'inside',1}}] )
+ -| ['compiler_generated'] )
+ end
+'inside'/2 =
+ %% Line 272
+ fun (_xm,_ym) ->
+ let <_x> =
+ <-1.00000000000000000000e+01>
+ in let <_y> =
+ <-2.00000000000000000000e+00>
+ in let <_w> =
+ <2.00000000000000000000e+01>
+ in let <_h> =
+ <4.00000000000000000000e+00>
+ in let <_r0> =
+ <apply 'inside'/6
+ (_xm, _ym, _x, _y, _w, _h)>
+ in case <case 1 of
+ <_0>
+ when try
+ let <_4> =
+ let <_3> =
+ case call 'erlang':'=<'
+ (_x, _xm) of
+ <'true'> when 'true' ->
+ case let <_1> =
+ call 'erlang':'+'
+ (_x, _w)
+ in call 'erlang':'<'
+ (_xm, _1) of
+ <'true'> when 'true' ->
+ case call 'erlang':'=<'
+ (_y, _ym) of
+ <'true'> when 'true' ->
+ let <_2> =
+ call 'erlang':'+'
+ (_y, _h)
+ in call 'erlang':'<'
+ (_ym, _2)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_3, 'true')
+ -| ['compiler_generated'] )
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_5>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <_r1>
+ when try
+ let <_6> =
+ call 'erlang':'=:='
+ (_r0, _r1)
+ in _6
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do case let <_7> =
+ apply 'id'/1
+ (_r1)
+ in call 'erlang':'not'
+ (_7) of
+ <_o0> when 'true' ->
+ case <case 1 of
+ <_8>
+ when try
+ let <_12> =
+ let <_11> =
+ case call 'erlang':'=<'
+ (_x, _xm) of
+ <'true'> when 'true' ->
+ case let <_9> =
+ call 'erlang':'+'
+ (_x, _w)
+ in call 'erlang':'<'
+ (_xm, _9) of
+ <'true'> when 'true' ->
+ case call 'erlang':'=<'
+ (_y, _ym) of
+ <'true'> when 'true' ->
+ let <_10> =
+ call 'erlang':'+'
+ (_y, _h)
+ in call 'erlang':'<'
+ (_ym, _10)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in call 'erlang':'not'
+ (_11)
+ in _12
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_13>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <_o1>
+ when try
+ let <_14> =
+ call 'erlang':'=:='
+ (_o0, _o1)
+ in _14
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ _o1
+ ( <_15> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_15}})
+ -| ['compiler_generated'] )
+ end
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ do case <apply 'inside-guard'/6
+ (_xm, _ym, _x, _y, _w, _h)> of
+ <{_r2,_xm2,_ym2,_x2,_y2,_w2,_h2}>
+ when try
+ let <_16> =
+ call 'erlang':'=:='
+ (_r1, _r2)
+ in let <_17> =
+ call 'erlang':'=:='
+ (_xm, _xm2)
+ in let <_18> =
+ call 'erlang':'=:='
+ (_ym, _ym2)
+ in let <_19> =
+ call 'erlang':'=:='
+ (_x, _x2)
+ in let <_20> =
+ call 'erlang':'=:='
+ (_y, _y2)
+ in let <_21> =
+ call 'erlang':'=:='
+ (_w, _w2)
+ in let <_22> =
+ call 'erlang':'=:='
+ (_h, _h2)
+ in let <_23> =
+ call 'erlang':'and'
+ (_16, _17)
+ in let <_24> =
+ call 'erlang':'and'
+ (_23, _18)
+ in let <_25> =
+ call 'erlang':'and'
+ (_24, _19)
+ in let <_26> =
+ call 'erlang':'and'
+ (_25, _20)
+ in let <_27> =
+ call 'erlang':'and'
+ (_26, _21)
+ in call 'erlang':'and'
+ (_27, _22)
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_30> =
+ let <_28> =
+ call 'erlang':'+'
+ (_x, _w)
+ in let <_29> =
+ call 'erlang':'+'
+ (_y, _h)
+ in [_x,_xm,_xm,_28,_y,_ym,_ym,_29,_r1]
+ in call 'io':'fwrite'
+ ([40|[97|[110|[100|[97|[108|[115|[111|[32|[40|[61|[60|[32|[126|[112|[32|[126|[112|[41|[32|[40|[60|[32|[126|[112|[32|[126|[112|[41|[32|[40|[61|[60|[32|[126|[112|[32|[126|[112|[41|[32|[40|[60|[32|[126|[112|[32|[126|[112|[41|[41|[32|[61|[61|[62|[32|[126|[112|[10]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]], _30)
+ ( <_31> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_31}})
+ -| ['compiler_generated'] )
+ end
+ _r1
+ ( <_32> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_32}})
+ -| ['compiler_generated'] )
+ end
+'inside'/6 =
+ %% Line 297
+ fun (_xm,_ym,_x,_y,_w,_h) ->
+ case call 'erlang':'=<'
+ (_x, _xm) of
+ <'true'> when 'true' ->
+ case let <_0> =
+ call 'erlang':'+'
+ (_x, _w)
+ in call 'erlang':'<'
+ (_xm, _0) of
+ <'true'> when 'true' ->
+ case call 'erlang':'=<'
+ (_y, _ym) of
+ <'true'> when 'true' ->
+ let <_1> =
+ call 'erlang':'+'
+ (_y, _h)
+ in call 'erlang':'<'
+ (_ym, _1)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end
+'inside-guard'/6 =
+ %% Line 300
+ fun (_5,_4,_3,_2,_1,_0) ->
+ case <_5,_4,_3,_2,_1,_0> of
+ <_xm,_ym,_x,_y,_w,_h>
+ when try
+ let <_9> =
+ let <_8> =
+ case call 'erlang':'=<'
+ (_x, _xm) of
+ <'true'> when 'true' ->
+ case let <_6> =
+ call 'erlang':'+'
+ (_x, _w)
+ in call 'erlang':'<'
+ (_xm, _6) of
+ <'true'> when 'true' ->
+ case call 'erlang':'=<'
+ (_y, _ym) of
+ <'true'> when 'true' ->
+ let <_7> =
+ call 'erlang':'+'
+ (_y, _h)
+ in call 'erlang':'<'
+ (_ym, _7)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_8, 'true')
+ -| ['compiler_generated'] )
+ in _9
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ {'true',_xm,_ym,_x,_y,_w,_h}
+ <_xm,_ym,_x,_y,_w,_h> when 'true' ->
+ {'false',_xm,_ym,_x,_y,_w,_h}
+ ( <_15,_14,_13,_12,_11,_10> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_15,_14,_13,_12,_11,_10})
+ -| [{'function_name',{'inside-guard',6}}] )
+ -| ['compiler_generated'] )
+ end
+'overlap'/1 =
+ %% Line 307
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_andor_SUITE',['test-pat'|[['quote'|['true']]|[['overlap'|[7.00000000000000000000e+00|[2.00000000000000000000e+00|[8.00000000000000000000e+00|[5.00000000000000000000e-01]]]]]]]]})
+ let <_val> =
+ <apply 'overlap'/4
+ (7.00000000000000000000e+00, 2.00000000000000000000e+00, 8.00000000000000000000e+00, 5.00000000000000000000e-01)>
+ in case <_val> of
+ <'true'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_10> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_10})
+ -| [{'function_name',{'overlap',1}}] )
+ -| ['compiler_generated'] )
+ end
+'overlap'/4 =
+ %% Line 321
+ fun (_pos1,_len1,_pos2,_len2) ->
+ let <_r0> =
+ <case _pos1 of
+ <_pos1>
+ when try
+ let <_3> =
+ let <_2> =
+ case case call 'erlang':'=<'
+ (_pos2, _pos1) of
+ <'true'> when 'true' ->
+ let <_0> =
+ call 'erlang':'+'
+ (_pos2, _len2)
+ in call 'erlang':'<'
+ (_pos1, _0)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ case call 'erlang':'=<'
+ (_pos1, _pos2) of
+ <'true'> when 'true' ->
+ let <_1> =
+ call 'erlang':'+'
+ (_pos1, _len1)
+ in call 'erlang':'<'
+ (_pos2, _1)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_2, 'true')
+ -| ['compiler_generated'] )
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_pos1> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end>
+ in case <case case call 'erlang':'=<'
+ (_pos2, _pos1) of
+ <'true'> when 'true' ->
+ let <_4> =
+ call 'erlang':'+'
+ (_pos2, _len2)
+ in call 'erlang':'<'
+ (_pos1, _4)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ case call 'erlang':'=<'
+ (_pos1, _pos2) of
+ <'true'> when 'true' ->
+ let <_5> =
+ call 'erlang':'+'
+ (_pos1, _len1)
+ in call 'erlang':'<'
+ (_pos2, _5)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end> of
+ <_r1>
+ when try
+ let <_6> =
+ call 'erlang':'=:='
+ (_r0, _r1)
+ in _6
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ case <case _pos1 of
+ <_pos1>
+ when try
+ let <_10> =
+ let <_9> =
+ case case call 'erlang':'=<'
+ (_pos2, _pos1) of
+ <'true'> when 'true' ->
+ let <_7> =
+ call 'erlang':'+'
+ (_pos2, _len2)
+ in call 'erlang':'<'
+ (_pos1, _7)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ case call 'erlang':'=<'
+ (_pos1, _pos2) of
+ <'true'> when 'true' ->
+ let <_8> =
+ call 'erlang':'+'
+ (_pos1, _len1)
+ in call 'erlang':'<'
+ (_pos2, _8)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_9, 'true')
+ -| ['compiler_generated'] )
+ in _10
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_pos1> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <_r2>
+ when try
+ let <_11> =
+ call 'erlang':'=:='
+ (_r2, _r1)
+ in _11
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ apply 'id'/1
+ (_r2)
+ ( <_12> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_12}})
+ -| ['compiler_generated'] )
+ end
+ ( <_13> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_13}})
+ -| ['compiler_generated'] )
+ end
+'combined'/1 =
+ %% Line 348
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_andor_SUITE',['test-pat'|[['quote'|['false']]|[['comb'|[['quote'|['false']]|[['quote'|['false']]|[['quote'|['false']]]]]]]]]})
+ let <_val> =
+ <apply 'comb'/3
+ ('false', 'false', 'false')>
+ in case <_val> of
+ <'false'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_26> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_26})
+ -| [{'function_name',{'combined',1}}] )
+ -| ['compiler_generated'] )
+ end
+'comb'/3 =
+ %% Line 383
+ fun (_a,_b,_c) ->
+ let <_r0> =
+ <case case _a of
+ <'true'> when 'true' ->
+ _b
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ _c
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end>
+ in case <case 1 of
+ <_0>
+ when try
+ let <_2> =
+ let <_1> =
+ case case _a of
+ <'true'> when 'true' ->
+ _b
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ _c
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_1, 'true')
+ -| ['compiler_generated'] )
+ in _2
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_3>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <_r1>
+ when try
+ let <_4> =
+ call 'erlang':'=:='
+ (_r0, _r1)
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_n0> =
+ <case 1 of
+ <_5>
+ when try
+ let <_7> =
+ let <_6> =
+ case case _a of
+ <'true'> when 'true' ->
+ _b
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ _c
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in call 'erlang':'not'
+ (_6)
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_8>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end>
+ in case <let <_9> =
+ call 'erlang':'not'
+ (_r1)
+ in apply 'id'/1
+ (_9)> of
+ <_n1>
+ when try
+ let <_10> =
+ call 'erlang':'=:='
+ (_n0, _n1)
+ in _10
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ case <case case _a of
+ <'true'> when 'true' ->
+ _b
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ _c
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end> of
+ <_r2>
+ when try
+ let <_11> =
+ call 'erlang':'=:='
+ (_r1, _r2)
+ in _11
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ case <case 1 of
+ <_12>
+ when try
+ let <_14> =
+ let <_13> =
+ case case _a of
+ <'true'> when 'true' ->
+ _b
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ _c
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_13, 'true')
+ -| ['compiler_generated'] )
+ in _14
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_15>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <_r3>
+ when try
+ let <_16> =
+ call 'erlang':'=:='
+ (_r2, _r3)
+ in _16
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ case <let <_17> =
+ call 'erlang':'not'
+ (_r3)
+ in apply 'id'/1
+ (_17)> of
+ <_n2>
+ when try
+ let <_18> =
+ call 'erlang':'=:='
+ (_n1, _n2)
+ in _18
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ case <case 1 of
+ <_19>
+ when try
+ let <_21> =
+ let <_20> =
+ case case _a of
+ <'true'> when 'true' ->
+ _b
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ _c
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_20, 'true')
+ -| ['compiler_generated'] )
+ in _21
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_22>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <_r4>
+ when try
+ let <_23> =
+ call 'erlang':'=:='
+ (_r3, _r4)
+ in _23
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ apply 'id'/1
+ (_r4)
+ ( <_24> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_24}})
+ -| ['compiler_generated'] )
+ end
+ ( <_25> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_25}})
+ -| ['compiler_generated'] )
+ end
+ ( <_26> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_26}})
+ -| ['compiler_generated'] )
+ end
+ ( <_27> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_27}})
+ -| ['compiler_generated'] )
+ end
+ ( <_28> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_28}})
+ -| ['compiler_generated'] )
+ end
+ ( <_29> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_29}})
+ -| ['compiler_generated'] )
+ end
+'in_case'/1 =
+ %% Line 402
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_andor_SUITE',['test-pat'|[['quote'|['edge_rings']]|[['in-case-1'|[1|[1|[1|[1|[1]]]]]]]]]})
+ let <_val> =
+ <apply 'in-case-1'/5
+ (1, 1, 1, 1, 1)>
+ in case <_val> of
+ <'edge_rings'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_13> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_13})
+ -| [{'function_name',{'in_case',1}}] )
+ -| ['compiler_generated'] )
+ end
+'in-case-1'/5 =
+ %% Line 419
+ fun (_lenup,_lendw,_lenn,_rot,_count) ->
+ let <_r0> =
+ <apply 'in-case-1-body'/5
+ (_lenup, _lendw, _lenn, _rot, _count)>
+ in case <apply 'in-case-1-guard'/5
+ (_lenup, _lendw, _lenn, _rot, _count)> of
+ <_res>
+ when try
+ let <_0> =
+ call 'erlang':'=:='
+ (_r0, _res)
+ in _0
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ _res
+ ( <_1> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_1}})
+ -| ['compiler_generated'] )
+ end
+'in-case-1-body'/5 =
+ %% Line 425
+ fun (_lenup,_lendw,_lenn,_rot,_count) ->
+ case let <_5> =
+ let <_2> =
+ let <_0> =
+ call 'erlang':'/'
+ (_lenup, _count)
+ in call 'erlang':'>'
+ (_0, 7.06999999999999961808e-01)
+ in let <_3> =
+ let <_1> =
+ call 'erlang':'/'
+ (_lenn, _count)
+ in call 'erlang':'>'
+ (_1, 7.06999999999999961808e-01)
+ in call 'erlang':'and'
+ (_2, _3)
+ in let <_6> =
+ let <_4> =
+ call 'erlang':'abs'
+ (_rot)
+ in call 'erlang':'>'
+ (_4, 7.06999999999999961808e-01)
+ in call 'erlang':'and'
+ (_5, _6) of
+ <'true'> when 'true' ->
+ 'edge_rings'
+ <'false'> when 'true' ->
+ case let <_11> =
+ let <_9> =
+ let <_7> =
+ call 'erlang':'>='
+ (_lenup, 1)
+ in let <_8> =
+ call 'erlang':'>='
+ (_lendw, 1)
+ in call 'erlang':'or'
+ (_7, _8)
+ in let <_10> =
+ call 'erlang':'=<'
+ (_lenn, 1)
+ in call 'erlang':'or'
+ (_9, _10)
+ in let <_12> =
+ call 'erlang':'>'
+ (_count, 4)
+ in call 'erlang':'or'
+ (_11, _12) of
+ <'true'> when 'true' ->
+ 'not_loop'
+ <'false'> when 'true' ->
+ 'loop'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'in-case-1-guard'/5 =
+ %% Line 435
+ fun (_lenup,_lendw,_lenn,_rot,_count) ->
+ case case let <_0> =
+ call 'erlang':'/'
+ (_lenup, _count)
+ in call 'erlang':'>'
+ (_0, 7.06999999999999961808e-01) of
+ <'true'> when 'true' ->
+ case let <_1> =
+ call 'erlang':'/'
+ (_lenn, _count)
+ in call 'erlang':'>'
+ (_1, 7.06999999999999961808e-01) of
+ <'true'> when 'true' ->
+ let <_2> =
+ call 'erlang':'abs'
+ (_rot)
+ in call 'erlang':'>'
+ (_2, 7.06999999999999961808e-01)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'edge_rings'
+ <'false'>
+ when try
+ let <_4> =
+ let <_3> =
+ case call 'erlang':'>='
+ (_lenup, 1) of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ case call 'erlang':'>='
+ (_lendw, 1) of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ case call 'erlang':'=<'
+ (_lenn, 1) of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ call 'erlang':'<'
+ (_count, 4)
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_3, 'true')
+ -| ['compiler_generated'] )
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'not_loop'
+ <'false'> when 'true' ->
+ 'loop'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'before_and_inside_if'/1 =
+ %% Line 443
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_andor_SUITE',['test-pat'|[['quote'|['no']]|[['before-and-inside-if'|[['quote'|[['a']]]|[['quote'|[['b']]]|[['quote'|['delete']]]]]]]]]})
+ let <_val> =
+ <apply 'before-and-inside-if'/3
+ (['a'], ['b'], 'delete')>
+ in case <_val> of
+ <'no'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_18> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_18})
+ -| [{'function_name',{'before_and_inside_if',1}}] )
+ -| ['compiler_generated'] )
+ end
+'before-and-inside-if'/3 =
+ %% Line 468
+ fun (XDo1,XDo2,Do3) ->
+ let <Do1> =
+ <call 'erlang':'=/='
+ (XDo1, [])>
+ in let <Do2> =
+ <call 'erlang':'=/='
+ (XDo2, [])>
+ in case 1 of
+ <_0>
+ when try
+ let <_7> =
+ let <_5> =
+ call 'erlang':'=:='
+ (Do1, 'true')
+ in let <_6> =
+ let <_3> =
+ let <_1> =
+ call 'erlang':'=:='
+ (Do1, 'false')
+ in let <_2> =
+ call 'erlang':'=:='
+ (Do2, 'false')
+ in call 'erlang':'and'
+ (_1, _2)
+ in let <_4> =
+ call 'erlang':'=:='
+ (Do3, 'delete')
+ in call 'erlang':'and'
+ (_3, _4)
+ in call 'erlang':'or'
+ (_5, _6)
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'no'
+ <_8>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'yes'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'before-and-inside-if-2'/3 =
+ %% Line 484
+ fun (XDo1,XDo2,Do3) ->
+ let <Do1> =
+ <call 'erlang':'=/='
+ (XDo1, [])>
+ in let <Do2> =
+ <call 'erlang':'=/='
+ (XDo2, [])>
+ in let <CH1> =
+ <case 1 of
+ <_0>
+ when try
+ let <_7> =
+ let <_5> =
+ call 'erlang':'=='
+ (Do1, 'true')
+ in let <_6> =
+ let <_3> =
+ let <_1> =
+ call 'erlang':'=='
+ (Do1, 'false')
+ in let <_2> =
+ call 'erlang':'=='
+ (Do2, 'false')
+ in call 'erlang':'and'
+ (_1, _2)
+ in let <_4> =
+ call 'erlang':'=='
+ (Do3, 'blah')
+ in call 'erlang':'and'
+ (_3, _4)
+ in call 'erlang':'or'
+ (_5, _6)
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ch1'
+ <_8>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'no'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end>
+ in let <CH2> =
+ <case 1 of
+ <_9>
+ when try
+ let <_16> =
+ let <_14> =
+ call 'erlang':'=='
+ (Do1, 'true')
+ in let <_15> =
+ let <_12> =
+ let <_10> =
+ call 'erlang':'=='
+ (Do1, 'false')
+ in let <_11> =
+ call 'erlang':'=='
+ (Do2, 'false')
+ in call 'erlang':'and'
+ (_10, _11)
+ in let <_13> =
+ call 'erlang':'=='
+ (Do3, 'xx')
+ in call 'erlang':'and'
+ (_12, _13)
+ in call 'erlang':'or'
+ (_14, _15)
+ in _16
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ch2'
+ <_17>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'no'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end>
+ in {CH1,CH2}
+'check'/2 =
+ %% Line 501
+ fun (_v1,_v0) ->
+ case 1 of
+ <_0>
+ when try
+ let <_1> =
+ call 'erlang':'/='
+ (_v1, _v0)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'io':'fwrite'
+ ([101|[114|[114|[111|[114|[58|[32|[126|[119|[46|[10]]]]]]]]]]], [_v1])
+ call 'erlang':'exit'
+ ('suite_failed')
+ <_2>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ call 'io':'fwrite'
+ ([111|[107|[58|[32|[126|[119|[46|[10]]]]]]]], [_v1])
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'echo'/1 =
+ %% Line 506
+ fun (_x) ->
+ do call 'io':'fwrite'
+ ([40|[101|[118|[97|[108|[32|[126|[119|[41|[59|[32]]]]]]]]]]], [_x])
+ _x
+'id'/1 =
+ %% Line 511
+ fun (_i) ->
+ _i
+'$handle_undefined_function'/2 =
+ %% Line 29
+ fun (_f,_as) ->
+ case let <_0> =
+ call 'lfe_env':'new'
+ ()
+ in apply 'LFE-EXPAND-EXPORTED-MACRO'/3
+ (_f, _as, _0) of
+ <{'yes',_exp}> when 'true' ->
+ call 'lfe_eval':'expr'
+ (_exp)
+ <'no'> when 'true' ->
+ let <_a,_b> =
+ <_f,_as>
+ in call 'error_handler':'raise_undef_exception'
+ ('lfe_andor_SUITE', _a, _b)
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'LFE-EXPAND-EXPORTED-MACRO'/3 =
+ %% Line 29
+ fun (_2,_1,_0) ->
+ 'no'
+'module_info'/0 =
+ fun () ->
+ call 'erlang':'get_module_info'
+ ('lfe_andor_SUITE')
+'module_info'/1 =
+ fun (_x) ->
+ call 'erlang':'get_module_info'
+ ('lfe_andor_SUITE', _x)
+end
diff --git a/lib/compiler/test/lfe_guard_SUITE.core b/lib/compiler/test/lfe_guard_SUITE.core
new file mode 100644
index 0000000000..920be82f61
--- /dev/null
+++ b/lib/compiler/test/lfe_guard_SUITE.core
@@ -0,0 +1,3438 @@
+module 'lfe_guard_SUITE' ['$handle_undefined_function'/2,
+ 'LFE-EXPAND-EXPORTED-MACRO'/3,
+ 'all'/0,
+ 'and_guard'/1,
+ 'andalso_semi'/1,
+ 'basic_andalso_orelse'/1,
+ 'basic_not'/1,
+ 'binary_part'/1,
+ 'build_in_guard'/1,
+ 'check_qlc_hrl'/1,
+ 'comma'/1,
+ 'complex_not'/1,
+ 'complex_or_guards'/1,
+ 'complex_semicolon'/1,
+ 'const_cond'/1,
+ 'end_per_group'/2,
+ 'end_per_suite'/1,
+ 'gbif'/1,
+ 'groups'/0,
+ 'init_per_group'/2,
+ 'init_per_suite'/1,
+ 'is_function_2'/1,
+ 'literal_type_tests'/1,
+ 'misc'/1,
+ 'module_info'/0,
+ 'module_info'/1,
+ 'more_or_guards'/1,
+ 'more_xor_guards'/1,
+ 'nested_nots'/1,
+ 'old_guard_tests'/1,
+ 'or_guard'/1,
+ 'rel_ops'/1,
+ 'semicolon'/1,
+ 'suite'/0,
+ 't_is_boolean'/1,
+ 't_tuple_size'/1,
+ 'traverse_dcd'/1,
+ 'tricky'/1,
+ 'xor_guard'/1]
+ attributes []
+'all'/0 =
+ %% Line 47
+ fun () ->
+ ['misc'|['const_cond'|['basic_not'|['complex_not'|['nested_nots'|['semicolon'|['complex_semicolon'|['comma'|['or_guard'|['more_or_guards'|['complex_or_guards'|['and_guard'|['xor_guard'|['more_xor_guards'|['build_in_guard'|['old_guard_tests'|['gbif'|['t_is_boolean'|['is_function_2'|['tricky'|['rel_ops'|['literal_type_tests'|['basic_andalso_orelse'|['traverse_dcd'|['check_qlc_hrl'|['andalso_semi'|['t_tuple_size'|['binary_part']]]]]]]]]]]]]]]]]]]]]]]]]]]]
+'suite'/0 =
+ %% Line 58
+ fun () ->
+ []
+'groups'/0 =
+ %% Line 60
+ fun () ->
+ []
+'init_per_suite'/1 =
+ %% Line 62
+ fun (_config) ->
+ _config
+'end_per_suite'/1 =
+ %% Line 64
+ fun (_config) ->
+ 'ok'
+'init_per_group'/2 =
+ %% Line 66
+ fun (_name,_config) ->
+ _config
+'end_per_group'/2 =
+ %% Line 68
+ fun (_name,_config) ->
+ _config
+'misc'/1 =
+ %% Line 70
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[42|[['case'|[['id'|[42]]|[['x'|[['when'|[['-'|['x']]]]|[['quote'|['ok']]]]]|[['x'|['x']]]]]]]]]})
+ let <_val> =
+ <case apply 'id'/1
+ (42) of
+ <_x>
+ when try
+ let <_3> =
+ let <_2> =
+ call 'erlang':'-'
+ (_x)
+ in ( call 'erlang':'=:='
+ (_2, 'true')
+ -| ['compiler_generated'] )
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_x> when 'true' ->
+ _x
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end>
+ in case <_val> of
+ <42> when 'true' ->
+ _val
+ ( <_4> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_4}})
+ -| ['compiler_generated'] )
+ end
+ ( <_17> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_17})
+ -| [{'function_name',{'misc',1}}] )
+ -| ['compiler_generated'] )
+ end
+'misc-1'/1 =
+ %% Line 93
+ fun (_0) ->
+ case <_0> of
+ <[{_w},{_x},{_y},{_z}]> when 'true' ->
+ case 1 of
+ <_1>
+ when try
+ let <_4> =
+ let <_3> =
+ case call 'erlang':'>'
+ (_x, _y) of
+ <'true'> when 'true' ->
+ let <_2> =
+ call 'erlang':'abs'
+ (_z)
+ in call 'erlang':'=:='
+ (_2, 2)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_3, 'true')
+ -| ['compiler_generated'] )
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ apply 'id'/1
+ (_w)
+ <_5>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'none'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ ( <_6> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_6})
+ -| [{'function_name',{'misc-1',1}}] )
+ -| ['compiler_generated'] )
+ end
+'get-data'/3 =
+ %% Line 99
+ fun (_2,_1,_0) ->
+ case <_2,_1,_0> of
+ <{'o',_active,_raw},_bytes,_buffer>
+ when try
+ let <_5> =
+ let <_3> =
+ call 'erlang':'=:='
+ (_raw, 'raw')
+ in let <_4> =
+ call 'erlang':'=:='
+ (_raw, 0)
+ in call 'erlang':'or'
+ (_3, _4)
+ in _5
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ case 1 of
+ <_6>
+ when try
+ let <_8> =
+ let <_7> =
+ case call 'erlang':'=/='
+ (_active, 'false') of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ call 'erlang':'=:='
+ (_bytes, 0)
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_7, 'true')
+ -| ['compiler_generated'] )
+ in _8
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ {'ok',_buffer,#{}#}
+ <_9>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ ( <_12,_11,_10> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_12,_11,_10})
+ -| [{'function_name',{'get-data',3}}] )
+ -| ['compiler_generated'] )
+ end
+'const_cond'/1 =
+ %% Line 104
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['ok']]|[['const-cond'|[{}|[0]]]]]]})
+ let <_val> =
+ <apply 'const-cond'/2
+ ({}, 0)>
+ in case <_val> of
+ <'ok'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_7> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_7})
+ -| [{'function_name',{'const_cond',1}}] )
+ -| ['compiler_generated'] )
+ end
+'const-cond'/2 =
+ %% Line 113
+ fun (_t,_sz) ->
+ case _t of
+ <_0>
+ when try
+ 'false'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'never'
+ <_1>
+ when try
+ let <_3> =
+ call 'erlang':'is_tuple'
+ (_t)
+ in let <_4> =
+ call 'erlang':'=='
+ ('eq', 'eq')
+ in let <_5> =
+ let <_2> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=='
+ (_2, _sz)
+ in let <_6> =
+ call 'erlang':'and'
+ (_3, _4)
+ in call 'erlang':'and'
+ (_6, _5)
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_7>
+ when try
+ let <_9> =
+ call 'erlang':'is_tuple'
+ (_t)
+ in let <_10> =
+ call 'erlang':'=='
+ ('eq', 'leq')
+ in let <_11> =
+ let <_8> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=='
+ (_8, _sz)
+ in let <_12> =
+ call 'erlang':'and'
+ (_9, _10)
+ in call 'erlang':'and'
+ (_12, _11)
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_13> when 'true' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'basic_not'/1 =
+ %% Line 120
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_true> =
+ <apply 'id'/1
+ ('true')>
+ in let <_false> =
+ <apply 'id'/1
+ ('false')>
+ in let <_glurf> =
+ <apply 'id'/1
+ ('glurf')>
+ in let <_a> =
+ <apply 'id'/1
+ (5)>
+ in let <_b> =
+ <apply 'id'/1
+ (3.75000000000000000000e+01)>
+ in let <_c> =
+ <apply 'id'/1
+ (-1)>
+ in let <_d> =
+ <apply 'id'/1
+ (5)>
+ in let <_atuple> =
+ <{_false,_true,_glurf}>
+ in do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['check'|[['lambda'|[[]|[['eif'|[['not'|[['quote'|['false']]]]|[['quote'|['ok']]|[['quote'|['true']]|[['quote'|['error']]]]]]]]]]|[['quote'|['ok']]]]]})
+ let <_5> =
+ fun () ->
+ case 1 of
+ <_2>
+ when try
+ let <_3> =
+ call 'erlang':'not'
+ ('false')
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_4>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ in apply 'check'/2
+ (_5, 'ok')
+ ( <_128> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_128})
+ -| [{'function_name',{'basic_not',1}}] )
+ -| ['compiler_generated'] )
+ end
+'complex_not'/1 =
+ %% Line 164
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_atuple> =
+ <apply 'id'/1
+ ({'false','true','gurka'})>
+ in do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['check'|[['lambda'|[[]|[['eif'|[['not'|[['element'|[1|['atuple']]]]]|[['quote'|['ok']]|[['quote'|['true']]|[['quote'|['error']]]]]]]]]]|[['quote'|['ok']]]]]})
+ let <_6> =
+ fun () ->
+ case 1 of
+ <_2>
+ when try
+ let <_4> =
+ let <_3> =
+ call 'erlang':'element'
+ (1, _atuple)
+ in call 'erlang':'not'
+ (_3)
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_5>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ in apply 'check'/2
+ (_6, 'ok')
+ ( <_50> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_50})
+ -| [{'function_name',{'complex_not',1}}] )
+ -| ['compiler_generated'] )
+ end
+'nested_nots'/1 =
+ %% Line 191
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['true']]|[['nested-not-1'|[0|[0]]]]]]})
+ let <_val> =
+ <apply 'nested-not-1'/2
+ (0, 0)>
+ in case <_val> of
+ <'true'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_18> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_18})
+ -| [{'function_name',{'nested_nots',1}}] )
+ -| ['compiler_generated'] )
+ end
+'nested-not-1'/2 =
+ %% Line 213
+ fun (_1,_0) ->
+ case <_1,_0> of
+ <_x,_y>
+ when try
+ let <_10> =
+ let <_9> =
+ let <_7> =
+ let <_3> =
+ call 'erlang':'>'
+ (_x, _y)
+ in let <_4> =
+ let <_2> =
+ call 'erlang':'is_atom'
+ (_x)
+ in call 'erlang':'not'
+ (_2)
+ in call 'erlang':'or'
+ (_3, _4)
+ in let <_8> =
+ let <_5> =
+ call 'erlang':'is_atom'
+ (_y)
+ in let <_6> =
+ call 'erlang':'=='
+ (_x, 3.39999999999999991118e+00)
+ in call 'erlang':'or'
+ (_5, _6)
+ in call 'erlang':'and'
+ (_7, _8)
+ in call 'erlang':'not'
+ (_9)
+ in _10
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_11,_12> when 'true' ->
+ 'false'
+ ( <_14,_13> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_14,_13})
+ -| [{'function_name',{'nested-not-1',2}}] )
+ -| ['compiler_generated'] )
+ end
+'nested-not-2'/3 =
+ %% Line 219
+ fun (_x,_y,_z) ->
+ apply 'nested-not-2'/4
+ (_x, _y, _z, 'true')
+'nested-not-2'/4 =
+ %% Line 222
+ fun (_3,_2,_1,_0) ->
+ case <_3,_2,_1,_0> of
+ <_x,_y,_z,_true>
+ when try
+ let <_12> =
+ let <_11> =
+ let <_10> =
+ let <_9> =
+ let <_7> =
+ let <_4> =
+ call 'erlang':'not'
+ (_x)
+ in let <_5> =
+ call 'erlang':'not'
+ (_y)
+ in call 'erlang':'and'
+ (_4, _5)
+ in let <_8> =
+ let <_6> =
+ call 'erlang':'is_atom'
+ (_z)
+ in call 'erlang':'not'
+ (_6)
+ in call 'erlang':'or'
+ (_7, _8)
+ in call 'erlang':'not'
+ (_9)
+ in call 'erlang':'and'
+ (_true, _10)
+ in call 'erlang':'not'
+ (_11)
+ in _12
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_13,_14,_15,_16> when 'true' ->
+ 'false'
+ ( <_20,_19,_18,_17> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_20,_19,_18,_17})
+ -| [{'function_name',{'nested-not-2',4}}] )
+ -| ['compiler_generated'] )
+ end
+'semicolon'/1 =
+ %% Line 228
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_2> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_2})
+ -| [{'function_name',{'semicolon',1}}] )
+ -| ['compiler_generated'] )
+ end
+'complex_semicolon'/1 =
+ %% Line 233
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_2> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_2})
+ -| [{'function_name',{'complex_semicolon',1}}] )
+ -| ['compiler_generated'] )
+ end
+'comma'/1 =
+ %% Line 239
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['check'|[['lambda'|[[]|[['eif'|[['progn'|[['quote'|['true']]|[['quote'|['false']]]]]|[['quote'|['ok']]|[['quote'|['true']]|[['quote'|['error']]]]]]]]]]|[['quote'|['error']]]]]})
+ let <_6> =
+ fun () ->
+ case 1 of
+ <_2>
+ when try
+ let <_4> =
+ let <_3> =
+ call 'erlang':'and'
+ ('true', 'false')
+ in ( call 'erlang':'=:='
+ (_3, 'true')
+ -| ['compiler_generated'] )
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_5>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ in apply 'check'/2
+ (_6, 'error')
+ ( <_181> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_181})
+ -| [{'function_name',{'comma',1}}] )
+ -| ['compiler_generated'] )
+ end
+'or_guard'/1 =
+ %% Line 305
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do let <_true,_false,_glurf> =
+ <apply 'id'/1
+ ('true'),apply 'id'/1
+ ('false'),apply 'id'/1
+ ('glurf')>
+ in do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['check'|[['lambda'|[[]|[['eif'|[['or'|[['quote'|['true']]|[['quote'|['false']]]]]|[['quote'|['ok']]]]]]]]|[['quote'|['ok']]]]]})
+ let <_4> =
+ fun () ->
+ case 1 of
+ <_2>
+ when try
+ let <_3> =
+ call 'erlang':'or'
+ ('true', 'false')
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ in apply 'check'/2
+ (_4, 'ok')
+ 'ok'
+ ( <_64> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_64})
+ -| [{'function_name',{'or_guard',1}}] )
+ -| ['compiler_generated'] )
+ end
+'more_or_guards'/1 =
+ %% Line 346
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do let <_true> =
+ <apply 'id'/1
+ ('true')>
+ in let <_false> =
+ <apply 'id'/1
+ ('false')>
+ in let <_atuple> =
+ <apply 'id'/1
+ ({'false','true','gurks'})>
+ in do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['check'|[['lambda'|[[]|[['eif'|[['or'|[['element'|[42|['atuple']]]|['false']]]|[['quote'|['ok']]|[['quote'|['true']]|[['quote'|['error']]]]]]]]]]|[['quote'|['error']]]]]})
+ let <_6> =
+ fun () ->
+ case 1 of
+ <_2>
+ when try
+ let <_4> =
+ let <_3> =
+ call 'erlang':'element'
+ (42, _atuple)
+ in call 'erlang':'or'
+ (_3, _false)
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_5>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ in apply 'check'/2
+ (_6, 'error')
+ 'ok'
+ ( <_68> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_68})
+ -| [{'function_name',{'more_or_guards',1}}] )
+ -| ['compiler_generated'] )
+ end
+'complex_or_guards'/1 =
+ %% Line 409
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['ok']]|[['complex-or-1'|[{'a','b','c','d'}|[{1,2,3}]]]]]]})
+ let <_val> =
+ <apply 'complex-or-1'/2
+ ({'a','b','c','d'}, {1,2,3})>
+ in case <_val> of
+ <'ok'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_55> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_55})
+ -| [{'function_name',{'complex_or_guards',1}}] )
+ -| ['compiler_generated'] )
+ end
+'complex-or-1'/2 =
+ %% Line 487
+ fun (_a,_b) ->
+ case 1 of
+ <_0>
+ when try
+ let <_11> =
+ let <_9> =
+ let <_3> =
+ let <_1> =
+ call 'erlang':'tuple_size'
+ (_a)
+ in call 'erlang':'<'
+ (3, _1)
+ in let <_4> =
+ let <_2> =
+ call 'erlang':'tuple_size'
+ (_a)
+ in call 'erlang':'<'
+ (_2, 9)
+ in call 'erlang':'and'
+ (_3, _4)
+ in let <_10> =
+ let <_7> =
+ let <_5> =
+ call 'erlang':'tuple_size'
+ (_b)
+ in call 'erlang':'<'
+ (2, _5)
+ in let <_8> =
+ let <_6> =
+ call 'erlang':'tuple_size'
+ (_b)
+ in call 'erlang':'<'
+ (_6, 7)
+ in call 'erlang':'and'
+ (_7, _8)
+ in call 'erlang':'or'
+ (_9, _10)
+ in _11
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_12>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'complex-or-2'/1 =
+ %% Line 492
+ fun (_tuple) ->
+ case 1 of
+ <_0>
+ when try
+ let <_6> =
+ let <_4> =
+ call 'erlang':'element'
+ (1, _tuple)
+ in let <_5> =
+ let <_3> =
+ let <_2> =
+ let <_1> =
+ call 'erlang':'element'
+ (2, _tuple)
+ in call 'erlang':'tuple_size'
+ (_1)
+ in call 'erlang':'>'
+ (_2, 3)
+ in call 'erlang':'not'
+ (_3)
+ in call 'erlang':'or'
+ (_4, _5)
+ in _6
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_7>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'complex-or-3'/2 =
+ %% Line 496
+ fun (_a,_b) ->
+ case 1 of
+ <_0>
+ when try
+ let <_5> =
+ let <_3> =
+ let <_2> =
+ let <_1> =
+ call 'erlang':'size'
+ (_b)
+ in call 'erlang':'>'
+ (_1, 3)
+ in call 'erlang':'not'
+ (_2)
+ in let <_4> =
+ call 'erlang':'element'
+ (1, _a)
+ in call 'erlang':'or'
+ (_3, _4)
+ in _5
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_6>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'complex-or-4'/2 =
+ %% Line 499
+ fun (_a,_b) ->
+ case 1 of
+ <_0>
+ when try
+ let <_7> =
+ let <_5> =
+ let <_4> =
+ let <_2> =
+ call 'erlang':'is_tuple'
+ (_a)
+ in let <_3> =
+ let <_1> =
+ call 'erlang':'size'
+ (_a)
+ in call 'erlang':'>'
+ (_1, 3)
+ in call 'erlang':'and'
+ (_2, _3)
+ in call 'erlang':'not'
+ (_4)
+ in let <_6> =
+ call 'erlang':'element'
+ (1, _b)
+ in call 'erlang':'or'
+ (_5, _6)
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_8>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'complex-or-5'/2 =
+ %% Line 503
+ fun (_a,_b) ->
+ case 1 of
+ <_0>
+ when try
+ let <_8> =
+ let <_6> =
+ let <_4> =
+ let <_2> =
+ call 'erlang':'is_tuple'
+ (_a)
+ in let <_3> =
+ let <_1> =
+ call 'erlang':'size'
+ (_a)
+ in call 'erlang':'>'
+ (_1, 3)
+ in call 'erlang':'and'
+ (_2, _3)
+ in call 'erlang':'not'
+ (_4)
+ in let <_7> =
+ let <_5> =
+ call 'erlang':'element'
+ (1, _b)
+ in call 'erlang':'not'
+ (_5)
+ in call 'erlang':'or'
+ (_6, _7)
+ in _8
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_9>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'complex-or-6'/2 =
+ %% Line 507
+ fun (_a,_b) ->
+ case 1 of
+ <_0>
+ when try
+ let <_11> =
+ let <_9> =
+ let <_5> =
+ let <_3> =
+ let <_1> =
+ call 'erlang':'element'
+ (1, _a)
+ in call 'erlang':'not'
+ (_1)
+ in let <_4> =
+ let <_2> =
+ call 'erlang':'element'
+ (2, _a)
+ in call 'erlang':'not'
+ (_2)
+ in call 'erlang':'and'
+ (_3, _4)
+ in call 'erlang':'not'
+ (_5)
+ in let <_10> =
+ let <_8> =
+ let <_7> =
+ let <_6> =
+ call 'erlang':'size'
+ (_b)
+ in call 'erlang':'>'
+ (_6, 3)
+ in call 'erlang':'not'
+ (_7)
+ in call 'erlang':'not'
+ (_8)
+ in call 'erlang':'or'
+ (_9, _10)
+ in _11
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_12>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'and_guard'/1 =
+ %% Line 512
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['check'|[['lambda'|[[]|[['eif'|[['and'|[['quote'|['true']]|[['quote'|['false']]]]]|[['quote'|['ok']]|[['quote'|['true']]|[['quote'|['error']]]]]]]]]]|[['quote'|['error']]]]]})
+ let <_5> =
+ fun () ->
+ case 1 of
+ <_2>
+ when try
+ let <_3> =
+ call 'erlang':'and'
+ ('true', 'false')
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_4>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ in apply 'check'/2
+ (_5, 'error')
+ ( <_120> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_120})
+ -| [{'function_name',{'and_guard',1}}] )
+ -| ['compiler_generated'] )
+ end
+'relprod'/2 =
+ %% Line 588
+ fun (_1,_0) ->
+ case <_1,_0> of
+ <_r1,_r2>
+ when try
+ let <_10> =
+ let <_4> =
+ let <_2> =
+ call 'erlang':'size'
+ (_r1)
+ in call 'erlang':'=:='
+ (_2, 3)
+ in let <_5> =
+ let <_3> =
+ call 'erlang':'element'
+ (1, _r1)
+ in call 'erlang':'=:='
+ (_3, 'Set')
+ in call 'erlang':'and'
+ (_4, _5)
+ in let <_11> =
+ let <_8> =
+ let <_6> =
+ call 'erlang':'size'
+ (_r2)
+ in call 'erlang':'=:='
+ (_6, 3)
+ in let <_9> =
+ let <_7> =
+ call 'erlang':'element'
+ (1, _r2)
+ in call 'erlang':'=:='
+ (_7, 'Set')
+ in call 'erlang':'and'
+ (_8, _9)
+ in call 'erlang':'and'
+ (_10, _11)
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_13,_12> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_13,_12})
+ -| [{'function_name',{'relprod',2}}] )
+ -| ['compiler_generated'] )
+ end
+'xor_guard'/1 =
+ %% Line 595
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['check'|[['lambda'|[[]|[['eif'|[['xor'|[['quote'|['true']]|[['quote'|['false']]]]]|[['quote'|['ok']]]]]]]]|[['quote'|['ok']]]]]})
+ let <_4> =
+ fun () ->
+ case 1 of
+ <_2>
+ when try
+ let <_3> =
+ call 'erlang':'xor'
+ ('true', 'false')
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ in apply 'check'/2
+ (_4, 'ok')
+ ( <_54> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_54})
+ -| [{'function_name',{'xor_guard',1}}] )
+ -| ['compiler_generated'] )
+ end
+'more_xor_guards'/1 =
+ %% Line 636
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_true,_false,_atuple> =
+ <apply 'id'/1
+ ('true'),apply 'id'/1
+ ('false'),apply 'id'/1
+ ({'false','true','gurka'})>
+ in do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['check'|[['lambda'|[[]|[['eif'|[['xor'|[['element'|[42|['atuple']]]|['false']]]|[['quote'|['ok']]|[['quote'|['true']]|[['quote'|['error']]]]]]]]]]|[['quote'|['error']]]]]})
+ let <_6> =
+ fun () ->
+ case 1 of
+ <_2>
+ when try
+ let <_4> =
+ let <_3> =
+ call 'erlang':'element'
+ (42, _atuple)
+ in call 'erlang':'xor'
+ (_3, _false)
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_5>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ in apply 'check'/2
+ (_6, 'error')
+ ( <_29> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_29})
+ -| [{'function_name',{'more_xor_guards',1}}] )
+ -| ['compiler_generated'] )
+ end
+'build_in_guard'/1 =
+ %% Line 666
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_subbin> =
+ <#{#<64>(8,1,'integer',['unsigned'|['big']]),
+ #<20>(8,1,'integer',['unsigned'|['big']]),
+ #<0>(8,1,'integer',['unsigned'|['big']]),
+ #<0>(8,1,'integer',['unsigned'|['big']]),
+ #<0>(8,1,'integer',['unsigned'|['big']]),
+ #<0>(8,1,'integer',['unsigned'|['big']]),
+ #<0>(8,1,'integer',['unsigned'|['big']]),
+ #<0>(8,1,'integer',['unsigned'|['big']])}#>
+ in let <_b> =
+ <#{#<1>(8,1,'integer',['unsigned'|['big']]),
+ #<_subbin>('all',8,'binary',['unsigned'|['big']]),
+ #<3.50000000000000000000e+00>(64,1,'float',['unsigned'|['big']])}#>
+ in do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['ok']]|[['eif'|[['=:='|['b'|[['binary'|[1|[['subbin'|['binary']]|[[3.50000000000000000000e+00|['float']]]]]]]]]|[['quote'|['ok']]]]]]]]})
+ let <_val> =
+ <case 1 of
+ <_2>
+ when try
+ let <_3> =
+ call 'erlang':'=:='
+ (_b, #{#<1>(8,1,'integer',['unsigned'|['big']]),
+ #<_subbin>('all',8,'binary',['unsigned'|['big']]),
+ #<3.50000000000000000000e+00>(64,1,'float',['unsigned'|['big']])}#)
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end>
+ in case <_val> of
+ <'ok'> when 'true' ->
+ _val
+ ( <_4> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_4}})
+ -| ['compiler_generated'] )
+ end
+ ( <_5> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_5})
+ -| [{'function_name',{'build_in_guard',1}}] )
+ -| ['compiler_generated'] )
+ end
+'old_guard_tests'/1 =
+ %% Line 674
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_2> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_2})
+ -| [{'function_name',{'old_guard_tests',1}}] )
+ -| ['compiler_generated'] )
+ end
+'gbif'/1 =
+ %% Line 679
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['error']]|[['gbif-1'|[1|[{'false','true'}]]]]]]})
+ let <_val> =
+ <apply 'gbif-1'/2
+ (1, {'false','true'})>
+ in case <_val> of
+ <'error'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_4> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_4})
+ -| [{'function_name',{'gbif',1}}] )
+ -| ['compiler_generated'] )
+ end
+'gbif-1'/2 =
+ %% Line 685
+ fun (_1,_0) ->
+ case <_1,_0> of
+ <_p,_t>
+ when try
+ let <_3> =
+ let <_2> =
+ call 'erlang':'element'
+ (_p, _t)
+ in ( call 'erlang':'=:='
+ (_2, 'true')
+ -| ['compiler_generated'] )
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_4,_5> when 'true' ->
+ 'error'
+ ( <_7,_6> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_7,_6})
+ -| [{'function_name',{'gbif-1',2}}] )
+ -| ['compiler_generated'] )
+ end
+'t_is_boolean'/1 =
+ %% Line 690
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['true']]|[['is_boolean'|[['quote'|['true']]]]]]]})
+ let <_val> =
+ <call 'erlang':'is_boolean'
+ ('true')>
+ in case <_val> of
+ <'true'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_70> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_70})
+ -| [{'function_name',{'t_is_boolean',1}}] )
+ -| ['compiler_generated'] )
+ end
+'bool'/1 =
+ %% Line 744
+ fun (_0) ->
+ case <_0> of
+ <_x>
+ when try
+ let <_1> =
+ call 'erlang':'is_boolean'
+ (_x)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_2> when 'true' ->
+ 'error'
+ ( <_3> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_3})
+ -| [{'function_name',{'bool',1}}] )
+ -| ['compiler_generated'] )
+ end
+'my-is-bool'/1 =
+ %% Line 748
+ fun (_v) ->
+ let <_r0> =
+ <apply 'my-is-bool-a'/1
+ (_v)>
+ in case <apply 'my-is-bool-b'/1
+ (_v)> of
+ <_res>
+ when try
+ let <_0> =
+ call 'erlang':'=:='
+ (_res, _r0)
+ in _0
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ _res
+ ( <_1> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_1}})
+ -| ['compiler_generated'] )
+ end
+'my-is-bool-a'/1 =
+ %% Line 753
+ fun (_v) ->
+ case _v of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ 'true'
+ <_0> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'my-is-bool-b'/1 =
+ %% Line 759
+ fun (_v) ->
+ case _v of
+ <'false'> when 'true' ->
+ 'true'
+ <'true'> when 'true' ->
+ 'true'
+ <_0> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'is_function_2'/1 =
+ %% Line 765
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['true']]|[['is_function'|[['id'|[['function'|['lfe_guard_SUITE'|['all'|[1]]]]]]|[1]]]]]]})
+ let <_val> =
+ <let <_3> =
+ let <_2> =
+ call 'erlang':'make_fun'
+ ('lfe_guard_SUITE', 'all', 1)
+ in apply 'id'/1
+ (_2)
+ in call 'erlang':'is_function'
+ (_3, 1)>
+ in case <_val> of
+ <'true'> when 'true' ->
+ _val
+ ( <_4> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_4}})
+ -| ['compiler_generated'] )
+ end
+ ( <_17> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_17})
+ -| [{'function_name',{'is_function_2',1}}] )
+ -| ['compiler_generated'] )
+ end
+'tricky'/1 =
+ %% Line 775
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['not_ok']]|[['tricky-1'|[1|[2]]]]]]})
+ let <_val> =
+ <apply 'tricky-1'/2
+ (1, 2)>
+ in case <_val> of
+ <'not_ok'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_12> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_12})
+ -| [{'function_name',{'tricky',1}}] )
+ -| ['compiler_generated'] )
+ end
+'tricky-1'/2 =
+ %% Line 791
+ fun (_1,_0) ->
+ case <_1,_0> of
+ <_x,_y>
+ when try
+ let <_6> =
+ let <_5> =
+ let <_4> =
+ let <_2> =
+ call 'erlang':'=='
+ (_x, 1)
+ in let <_3> =
+ call 'erlang':'=='
+ (_y, 2)
+ in call 'erlang':'or'
+ (_2, _3)
+ in call 'erlang':'abs'
+ (_4)
+ in ( call 'erlang':'=:='
+ (_5, 'true')
+ -| ['compiler_generated'] )
+ in _6
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_7,_8> when 'true' ->
+ 'not_ok'
+ ( <_10,_9> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_10,_9})
+ -| [{'function_name',{'tricky-1',2}}] )
+ -| ['compiler_generated'] )
+ end
+'tricky-2'/1 =
+ %% Line 795
+ fun (_0) ->
+ case <_0> of
+ <_x>
+ when try
+ let <_3> =
+ let <_1> =
+ call 'erlang':'float'
+ (_x)
+ in let <_2> =
+ call 'erlang':'float'
+ (_x)
+ in call 'erlang':'or'
+ (_1, _2)
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_4> when 'true' ->
+ 'error'
+ ( <_5> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_5})
+ -| [{'function_name',{'tricky-2',1}}] )
+ -| ['compiler_generated'] )
+ end
+'rb'/3 =
+ %% Line 801
+ fun (_2,_1,_0) ->
+ case <_2,_1,_0> of
+ <_size,_toread,_sofar>
+ when try
+ let <_6> =
+ let <_4> =
+ let <_3> =
+ call 'erlang':'+'
+ (_sofar, _size)
+ in call 'erlang':'<'
+ (_3, 81920)
+ in let <_5> =
+ call 'erlang':'=='
+ (_toread, [])
+ in call 'erlang':'or'
+ (_4, _5)
+ in _6
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_7,_8,_9> when 'true' ->
+ 'false'
+ ( <_12,_11,_10> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_12,_11,_10})
+ -| [{'function_name',{'rb',3}}] )
+ -| ['compiler_generated'] )
+ end
+'rel_ops'/1 =
+ %% Line 830
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['T'|['=/='|[1|[1.00000000000000000000e+00]]]]})
+ case <case 1 of
+ <_2>
+ when try
+ let <_3> =
+ call 'erlang':'=/='
+ (1, 1.00000000000000000000e+00)
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_4>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <'ok'> when 'true' ->
+ case <case 1 of
+ <_5>
+ when try
+ let <_7> =
+ let <_6> =
+ call 'erlang':'=/='
+ (1, 1.00000000000000000000e+00)
+ in call 'erlang':'not'
+ (_6)
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ <_8>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <'ok'> when 'true' ->
+ let <_x,_y,_true,_false> =
+ <apply 'id'/1
+ (1),apply 'id'/1
+ (1.00000000000000000000e+00),apply 'id'/1
+ ('true'),apply 'id'/1
+ ('false')>
+ in case <case 1 of
+ <_9>
+ when try
+ let <_10> =
+ call 'erlang':'=/='
+ (_x, _y)
+ in _10
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_11>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <'ok'> when 'true' ->
+ case <case 1 of
+ <_12>
+ when try
+ let <_15> =
+ let <_14> =
+ let <_13> =
+ call 'erlang':'=/='
+ (_x, _y)
+ in call 'erlang':'or'
+ (_false, _13)
+ in call 'erlang':'or'
+ (_14, _false)
+ in _15
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_16>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <'ok'> when 'true' ->
+ case <case 1 of
+ <_17>
+ when try
+ let <_19> =
+ let <_18> =
+ call 'erlang':'=/='
+ (_x, _y)
+ in call 'erlang':'and'
+ (_18, _true)
+ in _19
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_20>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <'ok'> when 'true' ->
+ case <case 1 of
+ <_21>
+ when try
+ let <_23> =
+ let <_22> =
+ call 'erlang':'=/='
+ (_x, _y)
+ in call 'erlang':'not'
+ (_22)
+ in _23
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ <_24>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <'ok'> when 'true' ->
+ case <case 1 of
+ <_25>
+ when try
+ let <_29> =
+ let <_28> =
+ let <_27> =
+ let <_26> =
+ call 'erlang':'=/='
+ (_x, _y)
+ in call 'erlang':'not'
+ (_26)
+ in call 'erlang':'or'
+ (_false, _27)
+ in call 'erlang':'or'
+ (_28, _false)
+ in _29
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ <_30>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <'ok'> when 'true' ->
+ 'ok'
+ ( <_31> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_31}})
+ -| ['compiler_generated'] )
+ end
+ ( <_32> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_32}})
+ -| ['compiler_generated'] )
+ end
+ ( <_33> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_33}})
+ -| ['compiler_generated'] )
+ end
+ ( <_34> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_34}})
+ -| ['compiler_generated'] )
+ end
+ ( <_35> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_35}})
+ -| ['compiler_generated'] )
+ end
+ ( <_36> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_36}})
+ -| ['compiler_generated'] )
+ end
+ ( <_37> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_37}})
+ -| ['compiler_generated'] )
+ end
+ ( <_769> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_769})
+ -| [{'function_name',{'rel_ops',1}}] )
+ -| ['compiler_generated'] )
+ end
+'literal_type_tests'/1 =
+ %% Line 873
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ case 'guard_suite' of
+ <'guard_suite'> when 'true' ->
+ apply 'literal-type-tests-1'/1
+ (_config)
+ <_2> when 'true' ->
+ {'skip',[69|[110|[111|[117|[103|[104|[32|[116|[111|[32|[114|[117|[110|[32|[116|[104|[105|[115|[32|[99|[97|[115|[101|[32|[111|[110|[99|[101|[46]]]]]]]]]]]]]]]]]]]]]]]]]]]]]}
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ ( <_3> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_3})
+ -| [{'function_name',{'literal_type_tests',1}}] )
+ -| ['compiler_generated'] )
+ end
+'literal-type-tests-1'/1 =
+ %% Line 879
+ fun (_config) ->
+ 'ok'
+'basic_andalso_orelse'/1 =
+ %% Line 967
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_t> =
+ <apply 'id'/1
+ ({'type','integers',23,42})>
+ in do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[65|[['eif'|[['andalso'|[['=:='|[['element'|[1|['t']]]|[['quote'|['type']]]]]|[['=:='|[['tuple_size'|['t']]|[4]]]|[['=:='|[['element'|[2|['t']]]|[['quote'|['integers']]]]]]]]]|[['+'|[['element'|[3|['t']]]|[['element'|[4|['t']]]]]]|[['quote'|['true']]|[['quote'|['error']]]]]]]]]]})
+ let <_val> =
+ <case 1 of
+ <_2>
+ when try
+ let <_7> =
+ let <_6> =
+ case let <_3> =
+ call 'erlang':'element'
+ (1, _t)
+ in call 'erlang':'=:='
+ (_3, 'type') of
+ <'true'> when 'true' ->
+ case let <_4> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=:='
+ (_4, 4) of
+ <'true'> when 'true' ->
+ let <_5> =
+ call 'erlang':'element'
+ (2, _t)
+ in call 'erlang':'=:='
+ (_5, 'integers')
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_6, 'true')
+ -| ['compiler_generated'] )
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_8> =
+ call 'erlang':'element'
+ (3, _t)
+ in let <_9> =
+ call 'erlang':'element'
+ (4, _t)
+ in call 'erlang':'+'
+ (_8, _9)
+ <_10>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end>
+ in case <_val> of
+ <65> when 'true' ->
+ _val
+ ( <_11> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_11}})
+ -| ['compiler_generated'] )
+ end
+ ( <_47> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_47})
+ -| [{'function_name',{'basic_andalso_orelse',1}}] )
+ -| ['compiler_generated'] )
+ end
+'basic-rt'/1 =
+ %% Line 1020
+ fun (_0) ->
+ case <_0> of
+ <_t>
+ when try
+ let <_5> =
+ let <_4> =
+ case call 'erlang':'is_tuple'
+ (_t) of
+ <'true'> when 'true' ->
+ case let <_1> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=:='
+ (_1, 4) of
+ <'true'> when 'true' ->
+ case let <_2> =
+ call 'erlang':'element'
+ (1, _t)
+ in call 'erlang':'=:='
+ (_2, 'type') of
+ <'true'> when 'true' ->
+ let <_3> =
+ call 'erlang':'element'
+ (2, _t)
+ in call 'erlang':'=='
+ (_3, 'integers')
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_4, 'true')
+ -| ['compiler_generated'] )
+ in _5
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_6> =
+ call 'erlang':'element'
+ (3, _t)
+ in let <_7> =
+ call 'erlang':'element'
+ (4, _t)
+ in call 'erlang':'+'
+ (_6, _7)
+ <_t>
+ when try
+ let <_11> =
+ let <_10> =
+ case call 'erlang':'is_tuple'
+ (_t) of
+ <'true'> when 'true' ->
+ case let <_8> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=:='
+ (_8, 2) of
+ <'true'> when 'true' ->
+ let <_9> =
+ call 'erlang':'element'
+ (1, _t)
+ in call 'erlang':'=:='
+ (_9, 'vector')
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_10, 'true')
+ -| ['compiler_generated'] )
+ in _11
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ case <call 'erlang':'element'
+ (2, _t)> of
+ <{_x,_y}> when 'true' ->
+ case 1 of
+ <_12>
+ when try
+ let <_16> =
+ let <_15> =
+ let <_13> =
+ call 'erlang':'is_float'
+ (_x)
+ in let <_14> =
+ call 'erlang':'is_float'
+ (_y)
+ in call 'erlang':'and'
+ (_13, _14)
+ in ( call 'erlang':'=:='
+ (_15, 'true')
+ -| ['compiler_generated'] )
+ in _16
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_19> =
+ let <_17> =
+ call 'erlang':'*'
+ (_x, _x)
+ in let <_18> =
+ call 'erlang':'*'
+ (_y, _y)
+ in call 'erlang':'+'
+ (_17, _18)
+ in call 'math':'sqrt'
+ (_19)
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ ( <_20> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_20}})
+ -| ['compiler_generated'] )
+ end
+ <['+',_a,_b]> when 'true' ->
+ let <_22> =
+ let <_21> =
+ call 'erlang':'+'
+ (_a, _b)
+ in apply 'id'/1
+ (_21)
+ in call 'erlang':'*'
+ (_22, 2)
+ <{_r1,_r2}>
+ when try
+ let <_28> =
+ let <_27> =
+ case let <_23> =
+ call 'erlang':'size'
+ (_r1)
+ in call 'erlang':'=:='
+ (_23, 3) of
+ <'true'> when 'true' ->
+ case let <_24> =
+ call 'erlang':'element'
+ (1, _r1)
+ in call 'erlang':'=:='
+ (_24, 'Set') of
+ <'true'> when 'true' ->
+ case let <_25> =
+ call 'erlang':'size'
+ (_r2)
+ in call 'erlang':'=:='
+ (_25, 3) of
+ <'true'> when 'true' ->
+ let <_26> =
+ call 'erlang':'element'
+ (1, _r2)
+ in call 'erlang':'=:='
+ (_26, 'Set')
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_27, 'true')
+ -| ['compiler_generated'] )
+ in _28
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_r1> =
+ <apply 'id'/1
+ (_r1)>
+ in let <_r2> =
+ <apply 'id'/1
+ (_r2)>
+ in _r1
+ <_t>
+ when try
+ let <_32> =
+ let <_31> =
+ case call 'erlang':'is_tuple'
+ (_t) of
+ <'true'> when 'true' ->
+ case let <_29> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=:='
+ (_29, 2) of
+ <'true'> when 'true' ->
+ let <_30> =
+ call 'erlang':'element'
+ (1, _t)
+ in call 'erlang':'=:='
+ (_30, 'klurf')
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_31, 'true')
+ -| ['compiler_generated'] )
+ in _32
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_34> =
+ let <_33> =
+ call 'erlang':'element'
+ (2, _t)
+ in apply 'id'/1
+ (_33)
+ in call 'erlang':'*'
+ (3, _34)
+ <_35> when 'true' ->
+ 'error'
+ ( <_36> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_36})
+ -| [{'function_name',{'basic-rt',1}}] )
+ -| ['compiler_generated'] )
+ end
+'traverse_dcd'/1 =
+ %% Line 1043
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_l0> =
+ <[{'log_header','dcd_log',[49|[46|[48]]],'a','b','c'}|[{'log_header','dcd_log',[50|[46|[48]]],'a','b','c'}|[{'log_header','dcd_log',[48|[46|[48]]],'a','b','c'}|['blurf']]]]>
+ in case <apply 'traverse-dcd'/3
+ ({'cont',_l0}, 'log', 'funny')> of
+ <{'cont',[{'log_header','dcd_log',[48|[46|[48]]],'a','b','c'}|['blurf']],'log','funny'}> when 'true' ->
+ let <_l1> =
+ <[{'log_header','dcd_log',[49|[46|[48]]]}]>
+ in case <apply 'traverse-dcd'/3
+ ({'cont',_l1}, 'log', 'funny')> of
+ <{'cont',_l1,'log','funny'}> when 'true' ->
+ let <_l2> =
+ <[{'a','tuple'}]>
+ in case <apply 'traverse-dcd'/3
+ ({'cont',_l2}, 'log', 'funny')> of
+ <{'cont',_l2,'log','funny'}> when 'true' ->
+ 'ok'
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_3> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_3}})
+ -| ['compiler_generated'] )
+ end
+ ( <_4> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_4}})
+ -| ['compiler_generated'] )
+ end
+ ( <_5> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_5})
+ -| [{'function_name',{'traverse_dcd',1}}] )
+ -| ['compiler_generated'] )
+ end
+'traverse-dcd'/3 =
+ %% Line 1066
+ fun (_2,_1,_0) ->
+ case <_2,_1,_0> of
+ <{_cont,[_logh|_rest]},_log,_fun>
+ when try
+ let <_11> =
+ let <_6> =
+ case call 'erlang':'is_tuple'
+ (_logh) of
+ <'true'> when 'true' ->
+ case let <_3> =
+ call 'erlang':'tuple_size'
+ (_logh)
+ in call 'erlang':'=:='
+ (_3, 6) of
+ <'true'> when 'true' ->
+ case let <_4> =
+ call 'erlang':'element'
+ (1, _logh)
+ in call 'erlang':'=:='
+ (_4, 'log_header') of
+ <'true'> when 'true' ->
+ let <_5> =
+ call 'erlang':'element'
+ (2, _logh)
+ in call 'erlang':'=='
+ (_5, 'dcd_log')
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_6, 'true')
+ -| ['compiler_generated'] )
+ in let <_12> =
+ let <_10> =
+ case call 'erlang':'is_tuple'
+ (_logh) of
+ <'true'> when 'true' ->
+ case let <_7> =
+ call 'erlang':'tuple_size'
+ (_logh)
+ in call 'erlang':'=:='
+ (_7, 6) of
+ <'true'> when 'true' ->
+ case let <_8> =
+ call 'erlang':'element'
+ (1, _logh)
+ in call 'erlang':'=:='
+ (_8, 'log_header') of
+ <'true'> when 'true' ->
+ let <_9> =
+ call 'erlang':'element'
+ (3, _logh)
+ in call 'erlang':'>='
+ (_9, [49|[46|[48]]])
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_10, 'true')
+ -| ['compiler_generated'] )
+ in call 'erlang':'and'
+ (_11, _12)
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ apply 'traverse-dcd'/3
+ ({_cont,_rest}, _log, _fun)
+ <{_cont,_recs},_log,_fun> when 'true' ->
+ {_cont,_recs,_log,_fun}
+ ( <_15,_14,_13> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_15,_14,_13})
+ -| [{'function_name',{'traverse-dcd',3}}] )
+ -| ['compiler_generated'] )
+ end
+'check_qlc_hrl'/1 =
+ %% Line 1078
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_st> =
+ <{'r1','false','dum'}>
+ in do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['foo']]|[['cqlc'|[['quote'|['qlc']]|[['quote'|['q']]|[['quote'|[[{'lc',1,2,3}]]]|['st']]]]]]]]})
+ let <_val> =
+ <apply 'cqlc'/4
+ ('qlc', 'q', [{'lc',1,2,3}], _st)>
+ in case <_val> of
+ <'foo'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_5> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_5})
+ -| [{'function_name',{'check_qlc_hrl',1}}] )
+ -| ['compiler_generated'] )
+ end
+'cqlc'/4 =
+ %% Line 1094
+ fun (_m,_f,_as,_st) ->
+ let <_arity> =
+ <call 'erlang':'length'
+ (_as)>
+ in case _as of
+ <[{'lc',_0,_1,_2}|_3]>
+ when try
+ let <_11> =
+ call 'erlang':'=:='
+ (_m, 'qlc')
+ in let <_12> =
+ call 'erlang':'=:='
+ (_f, 'q')
+ in let <_13> =
+ call 'erlang':'<'
+ (_arity, 3)
+ in let <_14> =
+ let <_10> =
+ let <_8> =
+ case let <_4> =
+ call 'erlang':'element'
+ (1, _st)
+ in call 'erlang':'=:='
+ (_4, 'r1') of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ 'fail'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in let <_9> =
+ let <_6> =
+ let <_5> =
+ call 'erlang':'tuple_size'
+ (_st)
+ in call 'erlang':'=:='
+ (_5, 3)
+ in let <_7> =
+ call 'erlang':'element'
+ (2, _st)
+ in call 'erlang':'and'
+ (_6, _7)
+ in call 'erlang':'and'
+ (_8, _9)
+ in call 'erlang':'not'
+ (_10)
+ in let <_15> =
+ call 'erlang':'and'
+ (_11, _12)
+ in let <_16> =
+ call 'erlang':'and'
+ (_15, _13)
+ in call 'erlang':'and'
+ (_16, _14)
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'foo'
+ <_17> when 'true' ->
+ _st
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'andalso_semi'/1 =
+ %% Line 1106
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['ok']]|[['andalso-semi-foo'|[0]]]]]})
+ let <_val> =
+ <apply 'andalso-semi-foo'/1
+ (0)>
+ in case <_val> of
+ <'ok'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_8> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_8})
+ -| [{'function_name',{'andalso_semi',1}}] )
+ -| ['compiler_generated'] )
+ end
+'andalso-semi-foo'/1 =
+ %% Line 1117
+ fun (_0) ->
+ case <_0> of
+ <_bar>
+ when try
+ let <_3> =
+ let <_1> =
+ case call 'erlang':'is_integer'
+ (_bar) of
+ <'true'> when 'true' ->
+ call 'erlang':'=:='
+ (_bar, 0)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in let <_2> =
+ call 'erlang':'=:='
+ (_bar, 1)
+ in call 'erlang':'or'
+ (_1, _2)
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_4> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_4})
+ -| [{'function_name',{'andalso-semi-foo',1}}] )
+ -| ['compiler_generated'] )
+ end
+'andalso-semi-bar'/1 =
+ %% Line 1121
+ fun (_0) ->
+ case <_0> of
+ <_bar>
+ when try
+ let <_4> =
+ let <_2> =
+ case call 'erlang':'is_list'
+ (_bar) of
+ <'true'> when 'true' ->
+ let <_1> =
+ call 'erlang':'length'
+ (_bar)
+ in call 'erlang':'=:='
+ (_1, 3)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in let <_3> =
+ call 'erlang':'=:='
+ (_bar, 1)
+ in call 'erlang':'or'
+ (_2, _3)
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_5> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_5})
+ -| [{'function_name',{'andalso-semi-bar',1}}] )
+ -| ['compiler_generated'] )
+ end
+'t_tuple_size'/1 =
+ %% Line 1125
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[10|[['do-tuple-size'|[{1,2,3,4}]]]]]})
+ let <_val> =
+ <apply 'do-tuple-size'/1
+ ({1,2,3,4})>
+ in case <_val> of
+ <10> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_7> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_7})
+ -| [{'function_name',{'t_tuple_size',1}}] )
+ -| ['compiler_generated'] )
+ end
+'do-tuple-size'/1 =
+ %% Line 1139
+ fun (_0) ->
+ case <_0> of
+ <_t>
+ when try
+ let <_2> =
+ let <_1> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=:='
+ (_1, 4)
+ in _2
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ case <_t> of
+ <{_a,_b,_c,_d}> when 'true' ->
+ let <_lfe0> =
+ <_a>
+ in let <_lfe1> =
+ <_b>
+ in let <_lfe2> =
+ <_c>
+ in let <_lfe3> =
+ <_d>
+ in let <_4> =
+ let <_3> =
+ call 'erlang':'+'
+ (_lfe0, _lfe1)
+ in call 'erlang':'+'
+ (_3, _lfe2)
+ in call 'erlang':'+'
+ (_4, _lfe3)
+ ( <_5> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_5}})
+ -| ['compiler_generated'] )
+ end
+ ( <_6> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_6})
+ -| [{'function_name',{'do-tuple-size',1}}] )
+ -| ['compiler_generated'] )
+ end
+'ludicrous-tuple-size'/1 =
+ %% Line 1144
+ fun (_0) ->
+ case <_0> of
+ <_t>
+ when try
+ let <_2> =
+ let <_1> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=:='
+ (_1, 40652400101488115101757819767848575661943)
+ in _2
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_t>
+ when try
+ let <_4> =
+ let <_3> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=:='
+ (_3, 18446744073709551616)
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_t>
+ when try
+ let <_8> =
+ let <_6> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in let <_7> =
+ let <_5> =
+ call 'erlang':'bsl'
+ (1, 64)
+ in call 'erlang':'-'
+ (_5, 1)
+ in call 'erlang':'=:='
+ (_6, _7)
+ in _8
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_t>
+ when try
+ let <_10> =
+ let <_9> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=:='
+ (_9, 18446744073709551615)
+ in _10
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_11> when 'true' ->
+ 'error'
+ ( <_12> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_12})
+ -| [{'function_name',{'ludicrous-tuple-size',1}}] )
+ -| ['compiler_generated'] )
+ end
+'mask-error'/1 =
+ %% Line 1152
+ fun (_0) ->
+ case <_0> of
+ <{'EXIT',{_err,_1}}> when 'true' ->
+ _err
+ <_else> when 'true' ->
+ _else
+ ( <_2> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_2})
+ -| [{'function_name',{'mask-error',1}}] )
+ -| ['compiler_generated'] )
+ end
+'binary_part'/1 =
+ %% Line 1156
+ fun (_0) ->
+ case <_0> of
+ <'doc'> when 'true' ->
+ [84|[101|[115|[116|[115|[32|[116|[104|[101|[32|[98|[105|[110|[97|[114|[121|[95|[112|[97|[114|[116|[47|[50|[44|[51|[32|[103|[117|[97|[114|[100|[32|[40|[71|[67|[41|[32|[98|[105|[102|[39|[115]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat',1,['bp-test',#{#<1>(8,1,'integer',['unsigned'|['big']]),
+ #<2>(8,1,'integer',['unsigned'|['big']]),
+ #<3>(8,1,'integer',['unsigned'|['big']])}#]]})
+ let <_val> =
+ <apply 'bp-test'/1
+ (#{#<1>(8,1,'integer',['unsigned'|['big']]),
+ #<2>(8,1,'integer',['unsigned'|['big']]),
+ #<3>(8,1,'integer',['unsigned'|['big']])}#)>
+ in case <_val> of
+ <1> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_53> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_53})
+ -| [{'function_name',{'binary_part',1}}] )
+ -| ['compiler_generated'] )
+ end
+'bp-test'/1 =
+ %% Line 1225
+ fun (_0) ->
+ case <_0> of
+ <_b>
+ when try
+ let <_2> =
+ let <_1> =
+ call 'erlang':'length'
+ (_b)
+ in call 'erlang':'=:='
+ (_1, 137)
+ in _2
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b>
+ when try
+ let <_4> =
+ let <_3> =
+ call 'erlang':'binary_part'
+ (_b, {1,1})
+ in call 'erlang':'=:='
+ (_3, #{#<2>(8,1,'integer',['unsigned'|['big']])}#)
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b>
+ when try
+ let <_6> =
+ let <_5> =
+ call 'erlang':'binary_part'
+ (_b, 1, 1)
+ in call 'erlang':'=:='
+ (_5, #{#<1>(8,1,'integer',['unsigned'|['big']])}#)
+ in _6
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 2
+ <_b>
+ when try
+ let <_8> =
+ let <_7> =
+ call 'erlang':'binary_part'
+ (_b, {1,2})
+ in call 'erlang':'=:='
+ (_7, #{#<3>(8,1,'integer',['unsigned'|['big']]),
+ #<3>(8,1,'integer',['unsigned'|['big']])}#)
+ in _8
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 3
+ <_9> when 'true' ->
+ 'error'
+ ( <_10> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_10})
+ -| [{'function_name',{'bp-test',1}}] )
+ -| ['compiler_generated'] )
+ end
+'bp-test'/2 =
+ %% Line 1232
+ fun (_1,_0) ->
+ case <_1,_0> of
+ <_b,_a>
+ when try
+ let <_3> =
+ let <_2> =
+ call 'erlang':'length'
+ (_b)
+ in call 'erlang':'=:='
+ (_2, _a)
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b,_a>
+ when try
+ let <_5> =
+ let <_4> =
+ call 'erlang':'binary_part'
+ (_b, {_a,1})
+ in call 'erlang':'=:='
+ (_4, #{#<2>(8,1,'integer',['unsigned'|['big']])}#)
+ in _5
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b,_a>
+ when try
+ let <_7> =
+ let <_6> =
+ call 'erlang':'binary_part'
+ (_b, _a, 1)
+ in call 'erlang':'=:='
+ (_6, #{#<1>(8,1,'integer',['unsigned'|['big']])}#)
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 2
+ <_b,_a>
+ when try
+ let <_9> =
+ let <_8> =
+ call 'erlang':'binary_part'
+ (_b, {_a,2})
+ in call 'erlang':'=:='
+ (_8, #{#<3>(8,1,'integer',['unsigned'|['big']]),
+ #<3>(8,1,'integer',['unsigned'|['big']])}#)
+ in _9
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 3
+ <_10,_11> when 'true' ->
+ 'error'
+ ( <_13,_12> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_13,_12})
+ -| [{'function_name',{'bp-test',2}}] )
+ -| ['compiler_generated'] )
+ end
+'bp-test-x'/2 =
+ %% Line 1239
+ fun (_1,_0) ->
+ case <_1,_0> of
+ <_b,_a>
+ when try
+ let <_3> =
+ let <_2> =
+ call 'erlang':'length'
+ (_b)
+ in call 'erlang':'=:='
+ (_2, _a)
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b,_a>
+ when try
+ let <_5> =
+ let <_4> =
+ call 'erlang':'binary_part'
+ (_b, _a)
+ in call 'erlang':'=:='
+ (_4, #{#<2>(8,1,'integer',['unsigned'|['big']])}#)
+ in _5
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b,_a>
+ when try
+ let <_7> =
+ let <_6> =
+ call 'erlang':'binary_part'
+ (_b, _a)
+ in call 'erlang':'=:='
+ (_6, #{#<1>(8,1,'integer',['unsigned'|['big']])}#)
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 2
+ <_b,_a>
+ when try
+ let <_9> =
+ let <_8> =
+ call 'erlang':'binary_part'
+ (_b, _a)
+ in call 'erlang':'=:='
+ (_8, #{#<3>(8,1,'integer',['unsigned'|['big']]),
+ #<3>(8,1,'integer',['unsigned'|['big']])}#)
+ in _9
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 3
+ <_10,_11> when 'true' ->
+ 'error'
+ ( <_13,_12> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_13,_12})
+ -| [{'function_name',{'bp-test-x',2}}] )
+ -| ['compiler_generated'] )
+ end
+'bp-test-y'/2 =
+ %% Line 1246
+ fun (_1,_0) ->
+ case <_1,_0> of
+ <_b,_a>
+ when try
+ let <_3> =
+ let <_2> =
+ call 'erlang':'length'
+ (_b)
+ in call 'erlang':'=:='
+ (_2, _a)
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b,_a>
+ when try
+ let <_5> =
+ let <_4> =
+ call 'erlang':'binary_part'
+ (_b, {1,_a})
+ in call 'erlang':'=:='
+ (_4, #{#<2>(8,1,'integer',['unsigned'|['big']])}#)
+ in _5
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b,_a>
+ when try
+ let <_7> =
+ let <_6> =
+ call 'erlang':'binary_part'
+ (_b, 1, _a)
+ in call 'erlang':'=:='
+ (_6, #{#<1>(8,1,'integer',['unsigned'|['big']])}#)
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 2
+ <_b,_a>
+ when try
+ let <_9> =
+ let <_8> =
+ call 'erlang':'binary_part'
+ (_b, {1,_a})
+ in call 'erlang':'=:='
+ (_8, #{#<3>(8,1,'integer',['unsigned'|['big']]),
+ #<3>(8,1,'integer',['unsigned'|['big']])}#)
+ in _9
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 3
+ <_10,_11> when 'true' ->
+ 'error'
+ ( <_13,_12> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_13,_12})
+ -| [{'function_name',{'bp-test-y',2}}] )
+ -| ['compiler_generated'] )
+ end
+'bp-test'/3 =
+ %% Line 1253
+ fun (_2,_1,_0) ->
+ case <_2,_1,_0> of
+ <_b,_a,_3>
+ when try
+ let <_5> =
+ let <_4> =
+ call 'erlang':'length'
+ (_b)
+ in call 'erlang':'=:='
+ (_4, _a)
+ in _5
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b,_a,_c>
+ when try
+ let <_7> =
+ let <_6> =
+ call 'erlang':'binary_part'
+ (_b, {_a,_c})
+ in call 'erlang':'=:='
+ (_6, #{#<2>(8,1,'integer',['unsigned'|['big']])}#)
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b,_a,_c>
+ when try
+ let <_9> =
+ let <_8> =
+ call 'erlang':'binary_part'
+ (_b, _a, _c)
+ in call 'erlang':'=:='
+ (_8, #{#<1>(8,1,'integer',['unsigned'|['big']])}#)
+ in _9
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 2
+ <_b,_a,_c>
+ when try
+ let <_11> =
+ let <_10> =
+ call 'erlang':'binary_part'
+ (_b, {_a,_c})
+ in call 'erlang':'=:='
+ (_10, #{#<3>(8,1,'integer',['unsigned'|['big']]),
+ #<3>(8,1,'integer',['unsigned'|['big']])}#)
+ in _11
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 3
+ <_12,_13,_14> when 'true' ->
+ 'error'
+ ( <_17,_16,_15> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_17,_16,_15})
+ -| [{'function_name',{'bp-test',3}}] )
+ -| ['compiler_generated'] )
+ end
+'id'/1 =
+ %% Line 1262
+ fun (_i) ->
+ _i
+'check'/2 =
+ %% Line 1264
+ fun (_f,_result) ->
+ case apply _f
+ () of
+ <_r>
+ when try
+ let <_0> =
+ call 'erlang':'=:='
+ (_r, _result)
+ in _0
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_other> when 'true' ->
+ do call 'lfe_io':'format'
+ ([69|[120|[112|[101|[99|[116|[101|[100|[58|[32|[126|[112|[10]]]]]]]]]]]]], [_result])
+ do call 'lfe_io':'format'
+ ([32|[32|[32|[32|[32|[71|[111|[116|[58|[32|[126|[112|[10]]]]]]]]]]]]], [_other])
+ call 'test_server':'fail'
+ ()
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'fc'/1 =
+ %% Line 1272
+ fun (_0) ->
+ case <_0> of
+ <{'EXIT',{'function_clause'}}> when 'true' ->
+ 'ok'
+ <{'EXIT',{{'case_clause',_1},_2}}> when 'true' ->
+ 'ok'
+ ( <_3> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_3})
+ -| [{'function_name',{'fc',1}}] )
+ -| ['compiler_generated'] )
+ end
+'$handle_undefined_function'/2 =
+ %% Line 29
+ fun (_f,_as) ->
+ case let <_0> =
+ call 'lfe_env':'new'
+ ()
+ in apply 'LFE-EXPAND-EXPORTED-MACRO'/3
+ (_f, _as, _0) of
+ <{'yes',_exp}> when 'true' ->
+ call 'lfe_eval':'expr'
+ (_exp)
+ <'no'> when 'true' ->
+ let <_a,_b> =
+ <_f,_as>
+ in call 'error_handler':'raise_undef_exception'
+ ('lfe_guard_SUITE', _a, _b)
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'LFE-EXPAND-EXPORTED-MACRO'/3 =
+ %% Line 29
+ fun (_2,_1,_0) ->
+ 'no'
+'module_info'/0 =
+ fun () ->
+ call 'erlang':'get_module_info'
+ ('lfe_guard_SUITE')
+'module_info'/1 =
+ fun (_x) ->
+ call 'erlang':'get_module_info'
+ ('lfe_guard_SUITE', _x)
+end
diff --git a/lib/compiler/test/misc_SUITE.erl b/lib/compiler/test/misc_SUITE.erl
index f543f0d4de..621524114f 100644
--- a/lib/compiler/test/misc_SUITE.erl
+++ b/lib/compiler/test/misc_SUITE.erl
@@ -229,14 +229,6 @@ silly_coverage(Config) when is_list(Config) ->
{label,2}|non_proper_list]}],99},
expect_error(fun() -> beam_except:module(ExceptInput, []) end),
- %% beam_bool
- BoolInput = {?MODULE,[{foo,0}],[],
- [{function,foo,0,2,
- [{label,1},
- {func_info,{atom,?MODULE},{atom,foo},0},
- {label,2}|non_proper_list]}],99},
- expect_error(fun() -> beam_bool:module(BoolInput, []) end),
-
%% beam_dead. This is tricky. Our function must look OK to
%% beam_utils:clean_labels/1, but must crash beam_dead.
DeadInput = {?MODULE,[{foo,0}],[],
diff --git a/lib/compiler/test/record_SUITE_data/record_access_in_guards.erl b/lib/compiler/test/record_SUITE_data/record_access_in_guards.erl
index 9b72432246..dbd2419ad2 100644
--- a/lib/compiler/test/record_SUITE_data/record_access_in_guards.erl
+++ b/lib/compiler/test/record_SUITE_data/record_access_in_guards.erl
@@ -27,12 +27,12 @@
-record(r3, {a = fun(_) -> #r1{} end(1), b}).
t() ->
- foo = fun(A) when A#r1.a > A#r1.b -> foo end(#r1{b = 2}),
- 0 = fun(A) when A#r2.a -> 0 end(#r2{a = true}),
+ foo = rec_call(fun(A) when A#r1.a > A#r1.b -> foo end, #r1{b = 2}),
+ 0 = rec_call(fun(A) when A#r2.a -> 0 end, #r2{a = true}),
1 = fun(A) when (#r1{a = A})#r1.a > 2 -> 1 end(3),
2 = fun(N) when ((#r2{a = #r{a = 4}, b = length([a,b,c])})#r2.a)#r.a > N ->
- 2 end(2),
- 3 = fun(A) when (A#r2.a)#r1.a =:= 3 -> 3 end(#r2{a = #r1{a = 3}}),
+ 2 end(2),
+ 3 = rec_call(fun(A) when (A#r2.a)#r1.a =:= 3 -> 3 end, #r2{a = #r1{a = 3}}),
ok = fun() ->
F = fun(A) when record(A#r.a, r1) -> 4;
(A) when record(A#r1.a, r1) -> 5
@@ -41,9 +41,9 @@ t() ->
4 = F(#r{a = #r1{}}),
ok
end(),
- 3 = fun(A) when record(A#r1.a, r),
- (A#r1.a)#r.a > 3 -> 3
- end(#r1{a = #r{a = 4}}),
+ 3 = rec_call(fun(A) when record(A#r1.a, r),
+ (A#r1.a)#r.a > 3 -> 3
+ end, #r1{a = #r{a = 4}}),
7 = fun(A) when record(A#r3.a, r1) -> 7 end(#r3{}),
[#r1{a = 2,b = 1}] =
fun() ->
@@ -71,9 +71,10 @@ t() ->
(_) -> p
end(#r1{a = 2}),
- 3 = fun(A) when A#r1.a > 3,
- record(A, r1) -> 3
- end(#r1{a = 5}),
+ o = rec_call(fun(A) when (A#r1.a =:= 2) orelse (A#r2.a =:= 1) -> o end, #r1{a = 2}),
+ o = rec_call(fun(A) when A#r1.a =:= 2; A#r2.a =:= 1 -> o end, #r2{a = 1}),
+
+ 3 = rec_call(fun(A) when A#r1.a > 3, record(A, r1) -> 3 end, #r1{a = 5}),
ok = fun() ->
F = fun(A) when (A#r2.a =:= 1) orelse (A#r2.a) -> 2;
@@ -93,6 +94,8 @@ t() ->
(_) -> b
end(#r1{a = 1}),
+ a = rec_call(fun(A) when not (A#r.a =:= 1) or false -> a end, #r{a = 42}),
+
ok = fun() ->
F = fun(A) when not (A#r.a =:= 1) -> yes;
(_) -> no
@@ -103,14 +106,14 @@ t() ->
ok
end(),
- a = fun(A) when record(A, r),
- A#r.a =:= 1,
- A#r.b =:= 2 ->a
- end(#r{a = 1, b = 2}),
- a = fun(A) when erlang:is_record(A, r),
- A#r.a =:= 1,
- A#r.b =:= 2 -> a
- end(#r{a = 1, b = 2}),
+ a = rec_call(fun(A) when record(A, r),
+ A#r.a =:= 1,
+ A#r.b =:= 2 -> a
+ end, #r{a = 1, b = 2}),
+ a = rec_call(fun(A) when erlang:is_record(A, r),
+ A#r.a =:= 1,
+ A#r.b =:= 2 -> a
+ end, #r{a = 1, b = 2}),
a = fun(A) when is_record(A, r),
A#r.a =:= 1,
A#r.b =:= 2 -> a
@@ -144,8 +147,7 @@ t() ->
ok
end(),
- both = fun(A) when A#r.a, A#r.b -> both
- end(#r{a = true, b = true}),
+ both = rec_call(fun(A) when A#r.a, A#r.b -> both end, #r{a = true, b = true}),
ok = fun() ->
F = fun(A, B) when ((A#r1.a) orelse (B#r2.a))
@@ -176,3 +178,24 @@ t() ->
ok.
+rec_call(F, Rec) ->
+ Corrupted1 = setelement(1, Rec, wrong),
+ Corrupted2 = erlang:append_element(Rec, extra),
+ Corrupted3 = erlang:append_element(Corrupted1, extra),
+ fc(F, Corrupted1),
+ fc(F, Corrupted2),
+ fc(F, Corrupted3),
+ F(Rec).
+
+fc(F, Term) ->
+ try
+ F(Term),
+ error(expected_to_fail)
+ catch
+ error:function_clause ->
+ ok;
+ error:{case_clause,_} ->
+ Comp = ?MODULE:module_info(compile),
+ {_,Opts} = lists:keyfind(options, 1, Comp),
+ true = lists:member(inline, Opts)
+ end.