1: %% -*- coding: utf-8 -*-
    2: %%
    3: %% %CopyrightBegin%
    4: %% 
    5: %% Copyright Ericsson AB 1998-2013. All Rights Reserved.
    6: %% 
    7: %% The contents of this file are subject to the Erlang Public License,
    8: %% Version 1.1, (the "License"); you may not use this file except in
    9: %% compliance with the License. You should have received a copy of the
   10: %% Erlang Public License along with this software. If not, it can be
   11: %% retrieved online at http://www.erlang.org/.
   12: %% 
   13: %% Software distributed under the License is distributed on an "AS IS"
   14: %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
   15: %% the License for the specific language governing rights and limitations
   16: %% under the License.
   17: %% 
   18: %% %CopyrightEnd%
   19: 
   20: -module(erl_eval_SUITE).
   21: -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, 
   22: 	 init_per_group/2,end_per_group/2]).
   23: 
   24: -export([guard_1/1, guard_2/1,
   25: 	 match_pattern/1,
   26: 	 match_bin/1,
   27: 	 string_plusplus/1,
   28: 	 pattern_expr/1,
   29:          guard_3/1, guard_4/1,
   30:          lc/1,
   31:          simple_cases/1,
   32:          unary_plus/1,
   33:          apply_atom/1,
   34:          otp_5269/1,
   35:          otp_6539/1,
   36:          otp_6543/1,
   37:          otp_6787/1,
   38:          otp_6977/1,
   39: 	 otp_7550/1,
   40:          otp_8133/1,
   41:          otp_10622/1,
   42:          funs/1,
   43: 	 try_catch/1,
   44: 	 eval_expr_5/1,
   45: 	 zero_width/1]).
   46: 
   47: %%
   48: %% Define to run outside of test server
   49: %%
   50: %%-define(STANDALONE,1).
   51: 
   52: -import(lists,[concat/1, sort/1]).
   53: 
   54: -export([count_down/2, count_down_fun/0, do_apply/2, 
   55:          local_func/3, local_func_value/2]).
   56: 
   57: -ifdef(STANDALONE).
   58: -define(config(A,B),config(A,B)).
   59: -export([config/2]).
   60: -define(line, noop, ).
   61: config(priv_dir,_) ->
   62:     ".".
   63: -else.
   64: -include_lib("test_server/include/test_server.hrl").
   65: -export([init_per_testcase/2, end_per_testcase/2]).
   66: % Default timetrap timeout (set in init_per_testcase).
   67: -define(default_timeout, ?t:minutes(1)).
   68: init_per_testcase(_Case, Config) ->
   69:     ?line Dog = ?t:timetrap(?default_timeout),
   70:     [{watchdog, Dog} | Config].
   71: end_per_testcase(_Case, Config) ->
   72:     Dog = ?config(watchdog, Config),
   73:     test_server:timetrap_cancel(Dog),
   74:     ok.
   75: -endif.
   76: 
   77: suite() -> [{ct_hooks,[ts_install_cth]}].
   78: 
   79: all() -> 
   80:     [guard_1, guard_2, match_pattern, string_plusplus,
   81:      pattern_expr, match_bin, guard_3, guard_4, lc,
   82:      simple_cases, unary_plus, apply_atom, otp_5269,
   83:      otp_6539, otp_6543, otp_6787, otp_6977, otp_7550,
   84:      otp_8133, otp_10622, funs, try_catch, eval_expr_5, zero_width].
   85: 
   86: groups() -> 
   87:     [].
   88: 
   89: init_per_suite(Config) ->
   90:     Config.
   91: 
   92: end_per_suite(_Config) ->
   93:     ok.
   94: 
   95: init_per_group(_GroupName, Config) ->
   96:     Config.
   97: 
   98: end_per_group(_GroupName, Config) ->
   99:     Config.
  100: 
  101: guard_1(doc) ->
  102:     ["(OTP-2405)"];
  103: guard_1(suite) ->
  104:     [];
  105: guard_1(Config) when is_list(Config) ->
  106:     ?line {ok,Tokens ,_} =
  107: 	erl_scan:string("if a+4 == 4 -> yes; true -> no end. "),
  108:     ?line {ok, [Expr]} = erl_parse:parse_exprs(Tokens),
  109:     ?line no = guard_1_compiled(),
  110:     ?line {value, no, []} = erl_eval:expr(Expr, []),
  111:     ok.
  112: 
  113: guard_1_compiled() ->
  114:     if a+4 == 4 -> yes; true -> no end.
  115: 
  116: guard_2(doc) ->
  117:     ["Similar to guard_1, but type-correct"];
  118: guard_2(suite) ->
  119:     [];
  120: guard_2(Config) when is_list(Config) ->
  121:     ?line {ok,Tokens ,_} =
  122: 	erl_scan:string("if 6+4 == 4 -> yes; true -> no end. "),
  123:     ?line {ok, [Expr]} = erl_parse:parse_exprs(Tokens),
  124:     ?line no = guard_2_compiled(),
  125:     ?line {value, no, []} = erl_eval:expr(Expr, []),
  126:     ok.
  127: 
  128: guard_2_compiled() ->
  129:     if 6+4 == 4 -> yes; true -> no end.
  130: 
  131: string_plusplus(doc) ->
  132:     ["OTP-3069: syntactic sugar string ++ ..."];
  133: string_plusplus(suite) ->
  134:     [];
  135: string_plusplus(Config) when is_list(Config) ->
  136:     ?line check(fun() -> case "abc" of "ab" ++ L -> L end end,
  137: 		"case \"abc\" of \"ab\" ++ L -> L end. ",
  138: 		"c"),
  139:     ?line check(fun() -> case "abcde" of "ab" ++ "cd" ++ L -> L end end,
  140: 		"case \"abcde\" of \"ab\" ++ \"cd\" ++ L -> L end. ",
  141: 		"e"),
  142:     ?line check(fun() -> case "abc" of [97, 98] ++ L -> L end end,
  143: 		"case \"abc\" of [97, 98] ++ L -> L end. ",
  144: 		"c"),
  145:     ok.
  146: 
  147: match_pattern(doc) ->
  148:     ["OTP-2983: match operator in pattern"];
  149: match_pattern(suite) ->
  150:     [];
  151: match_pattern(Config) when is_list(Config) ->
  152:     ?line check(fun() -> case {a, b} of {a, _X}=Y -> {x,Y} end end,
  153: 		"case {a, b} of {a, X}=Y -> {x,Y} end. ",
  154: 		{x, {a, b}}),
  155:     ?line check(fun() -> case {a, b} of Y={a, _X} -> {x,Y} end end,
  156: 		"case {a, b} of Y={a, X} -> {x,Y} end. ",
  157: 		{x, {a, b}}),
  158:     ?line check(fun() -> case {a, b} of Y={a, _X}=Z -> {Z,Y} end end,
  159: 		"case {a, b} of Y={a, X}=Z -> {Z,Y} end. ",
  160: 		{{a, b}, {a, b}}),
  161:     ?line check(fun() -> A = 4, B = 28, <<13:(A+(X=B))>>, X end,
  162:                 "begin A = 4, B = 28, <<13:(A+(X=B))>>, X end.",
  163:                 28),
  164:     ok.
  165: 
  166: match_bin(doc) ->
  167:     ["binary match problems"];
  168: match_bin(suite) ->
  169:     [];
  170: match_bin(Config) when is_list(Config) ->
  171:     ?line check(fun() -> <<"abc">> = <<"abc">> end,
  172: 		"<<\"abc\">> = <<\"abc\">>. ",
  173: 		<<"abc">>),
  174:     ?line check(fun() ->
  175: 			<<Size,B:Size/binary,Rest/binary>> = <<2,"AB","CD">>,
  176: 			{Size,B,Rest}
  177: 		end,
  178: 		"begin <<Size,B:Size/binary,Rest/binary>> = <<2,\"AB\",\"CD\">>, "
  179: 		"{Size,B,Rest} end. ",
  180: 		{2,<<"AB">>,<<"CD">>}),
  181:     ok.
  182: 
  183: pattern_expr(doc) ->
  184:     ["OTP-3144: compile-time expressions in pattern"];
  185: pattern_expr(suite) ->
  186:     [];
  187: pattern_expr(Config) when is_list(Config) ->
  188:     ?line check(fun() -> case 4 of 2+2 -> ok end end,
  189: 		"case 4 of 2+2 -> ok end. ",
  190: 		ok),
  191:     ?line check(fun() -> case 2 of +2 -> ok end end,
  192: 		"case 2 of +2 -> ok end. ",
  193: 		ok),
  194:     ok.
  195: 
  196: guard_3(doc) ->
  197:     ["OTP-4518."];
  198: guard_3(suite) ->
  199:     [];
  200: guard_3(Config) when is_list(Config) ->
  201:     ?line check(fun() -> if false -> false; true -> true end end,
  202:                 "if false -> false; true -> true end.",
  203:                 true),
  204:     ?line check(fun() -> if <<"hej">> == <<"hopp">> -> true; 
  205:                             true -> false end end,
  206:                 "begin if <<\"hej\">> == <<\"hopp\">> -> true; 
  207:                           true -> false end end.",
  208:                 false),
  209:     ?line check(fun() -> if <<"hej">> == <<"hej">> -> true; 
  210:                             true -> false end end,
  211:                 "begin if <<\"hej\">> == <<\"hej\">> -> true; 
  212:                           true -> false end end.",
  213:                 true),
  214:     ok.
  215: 
  216: guard_4(doc) ->
  217:     ["OTP-4885."];
  218: guard_4(suite) ->
  219:     [];
  220: guard_4(Config) when is_list(Config) ->
  221:     check(fun() -> if erlang:'+'(3,a) -> true ; true -> false end end,
  222: 	  "if erlang:'+'(3,a) -> true ; true -> false end.",
  223: 	  false),
  224:     check(fun() -> if erlang:is_integer(3) -> true ; true -> false end
  225: 	  end,
  226: 	  "if erlang:is_integer(3) -> true ; true -> false end.",
  227: 	  true),
  228:     ?line check(fun() -> [X || X <- [1,2,3], erlang:is_integer(X)] end,
  229:                 "[X || X <- [1,2,3], erlang:is_integer(X)].",
  230:                 [1,2,3]),
  231:     ?line check(fun() -> if is_atom(is_integer(a)) -> true ; true -> false end
  232:                 end,
  233:                 "if is_atom(is_integer(a)) -> true ; true -> false end.",
  234:                 true),
  235:     check(fun() -> if erlang:is_atom(erlang:is_integer(a)) -> true;
  236: 		      true -> false end end,
  237: 	  "if erlang:is_atom(erlang:is_integer(a)) -> true; "
  238: 	  "true -> false end.",
  239: 	  true),
  240:     ?line check(fun() -> if is_atom(3+a) -> true ; true -> false end end,
  241:                 "if is_atom(3+a) -> true ; true -> false end.",
  242:                 false),
  243:     ?line check(fun() -> if erlang:is_atom(3+a) -> true ; true -> false end 
  244:                 end,
  245:                 "if erlang:is_atom(3+a) -> true ; true -> false end.",
  246:                 false),
  247:     ok.
  248: 
  249: 
  250: lc(doc) ->
  251:     ["OTP-4518."];
  252: lc(suite) ->
  253:     [];
  254: lc(Config) when is_list(Config) ->
  255:     ?line check(fun() -> X = 32, [X || X <- [1,2,3]] end,
  256:                 "begin X = 32, [X || X <- [1,2,3]] end.",
  257:                 [1,2,3]),
  258:     ?line check(fun() -> X = 32, 
  259:                          [X || <<X:X>> <- [<<1:32>>,<<2:32>>,<<3:8>>]] end,
  260:     %% "binsize variable"          ^
  261:                 "begin X = 32, 
  262:                  [X || <<X:X>> <- [<<1:32>>,<<2:32>>,<<3:8>>]] end.",
  263:                 [1,2]),
  264:     ?line check(fun() -> Y = 13,[X || {X,Y} <- [{1,2}]] end,
  265:                 "begin Y = 13,[X || {X,Y} <- [{1,2}]] end.",
  266:                 [1]),
  267:     ?line error_check("begin [A || X <- [{1,2}], 1 == A] end.",
  268:                       {unbound_var,'A'}),
  269:     ?line error_check("begin X = 32, 
  270:                         [{Y,W} || X <- [1,2,32,Y=4], Z <- [1,2,W=3]] end.",
  271:                       {unbound_var,'Y'}),
  272:     ?line error_check("begin X = 32,<<A:B>> = <<100:X>> end.",
  273:                       {unbound_var,'B'}),
  274:     ?line check(fun() -> [X || X <- [1,2,3,4], not (X < 2)] end,
  275:                 "begin [X || X <- [1,2,3,4], not (X < 2)] end.",
  276:                 [2,3,4]),
  277:     ?line check(fun() -> [X || X <- [true,false], X] end,
  278:                 "[X || X <- [true,false], X].", [true]),
  279:     ok.
  280: 
  281: simple_cases(doc) ->
  282:     ["Simple cases, just to cover some code."];
  283: simple_cases(suite) ->
  284:     [];
  285: simple_cases(Config) when is_list(Config) ->
  286:     ?line check(fun() -> A = $C end, "A = $C.", $C),
  287:     %% ?line check(fun() -> A = 3.14 end, "A = 3.14.", 3.14),
  288:     ?line check(fun() -> self() ! a, A = receive a -> true end end,
  289:                 "begin self() ! a, A = receive a -> true end end.",
  290:                 true),
  291:     ?line check(fun() -> c:flush(), self() ! a, self() ! b, self() ! c,
  292:                          receive b -> b end, 
  293:                          {messages, [a,c]} =
  294:                              erlang:process_info(self(), messages),
  295:                          c:flush() end,
  296:                 "begin c:flush(), self() ! a, self() ! b, self() ! c,"
  297:                 "receive b -> b end,"
  298:                 "{messages, [a,c]} ="
  299:                 "     erlang:process_info(self(), messages), c:flush() end.",
  300:                 ok),
  301:     ?line check(fun() -> self() ! a, A = receive a -> true 
  302:                                          after 0 -> false end end,
  303:                 "begin self() ! a, A = receive a -> true"
  304:                 "                      after 0 -> false end end.",
  305:                 true),
  306:     ?line check(fun() -> c:flush(), self() ! a, self() ! b, self() ! c,
  307:                          receive b -> b after 0 -> true end, 
  308:                          {messages, [a,c]} =
  309:                              erlang:process_info(self(), messages),
  310:                          c:flush() end,
  311:                 "begin c:flush(), self() ! a, self() ! b, self() ! c,"
  312:                 "receive b -> b after 0 -> true end,"
  313:                 "{messages, [a,c]} ="
  314:                 "     erlang:process_info(self(), messages), c:flush() end.",
  315:                 ok),
  316:     ?line check(fun() -> receive _ -> true after 10 -> false end end,
  317:                 "receive _ -> true after 10 -> false end.",
  318:                 false),
  319:     ?line check(fun() -> F = fun(A) -> A end, true = 3 == F(3) end,
  320:                 "begin F = fun(A) -> A end, true = 3 == F(3) end.",
  321:                 true),
  322:     ?line check(fun() -> F = fun(A) -> A end, true = 3 == apply(F, [3]) end,
  323:                 "begin F = fun(A) -> A end, true = 3 == apply(F,[3]) end.",
  324:                 true),
  325:     ?line check(fun() -> catch throw(a) end, "catch throw(a).", a),
  326:     ?line check(fun() -> catch a end, "catch a.", a),
  327:     ?line check(fun() -> 4 == 3 end, "4 == 3.", false),
  328:     ?line check(fun() -> not true end, "not true.", false),
  329:     ?line check(fun() -> -3 end, "-3.", -3),
  330: 
  331:     ?line error_check("3.0 = 4.0.", {badmatch,4.0}),
  332:     ?line check(fun() -> <<(3.0+2.0):32/float>> = <<5.0:32/float>> end,
  333:                 "<<(3.0+2.0):32/float>> = <<5.0:32/float>>.",
  334:                 <<5.0:32/float>>),
  335: 
  336:     ?line check(fun() -> false andalso kludd end, "false andalso kludd.",
  337:                 false),
  338:     ?line check(fun() -> true andalso true end, "true andalso true.",
  339:                 true),
  340:     ?line check(fun() -> true andalso false end, "true andalso false.",
  341:                 false),
  342:     ?line check(fun() -> true andalso kludd end, "true andalso kludd.",
  343:                 kludd),
  344:     ?line error_check("kladd andalso kludd.", {badarg,kladd}),
  345: 
  346:     ?line check(fun() -> if false andalso kludd -> a; true -> b end end,
  347:                 "if false andalso kludd -> a; true -> b end.",
  348:                 b),
  349:     ?line check(fun() -> if true andalso true -> a; true -> b end end, 
  350:                 "if true andalso true -> a; true -> b end.",
  351:                 a),
  352:     ?line check(fun() -> if true andalso false -> a; true -> b end end, 
  353:                 "if true andalso false -> a; true -> b end.",
  354:                 b),
  355: 
  356:     ?line check(fun() -> true orelse kludd end, 
  357:                 "true orelse kludd.", true),
  358:     ?line check(fun() -> false orelse false end, 
  359:                 "false orelse false.", false),
  360:     ?line check(fun() -> false orelse true end, 
  361:                 "false orelse true.", true),
  362:     ?line check(fun() -> false orelse kludd end, 
  363:                 "false orelse kludd.", kludd),
  364:     ?line error_check("kladd orelse kludd.", {badarg,kladd}),
  365:     ?line error_check("[X || X <- [1,2,3], begin 1 end].",{bad_filter,1}),
  366:     ?line error_check("[X || X <- a].",{bad_generator,a}),
  367: 
  368:     ?line check(fun() -> if true orelse kludd -> a; true -> b end end, 
  369:                 "if true orelse kludd -> a; true -> b end.", a),
  370:     ?line check(fun() -> if false orelse false -> a; true -> b end end, 
  371:                 "if false orelse false -> a; true -> b end.", b),
  372:     ?line check(fun() -> if false orelse true -> a; true -> b end end, 
  373:                 "if false orelse true -> a; true -> b end.", a),
  374: 
  375:     ?line check(fun() -> [X || X <- [1,2,3], X+2] end,
  376:                 "[X || X <- [1,2,3], X+2].", []),
  377: 
  378:     ?line check(fun() -> [X || X <- [1,2,3], [X] == [X || X <- [2]]] end,
  379:                 "[X || X <- [1,2,3], [X] == [X || X <- [2]]].",
  380:                 [2]),
  381:     ?line check(fun() -> F = fun(1) -> ett; (2) -> zwei end, 
  382:                          ett = F(1), zwei = F(2) end,
  383:                 "begin F = fun(1) -> ett; (2) -> zwei end, 
  384:                          ett = F(1), zwei = F(2) end.",
  385:                 zwei),
  386:     ?line check(fun() -> F = fun(X) when X == 1 -> ett; 
  387:                                 (X) when X == 2 -> zwei end, 
  388:                          ett = F(1), zwei = F(2) end,
  389:                 "begin F = fun(X) when X == 1 -> ett; 
  390:                               (X) when X == 2 -> zwei end, 
  391:                          ett = F(1), zwei = F(2) end.",
  392:                 zwei),
  393:     ?line error_check("begin F = fun(1) -> ett end, zwei = F(2) end.",
  394:                       function_clause),
  395:     ?line check(fun() -> if length([1]) == 1 -> yes; 
  396:                             true -> no end end,
  397:                 "if length([1]) == 1 -> yes; 
  398:                             true -> no end.",
  399:                 yes),
  400:     ?line check(fun() -> if is_integer(3) -> true; true -> false end end,
  401:                 "if is_integer(3) -> true; true -> false end.", true),
  402:     ?line check(fun() -> if integer(3) -> true; true -> false end end,
  403:                 "if integer(3) -> true; true -> false end.", true),
  404:     ?line check(fun() -> if is_float(3) -> true; true -> false end end,
  405:                 "if is_float(3) -> true; true -> false end.", false),
  406:     ?line check(fun() -> if float(3) -> true; true -> false end end,
  407:                 "if float(3) -> true; true -> false end.", false),
  408:     ?line check(fun() -> if is_number(3) -> true; true -> false end end,
  409:                 "if is_number(3) -> true; true -> false end.", true),
  410:     ?line check(fun() -> if number(3) -> true; true -> false end end,
  411:                 "if number(3) -> true; true -> false end.", true),
  412:     ?line check(fun() -> if is_atom(a) -> true; true -> false end end,
  413:                 "if is_atom(a) -> true; true -> false end.", true),
  414:     ?line check(fun() -> if atom(a) -> true; true -> false end end,
  415:                 "if atom(a) -> true; true -> false end.", true),
  416:     ?line check(fun() -> if is_list([]) -> true; true -> false end end,
  417:                 "if is_list([]) -> true; true -> false end.", true),
  418:     ?line check(fun() -> if list([]) -> true; true -> false end end,
  419:                 "if list([]) -> true; true -> false end.", true),
  420:     ?line check(fun() -> if is_tuple({}) -> true; true -> false end end,
  421:                 "if is_tuple({}) -> true; true -> false end.", true),
  422:     ?line check(fun() -> if tuple({}) -> true; true -> false end end,
  423:                 "if tuple({}) -> true; true -> false end.", true),
  424:     ?line check(fun() -> if is_pid(self()) -> true; true -> false end end,
  425:                 "if is_pid(self()) -> true; true -> false end.", true),
  426:     ?line check(fun() -> if pid(self()) -> true; true -> false end end,
  427:                 "if pid(self()) -> true; true -> false end.", true),
  428:     ?line check(fun() -> R = make_ref(), if is_reference(R) -> true; 
  429:                                             true -> false end end,
  430:                 "begin R = make_ref(), if is_reference(R) -> true;"
  431:                 "true -> false end end.", true),
  432:     ?line check(fun() -> R = make_ref(), if reference(R) -> true; 
  433:                                             true -> false end end,
  434:                 "begin R = make_ref(), if reference(R) -> true;"
  435:                 "true -> false end end.", true),
  436:     ?line check(fun() -> if is_port(a) -> true; true -> false end end,
  437:                 "if is_port(a) -> true; true -> false end.", false),
  438:     ?line check(fun() -> if port(a) -> true; true -> false end end,
  439:                 "if port(a) -> true; true -> false end.", false),
  440:     ?line check(fun() -> if is_function(a) -> true; true -> false end end,
  441:                 "if is_function(a) -> true; true -> false end.", false),
  442:     ?line check(fun() -> if function(a) -> true; true -> false end end,
  443:                 "if function(a) -> true; true -> false end.", false),
  444:     ?line check(fun() -> if is_binary(<<>>) -> true; true -> false end end,
  445:                 "if is_binary(<<>>) -> true; true -> false end.", true),
  446:     ?line check(fun() -> if binary(<<>>) -> true; true -> false end end,
  447:                 "if binary(<<>>) -> true; true -> false end.", true),
  448:     ?line check(fun() -> if is_integer(a) == true -> yes; 
  449:                             true -> no end end,
  450:                 "if is_integer(a) == true -> yes; 
  451:                             true -> no end.",
  452:                 no),
  453:     ?line check(fun() -> if [] -> true; true -> false end end,
  454:                 "if [] -> true; true -> false end.", false),
  455:     ?line error_check("if lists:member(1,[1]) -> true; true -> false end.",
  456:                       illegal_guard_expr),
  457:     ?line error_check("if false -> true end.", if_clause),
  458:     ?line check(fun() -> if a+b -> true; true -> false end end,
  459:                 "if a + b -> true; true -> false end.", false),
  460:     ?line check(fun() -> if + b -> true; true -> false end end,
  461:                 "if + b -> true; true -> false end.", false),
  462:     ?line error_check("case foo of bar -> true end.", {case_clause,foo}),
  463:     ?line error_check("case 4 of 2+a -> true; _ -> false end.", 
  464:                       illegal_pattern),
  465:     ?line error_check("case 4 of +a -> true; _ -> false end.", 
  466:                       illegal_pattern),
  467:     ?line check(fun() -> case a of 
  468:                              X when X == b -> one;
  469:                              X when X == a -> two
  470:                          end end,
  471:                 "begin case a of 
  472:                              X when X == b -> one;
  473:                              X when X == a -> two
  474:                          end end.", two),
  475:     ?line error_check("3 = 4.", {badmatch,4}),
  476:     ?line error_check("a = 3.", {badmatch,3}),
  477:     %% ?line error_check("3.1 = 2.7.",{badmatch,2.7}),
  478:     ?line error_check("$c = 4.", {badmatch,4}),
  479:     ?line check(fun() -> $c = $c end, "$c = $c.", $c),
  480:     ?line check(fun() -> _ = bar end, "_ = bar.", bar),
  481:     ?line check(fun() -> A = 14, A = 14 end, 
  482:                 "begin A = 14, A = 14 end.", 14),
  483:     ?line error_check("begin A = 14, A = 16 end.", {badmatch,16}),
  484:     ?line error_check("\"hej\" = \"san\".", {badmatch,"san"}),
  485:     ?line check(fun() -> "hej" = "hej" end,
  486:                 "\"hej\" = \"hej\".", "hej"),
  487:     ?line error_check("[] = [a].", {badmatch,[a]}),
  488:     ?line check(fun() -> [] = [] end, "[] = [].", []),
  489:     ?line error_check("[a] = [].", {badmatch,[]}),
  490:     ?line error_check("{a,b} = 34.", {badmatch,34}),
  491:     ?line check(fun() -> <<X:7>> = <<8:7>>, X end,
  492: 		"begin <<X:7>> = <<8:7>>, X end.", 8),
  493:     ?line error_check("<<34:32>> = \"hej\".", {badmatch,"hej"}),
  494:     ?line check(fun() -> trunc((1 * 3 div 3 + 4 - 3) / 1) rem 2 end,
  495:                 "begin trunc((1 * 3 div 3 + 4 - 3) / 1) rem 2 end.", 0),
  496:     ?line check(fun() -> (2#101 band 2#10101) bor (2#110 bxor 2#010) end,
  497:                 "(2#101 band 2#10101) bor (2#110 bxor 2#010).", 5),
  498:     ?line check(fun() -> (2#1 bsl 4) + (2#10000 bsr 3) end,
  499:                 "(2#1 bsl 4) + (2#10000 bsr 3).", 18),
  500:     ?line check(fun() -> ((1<3) and ((1 =:= 2) or (1 =/= 2))) xor (1=<2) end,
  501:                 "((1<3) and ((1 =:= 2) or (1 =/= 2))) xor (1=<2).", false),
  502:     ?line check(fun() -> (a /= b) or (2 > 4) or (3 >= 3) end,
  503:                 "(a /= b) or (2 > 4) or (3 >= 3).", true),
  504:     ?line check(fun() -> "hej" ++ "san" =/= "hejsan" -- "san" end,
  505:                 "\"hej\" ++ \"san\" =/= \"hejsan\" -- \"san\".", true),
  506:     ?line check(fun() -> (bnot 1) < -0 end, "(bnot (+1)) < -0.", true),
  507:     ok.
  508: 
  509: unary_plus(doc) ->
  510:     ["OTP-4929. Unary plus rejects non-numbers."];
  511: unary_plus(suite) ->
  512:     [];
  513: unary_plus(Config) when is_list(Config) ->
  514:     ?line check(fun() -> F = fun(X) -> + X end, 
  515:                          true = -1 == F(-1) end,
  516:                 "begin F = fun(X) -> + X end," 
  517:                 "      true = -1 == F(-1) end.", true, ['F'], none, none),
  518:     ?line error_check("+a.", badarith),
  519:     ok.
  520: 
  521: apply_atom(doc) ->
  522:     ["OTP-5064. Can no longer apply atoms."];
  523: apply_atom(suite) ->
  524:     [];
  525: apply_atom(Config) when is_list(Config) ->
  526:     ?line error_check("[X || X <- [[1],[2]], 
  527:                              begin L = length, L(X) =:= 1 end].", 
  528:                       {badfun,length}),
  529:     ok.
  530: 
  531: otp_5269(doc) ->
  532:     ["OTP-5269. Bugs in the bit syntax."];
  533: otp_5269(suite) ->
  534:     [];
  535: otp_5269(Config) when is_list(Config) ->
  536:     ?line check(fun() -> L = 8,
  537:                          F = fun(<<A:L,B:A>>) -> B end,
  538:                          F(<<16:8, 7:16>>)
  539:                 end,
  540:                 "begin 
  541:                    L = 8, F = fun(<<A:L,B:A>>) -> B end, F(<<16:8, 7:16>>)
  542:                  end.",
  543:                 7),
  544:     ?line check(fun() -> L = 8,
  545:                          F = fun(<<L:L,B:L>>) -> B end,
  546:                          F(<<16:8, 7:16>>)
  547:                 end,
  548:                 "begin 
  549:                    L = 8, F = fun(<<L:L,B:L>>) -> B end, F(<<16:8, 7:16>>)
  550:                  end.",
  551:                 7),
  552:     ?line check(fun() -> L = 8, <<A:L,B:A>> = <<16:8, 7:16>>, B end,
  553:                 "begin L = 8, <<A:L,B:A>> = <<16:8, 7:16>>, B end.",
  554:                 7),
  555:     ?line error_check("begin L = 8, <<L:L,B:L>> = <<16:8, 7:16>> end.",
  556:                       {badmatch,<<16:8,7:16>>}),
  557:     
  558:     ?line error_check("begin <<L:16,L:L>> = <<16:16,8:16>>, L end.",
  559:                       {badmatch, <<16:16,8:16>>}),
  560:     ?line check(fun() -> U = 8, (fun(<<U:U>>) -> U end)(<<32:8>>) end,
  561:                 "begin U = 8, (fun(<<U:U>>) -> U end)(<<32:8>>) end.",
  562:                 32),
  563:     ?line check(fun() -> U = 8, [U || <<U:U>> <- [<<32:8>>]] end,
  564:                 "begin U = 8, [U || <<U:U>> <- [<<32:8>>]] end.",
  565:                 [32]),
  566:     ?line error_check("(fun({3,<<A:32,A:32>>}) -> a end)
  567:                           ({3,<<17:32,19:32>>}).",
  568:                       function_clause),
  569:     ?line check(fun() -> [X || <<A:8,
  570:                                  B:A>> <- [<<16:8,19:16>>],
  571:                                <<X:8>> <- [<<B:8>>]] end,
  572:                 "[X || <<A:8,
  573:                                  B:A>> <- [<<16:8,19:16>>],
  574:                                <<X:8>> <- [<<B:8>>]].",
  575:                 [19]),
  576:     ?line check(fun() ->
  577: 		(fun (<<A:1/binary, B:8/integer, _C:B/binary>>) ->
  578: 			    case A of
  579: 				B -> wrong;
  580: 				_ -> ok
  581: 			    end
  582: 		 end)(<<1,2,3,4>>) end,
  583: 		"(fun(<<A:1/binary, B:8/integer, _C:B/binary>>) ->"
  584: 			    " case A of B -> wrong; _ -> ok end"
  585: 		" end)(<<1, 2, 3, 4>>).",
  586: 		ok),
  587:     ok.
  588: 
  589: otp_6539(doc) ->
  590:     ["OTP-6539. try/catch bugs."];
  591: otp_6539(suite) ->
  592:     [];
  593: otp_6539(Config) when is_list(Config) ->
  594:     ?line check(fun() -> 
  595:                         F = fun(A,B) -> 
  596:                                     try A+B 
  597:                                     catch _:_ -> dontthinkso 
  598:                                     end 
  599:                             end,
  600:                         lists:zipwith(F, [1,2], [2,3])
  601:                 end,
  602:                 "begin 
  603:                      F = fun(A,B) -> 
  604:                                  try A+B 
  605:                                  catch _:_ -> dontthinkso 
  606:                                  end 
  607:                          end,
  608:                      lists:zipwith(F, [1,2], [2,3])
  609:                  end.",
  610:                 [3, 5]),
  611:     ok.
  612: 
  613: otp_6543(doc) ->
  614:     ["OTP-6543. bitlevel binaries."];
  615: otp_6543(suite) ->
  616:     [];
  617: otp_6543(Config) when is_list(Config) ->
  618:     ?line check(fun() ->
  619:                         << <<X>> || <<X>> <- [1,2,3] >>
  620:                 end,
  621:                 "<< <<X>> || <<X>> <- [1,2,3] >>.",
  622:                 <<>>),
  623:     ?line check(fun() -> 
  624:                         << <<X>> || X <- [1,2,3] >>
  625:                 end,
  626:                 "<< <<X>> || X <- [1,2,3] >>.",
  627:                 <<1,2,3>>),
  628:     ?line check(fun() -> 
  629:                         << <<X:8>> || <<X:2>> <= <<"hej">> >>
  630:                 end,
  631:                 "<< <<X:8>> || <<X:2>> <= <<\"hej\">> >>.",
  632:                 <<1,2,2,0,1,2,1,1,1,2,2,2>>),
  633:     ?line check(fun() ->
  634:                         << <<X:8>> || 
  635:                             <<65,X:4>> <= <<65,7:4,65,3:4,66,8:4>> >>
  636:                 end,
  637:                 "<< <<X:8>> || 
  638:                             <<65,X:4>> <= <<65,7:4,65,3:4,66,8:4>> >>.",
  639:                 <<7,3>>),
  640:     ?line check(fun() -> <<34:18/big>> end,
  641:                 "<<34:18/big>>.",
  642:                 <<0,8,2:2>>),
  643:     ?line check(fun() -> <<34:18/big-unit:2>> end,
  644:                 "<<34:18/big-unit:2>>.",
  645:                 <<0,0,0,2,2:4>>),
  646:     ?line check(fun() -> <<34:18/little>> end,
  647:                 "<<34:18/little>>.",
  648:                 <<34,0,0:2>>),
  649:     ?line case eval_string("<<34:18/native>>.") of
  650:               <<0,8,2:2>> -> ok;
  651:               <<34,0,0:2>> -> ok
  652:           end,
  653:     ?line check(fun() -> <<34:18/big-signed>> end,
  654:                 "<<34:18/big-signed>>.",
  655:                 <<0,8,2:2>>),
  656:     ?line check(fun() -> <<34:18/little-signed>> end,
  657:                 "<<34:18/little-signed>>.",
  658:                 <<34,0,0:2>>),
  659:     ?line case eval_string("<<34:18/native-signed>>.") of
  660:               <<0,8,2:2>> -> ok;
  661:               <<34,0,0:2>> -> ok
  662:           end,
  663:     ?line check(fun() -> <<34:18/big-unsigned>> end,
  664:                 "<<34:18/big-unsigned>>.",
  665:                 <<0,8,2:2>>),
  666:     ?line check(fun() -> <<34:18/little-unsigned>> end,
  667:                 "<<34:18/little-unsigned>>.",
  668:                 <<34,0,0:2>>),
  669:     ?line case eval_string("<<34:18/native-unsigned>>.") of
  670:               <<0,8,2:2>> -> ok;
  671:               <<34,0,0:2>> -> ok
  672:           end,
  673:     ?line check(fun() -> <<3.14:32/float-big>> end,
  674:                 "<<3.14:32/float-big>>.",
  675:                 <<64,72,245,195>>),
  676:     ?line check(fun() -> <<3.14:32/float-little>> end,
  677:                 "<<3.14:32/float-little>>.",
  678:                 <<195,245,72,64>>),
  679:     ?line case eval_string("<<3.14:32/float-native>>.") of
  680:               <<64,72,245,195>> -> ok;
  681:               <<195,245,72,64>> -> ok
  682:           end,
  683:     ?line error_check("<<(<<17,3:2>>)/binary>>.", badarg),
  684:     ?line check(fun() -> <<(<<17,3:2>>)/bitstring>> end,
  685:                 "<<(<<17,3:2>>)/bitstring>>.",
  686:                 <<17,3:2>>),
  687:     ?line check(fun() -> <<(<<17,3:2>>):10/bitstring>> end,
  688:                 "<<(<<17,3:2>>):10/bitstring>>.",
  689:                 <<17,3:2>>),
  690:     ?line check(fun() -> <<<<344:17>>/binary-unit:17>> end,
  691: 		"<<<<344:17>>/binary-unit:17>>.",
  692: 		<<344:17>>),
  693: 
  694:     ?line check(fun() -> <<X:18/big>> = <<34:18/big>>, X end,
  695:                 "begin <<X:18/big>> = <<34:18/big>>, X end.",
  696:                 34),
  697:     ?line check(fun() -> <<X:18/big-unit:2>> = <<34:18/big-unit:2>>, X end,
  698:                 "begin <<X:18/big-unit:2>> = <<34:18/big-unit:2>>, X end.",
  699:                 34),
  700:     ?line check(fun() -> <<X:18/little>> = <<34:18/little>>, X end,
  701:                 "begin <<X:18/little>> = <<34:18/little>>, X end.",
  702:                 34),
  703:     ?line check(fun() -> <<X:18/native>> = <<34:18/native>>, X end,
  704:                 "begin <<X:18/native>> = <<34:18/native>>, X end.",
  705:                 34),
  706:     ?line check(fun() -> <<X:18/big-signed>> = <<34:18/big-signed>>, X end,
  707:                 "begin <<X:18/big-signed>> = <<34:18/big-signed>>, X end.",
  708:                 34),
  709:     ?line check(fun() -> <<X:18/little-signed>> = <<34:18/little-signed>>, 
  710:                          X end,
  711:                 "begin <<X:18/little-signed>> = <<34:18/little-signed>>, 
  712:                        X end.",
  713:                 34),
  714:     ?line check(fun() -> <<X:18/native-signed>> = <<34:18/native-signed>>, 
  715:                          X end,
  716:                 "begin <<X:18/native-signed>> = <<34:18/native-signed>>, 
  717:                        X end.",
  718:                 34),
  719:     ?line check(fun() -> <<X:18/big-unsigned>> = <<34:18/big-unsigned>>, 
  720:                          X end,
  721:                 "begin <<X:18/big-unsigned>> = <<34:18/big-unsigned>>, 
  722:                        X end.",
  723:                 34),
  724:     ?line check(fun() -> 
  725:                         <<X:18/little-unsigned>> = <<34:18/little-unsigned>>, 
  726:                         X end,
  727:                 "begin <<X:18/little-unsigned>> = <<34:18/little-unsigned>>, 
  728:                        X end.",
  729:                 34),
  730:     ?line check(fun() -> 
  731:                         <<X:18/native-unsigned>> = <<34:18/native-unsigned>>, 
  732:                         X end,
  733:                 "begin <<X:18/native-unsigned>> = <<34:18/native-unsigned>>, 
  734:                        X end.",
  735:                 34),
  736:     ?line check(fun() -> <<X:32/float-big>> = <<2.0:32/float-big>>, X end,
  737:                 "begin <<X:32/float-big>> = <<2.0:32/float-big>>, 
  738:                         X end.",
  739:                 2.0),
  740:     ?line check(fun() -> <<X:32/float-little>> = <<2.0:32/float-little>>, 
  741:                          X end,
  742:                 "begin <<X:32/float-little>> = <<2.0:32/float-little>>, 
  743:                         X end.",
  744:                 2.0),
  745:     ?line check(fun() -> <<X:32/float-native>> = <<2.0:32/float-native>>, 
  746:                          X end,
  747:                 "begin <<X:32/float-native>> = <<2.0:32/float-native>>, 
  748:                         X end.",
  749:                 2.0),
  750: 
  751:     ?line check(
  752:             fun() -> 
  753:                     [X || <<"hej",X:8>> <= <<"hej",8,"san",9,"hej",17,"hej">>]
  754:             end,
  755:             "[X || <<\"hej\",X:8>> <= 
  756:                         <<\"hej\",8,\"san\",9,\"hej\",17,\"hej\">>].",
  757:             [8,17]),
  758:     ?line check(
  759:             fun() ->
  760:                     L = 8, << <<B:32>> || <<L:L,B:L>> <= <<16:8, 7:16>> >>
  761:             end,
  762:             "begin L = 8, << <<B:32>> || <<L:L,B:L>> <= <<16:8, 7:16>> >> 
  763:              end.",
  764:             <<0,0,0,7>>),
  765:     %% Test the Value part of a binary segment. 
  766:     %% "Old" bugs have been fixed (partial_eval is called on Value).
  767:     ?line check(fun() -> [ 3 || <<17/float>> <= <<17.0/float>>] end,
  768:                 "[ 3 || <<17/float>> <= <<17.0/float>>].",
  769:                 [3]),
  770:     ?line check(fun() -> [ 3 || <<17/float>> <- [<<17.0/float>>]] end,
  771:                 "[ 3 || <<17/float>> <- [<<17.0/float>>]].",
  772:                 [3]),
  773:     ?line check(fun() -> [ X || <<17/float,X:3>> <= <<17.0/float,2:3>>] end,
  774:                 "[ X || <<17/float,X:3>> <= <<17.0/float,2:3>>].",
  775:                 [2]),
  776:     ?line check(fun() -> 
  777:                  [ foo || <<(1 bsl 1023)/float>> <= <<(1 bsl 1023)/float>>]
  778:                 end,
  779:                 "[ foo || <<(1 bsl 1023)/float>> <= <<(1 bsl 1023)/float>>].",
  780:                 [foo]),
  781:     ?line check(fun() -> 
  782:                  [ foo || <<(1 bsl 1023)/float>> <- [<<(1 bsl 1023)/float>>]]
  783:                 end,
  784:                "[ foo || <<(1 bsl 1023)/float>> <- [<<(1 bsl 1023)/float>>]].",
  785:                 [foo]),
  786:     ?line error_check("[ foo || <<(1 bsl 1024)/float>> <- 
  787:                             [<<(1 bsl 1024)/float>>]].",
  788:                       badarg),
  789:     ?line check(fun() -> 
  790:                  [ foo || <<(1 bsl 1024)/float>> <- [<<(1 bsl 1023)/float>>]]
  791:                 end,
  792:                 "[ foo || <<(1 bsl 1024)/float>> <- 
  793:                             [<<(1 bsl 1023)/float>>]].",
  794:                 []),
  795:     ?line check(fun() -> 
  796:                  [ foo || <<(1 bsl 1024)/float>> <= <<(1 bsl 1023)/float>>]
  797:                 end,
  798:                 "[ foo || <<(1 bsl 1024)/float>> <= 
  799:                             <<(1 bsl 1023)/float>>].",
  800:                 []),
  801:     ?line check(fun() ->
  802:                         L = 8, 
  803:                         [{L,B} || <<L:L,B:L/float>> <= <<32:8,7:32/float>>]
  804:                 end,
  805:                 "begin L = 8, 
  806:                        [{L,B} || <<L:L,B:L/float>> <= <<32:8,7:32/float>>]
  807:                  end.",
  808:                 [{32,7.0}]),
  809:     ?line check(fun() ->
  810:                         L = 8, 
  811:                         [{L,B} || <<L:L,B:L/float>> <- [<<32:8,7:32/float>>]]
  812:                 end,
  813:                 "begin L = 8, 
  814:                        [{L,B} || <<L:L,B:L/float>> <- [<<32:8,7:32/float>>]]
  815:                  end.",
  816:                 [{32,7.0}]),
  817:     ?line check(fun() ->
  818:                         [foo || <<"s">> <= <<"st">>]
  819:                 end,
  820:                 "[foo || <<\"s\">> <= <<\"st\">>].",
  821:                 [foo]),
  822:     ?line check(fun() -> <<_:32>> = <<17:32>> end,
  823:                 "<<_:32>> = <<17:32>>.",
  824:                 <<17:32>>),
  825:     ?line check(fun() -> [foo || <<_:32>> <= <<17:32,20:32>>] end,
  826:                 "[foo || <<_:32>> <= <<17:32,20:32>>].",
  827:                 [foo,foo]),
  828: 
  829:     ?line check(fun() -> << <<X:32>> || X <- [1,2,3], X > 1 >> end,
  830:                 "<< <<X:32>> || X <- [1,2,3], X > 1 >>.",
  831:                 <<0,0,0,2,0,0,0,3>>),
  832:     ?line error_check("[X || <<X>> <= [a,b]].",{bad_generator,[a,b]}),
  833:     ok.
  834: 
  835: otp_6787(doc) ->
  836:     ["OTP-6787. bitlevel binaries."];
  837: otp_6787(suite) ->
  838:     [];
  839: otp_6787(Config) when is_list(Config) ->
  840:     ?line check(
  841:             fun() -> <<16:(1024*1024)>> = <<16:(1024*1024)>> end,
  842:             "<<16:(1024*1024)>> = <<16:(1024*1024)>>.",
  843:             <<16:1048576>>),
  844:     ok.
  845: 
  846: otp_6977(doc) ->
  847:     ["OTP-6977. ++ bug."];
  848: otp_6977(suite) ->
  849:     [];
  850: otp_6977(Config) when is_list(Config) ->
  851:     ?line check(
  852:             fun() -> (fun([$X] ++ _) -> ok end)("X") end,
  853:             "(fun([$X] ++ _) -> ok end)(\"X\").",
  854:             ok),
  855:     ok.
  856: 
  857: otp_7550(doc) ->
  858:     ["OTP-7550. Support for UTF-8, UTF-16, UTF-32."];
  859: otp_7550(Config) when is_list(Config) ->
  860: 
  861:     %% UTF-8.
  862:     ?line check(
  863: 	    fun() -> <<65>> = <<65/utf8>> end,
  864: 	    "<<65>> = <<65/utf8>>.",
  865: 	    <<65>>),
  866:     ?line check(
  867: 	    fun() -> <<350/utf8>> = <<197,158>> end,
  868: 	    "<<350/utf8>> = <<197,158>>.",
  869: 	    <<197,158>>),
  870:     ?line check(
  871: 	    fun() -> <<$b,$j,$\303,$\266,$r,$n>> = <<"bj\366rn"/utf8>> end,
  872: 	    "<<$b,$j,$\303,$\266,$r,$n>> = <<\"bj\366rn\"/utf8>>.",
  873: 	    <<$b,$j,$\303,$\266,$r,$n>>),
  874: 
  875:     %% UTF-16.
  876:     ?line check(
  877: 	    fun() -> <<0,65>> = <<65/utf16>> end,
  878: 	    "<<0,65>> = <<65/utf16>>.",
  879: 	    <<0,65>>),
  880:     ?line check(
  881: 	    fun() -> <<16#D8,16#08,16#DF,16#45>> = <<16#12345/utf16>> end,
  882: 	    "<<16#D8,16#08,16#DF,16#45>> = <<16#12345/utf16>>.",
  883: 	    <<16#D8,16#08,16#DF,16#45>>),
  884:     ?line check(
  885: 	    fun() -> <<16#08,16#D8,16#45,16#DF>> = <<16#12345/little-utf16>> end,
  886: 	    "<<16#08,16#D8,16#45,16#DF>> = <<16#12345/little-utf16>>.",
  887: 	    <<16#08,16#D8,16#45,16#DF>>),
  888: 
  889:     ?line check(
  890: 	    fun() -> <<350/utf16>> = <<1,94>> end,
  891: 	    "<<350/utf16>> = <<1,94>>.",
  892: 	    <<1,94>>),
  893:     ?line check(
  894: 	    fun() -> <<350/little-utf16>> = <<94,1>> end,
  895: 	    "<<350/little-utf16>> = <<94,1>>.",
  896: 	    <<94,1>>),
  897:     ?line check(
  898: 	    fun() -> <<16#12345/utf16>> = <<16#D8,16#08,16#DF,16#45>> end,
  899: 	    "<<16#12345/utf16>> = <<16#D8,16#08,16#DF,16#45>>.",
  900: 	    <<16#D8,16#08,16#DF,16#45>>),
  901:     ?line check(
  902: 	    fun() -> <<16#12345/little-utf16>> = <<16#08,16#D8,16#45,16#DF>> end,
  903: 	    "<<16#12345/little-utf16>> = <<16#08,16#D8,16#45,16#DF>>.",
  904: 	    <<16#08,16#D8,16#45,16#DF>>),
  905: 
  906:     %% UTF-32.
  907:     ?line check(
  908: 	    fun() -> <<16#12345/utf32>> = <<16#0,16#01,16#23,16#45>> end,
  909: 	    "<<16#12345/utf32>> = <<16#0,16#01,16#23,16#45>>.",
  910: 	    <<16#0,16#01,16#23,16#45>>),
  911:     ?line check(
  912: 	    fun() -> <<16#0,16#01,16#23,16#45>> = <<16#12345/utf32>> end,
  913: 	    "<<16#0,16#01,16#23,16#45>> = <<16#12345/utf32>>.",
  914: 	    <<16#0,16#01,16#23,16#45>>),
  915:     ?line check(
  916: 	    fun() -> <<16#12345/little-utf32>> = <<16#45,16#23,16#01,16#00>> end,
  917: 	    "<<16#12345/little-utf32>> = <<16#45,16#23,16#01,16#00>>.",
  918: 	    <<16#45,16#23,16#01,16#00>>),
  919:     ?line check(
  920: 	    fun() -> <<16#12345/little-utf32>> end,
  921: 	    "<<16#12345/little-utf32>>.",
  922: 	    <<16#45,16#23,16#01,16#00>>),
  923: 
  924:     %% Mixed.
  925:     ?line check(
  926: 	    fun() -> <<16#41,16#12345/utf32,16#0391:16,16#2E:8>> end,
  927: 	    "<<16#41,16#12345/utf32,16#0391:16,16#2E:8>>.",
  928: 	    <<16#41,16#00,16#01,16#23,16#45,16#03,16#91,16#2E>>),
  929:     ok.
  930: 
  931: 
  932: otp_8133(doc) ->
  933:     ["OTP-8133. Bit comprehension bug."];
  934: otp_8133(suite) ->
  935:     [];
  936: otp_8133(Config) when is_list(Config) ->
  937:     ?line check(
  938:             fun() ->
  939:                   E = fun(N) -> 
  940:                               if 
  941:                                   is_integer(N) -> <<N/integer>>; 
  942:                                   true -> throw(foo) 
  943:                               end 
  944:                       end,
  945:                   try << << (E(V))/binary >> || V <- [1,2,3,a] >> 
  946:                   catch foo -> ok
  947:                   end
  948:             end,
  949:             "begin
  950:                  E = fun(N) -> 
  951:                             if is_integer(N) -> <<N/integer>>; 
  952:                                true -> throw(foo) 
  953:                             end 
  954:                      end,
  955:                  try << << (E(V))/binary >> || V <- [1,2,3,a] >> 
  956:                  catch foo -> ok
  957:                  end
  958:              end.",
  959:             ok),
  960:     ?line check(
  961:             fun() ->
  962:                   E = fun(N) -> 
  963:                               if 
  964:                                   is_integer(N) -> <<N/integer>>; 
  965: 
  966:                                   true -> erlang:error(foo) 
  967:                               end 
  968:                       end,
  969:                   try << << (E(V))/binary >> || V <- [1,2,3,a] >> 
  970:                   catch error:foo -> ok
  971:                   end
  972:             end,
  973:             "begin
  974:                  E = fun(N) -> 
  975:                             if is_integer(N) -> <<N/integer>>; 
  976:                                true -> erlang:error(foo) 
  977:                             end 
  978:                      end,
  979:                  try << << (E(V))/binary >> || V <- [1,2,3,a] >> 
  980:                  catch error:foo -> ok
  981:                  end
  982:              end.",
  983:             ok),
  984:     ok.
  985: 
  986: otp_10622(doc) ->
  987:     ["OTP-10622. Bugs."];
  988: otp_10622(suite) ->
  989:     [];
  990: otp_10622(Config) when is_list(Config) ->
  991:     check(fun() -> <<0>> = <<"\x{400}">> end,
  992:           "<<0>> = <<\"\\x{400}\">>. ",
  993:           <<0>>),
  994:     check(fun() -> <<"\x{aa}ff"/utf8>> = <<"\x{aa}ff"/utf8>> end,
  995:           "<<\"\\x{aa}ff\"/utf8>> = <<\"\\x{aa}ff\"/utf8>>. ",
  996:           <<"Â\xaaff">>),
  997:     %% The same bug as last example:
  998:     check(fun() -> case <<"foo"/utf8>> of
  999:                        <<"foo"/utf8>> -> true
 1000:                    end
 1001:           end,
 1002:           "case <<\"foo\"/utf8>> of <<\"foo\"/utf8>> -> true end.",
 1003:           true),
 1004:     check(fun() -> <<"\x{400}"/utf8>> = <<"\x{400}"/utf8>> end,
 1005:           "<<\"\\x{400}\"/utf8>> = <<\"\\x{400}\"/utf8>>. ",
 1006:           <<208,128>>),
 1007:     error_check("<<\"\\x{aaa}\">> = <<\"\\x{aaa}\">>.",
 1008:                 {badmatch,<<"\xaa">>}),
 1009: 
 1010:     check(fun() -> [a || <<"\x{aaa}">> <= <<2703:16>>] end,
 1011:           "[a || <<\"\\x{aaa}\">> <= <<2703:16>>]. ",
 1012:           []),
 1013:     check(fun() -> [a || <<"\x{aa}"/utf8>> <= <<"\x{aa}"/utf8>>] end,
 1014:           "[a || <<\"\\x{aa}\"/utf8>> <= <<\"\\x{aa}\"/utf8>>]. ",
 1015:           [a]),
 1016:     check(fun() -> [a || <<"\x{aa}x"/utf8>> <= <<"\x{aa}y"/utf8>>] end,
 1017:           "[a || <<\"\\x{aa}x\"/utf8>> <= <<\"\\x{aa}y\"/utf8>>]. ",
 1018:           []),
 1019:     check(fun() -> [a || <<"\x{aaa}">> <= <<"\x{aaa}">>] end,
 1020:           "[a || <<\"\\x{aaa}\">> <= <<\"\\x{aaa}\">>]. ",
 1021:           []),
 1022:     check(fun() -> [a || <<"\x{aaa}"/utf8>> <= <<"\x{aaa}"/utf8>>] end,
 1023:           "[a || <<\"\\x{aaa}\"/utf8>> <= <<\"\\x{aaa}\"/utf8>>]. ",
 1024:           [a]),
 1025: 
 1026:     ok.
 1027: 
 1028: funs(doc) ->
 1029:     ["Simple cases, just to cover some code."];
 1030: funs(suite) ->
 1031:     [];
 1032: funs(Config) when is_list(Config) ->
 1033:     do_funs(none, none),
 1034:     do_funs(lfh(), none),
 1035:     do_funs(lfh(), efh()),
 1036: 
 1037:     ?line error_check("nix:foo().", {access_not_allowed,nix}, lfh(), efh()),
 1038:     ?line error_check("bar().", undef, none, none),
 1039: 
 1040:     ?line check(fun() -> F1 = fun(F,N) -> ?MODULE:count_down(F, N) end,
 1041:                          F1(F1, 1000) end,
 1042:                 "begin F1 = fun(F,N) -> count_down(F, N) end,"
 1043:                 "F1(F1,1000) end.",
 1044: 		0, ['F1'], lfh(), none),
 1045: 
 1046:     ?line check(fun() -> F1 = fun(F,N) -> ?MODULE:count_down(F, N) end,
 1047:                          F1(F1, 1000) end,
 1048:                 "begin F1 = fun(F,N) -> count_down(F, N) end,"
 1049:                 "F1(F1,1000) end.",
 1050: 		0, ['F1'], lfh_value(), none),
 1051: 
 1052:     ?line check(fun() -> F1 = fun(F,N) -> ?MODULE:count_down(F, N) end,
 1053:                          F1(F1, 1000) end,
 1054:                 "begin F1 = fun(F,N) -> count_down(F, N) end,"
 1055:                 "F1(F1,1000) end.",
 1056: 		0, ['F1'], lfh_value_extra(), none),
 1057: 
 1058:     ?line check(fun() -> F1 = fun(F,N) -> ?MODULE:count_down(F, N) end,
 1059:                          F1(F1, 1000) end,
 1060:                 "begin F1 = fun(F,N) -> count_down(F, N) end,"
 1061:                 "F1(F1,1000) end.",
 1062: 		0, ['F1'], {?MODULE,local_func_value}, none),
 1063:     %% This is not documented, and only for backward compatibility (good!).
 1064:     B0 = erl_eval:new_bindings(),
 1065:     ?line check(fun() -> is_function(?MODULE:count_down_fun()) end,
 1066:                 "begin is_function(count_down_fun()) end.",
 1067:                 true, [], {?MODULE,local_func,[B0]},none),
 1068: 
 1069:     EF = fun({timer,sleep}, As) when length(As) == 1 -> exit({got_it,sleep});
 1070:             ({M,F}, As) -> apply(M, F, As)
 1071:          end,
 1072:     EFH = {value, EF},
 1073:     ?line error_check("apply(timer, sleep, [1]).", got_it, none, EFH),
 1074:     ?line error_check("begin F = fun(T) -> timer:sleep(T) end,F(1) end.",
 1075:                       got_it, none, EFH),
 1076:     ?line error_check("fun c/1.", undef),
 1077:     ?line error_check("fun a:b/0().", undef),
 1078: 
 1079:     MaxArgs = 20,
 1080:     ?line [true] = 
 1081:         lists:usort([run_many_args(SAs) || SAs <- many_args(MaxArgs)]),
 1082:     ?line {'EXIT',{{argument_limit,_},_}} = 
 1083:         (catch run_many_args(many_args1(MaxArgs+1))),
 1084: 
 1085:     ?line check(fun() -> M = lists, F = fun M:reverse/1,
 1086: 			 [1,2] = F([2,1]), ok end,
 1087: 		"begin M = lists, F = fun M:reverse/1,"
 1088: 		" [1,2] = F([2,1]), ok end.",
 1089: 		ok),
 1090: 
 1091:     %% Test that {M,F} is not accepted as a fun.
 1092:     error_check("{" ?MODULE_STRING ",module_info}().",
 1093: 		{badfun,{?MODULE,module_info}}),
 1094:     ok.
 1095: 
 1096: run_many_args({S, As}) ->
 1097:     apply(eval_string(S), As) =:= As.
 1098: 
 1099: many_args(N) ->
 1100:     [many_args1(I) || I <- lists:seq(1, N)].
 1101: 
 1102: many_args1(N) ->
 1103:     F = fun(L, P) -> 
 1104:                 tl(lists:flatten([","++P++integer_to_list(E) || E <- L]))
 1105:         end,
 1106:     L = lists:seq(1, N),
 1107:     T = F(L, "V"),
 1108:     S = lists:flatten(io_lib:format("fun(~s) -> [~s] end.", [T, T])),
 1109:     {S, L}.
 1110: 
 1111: do_funs(LFH, EFH) ->
 1112:     %% LFH is not really used by these examples...
 1113: 
 1114:     %% These tests do not prove that tail recursive functions really
 1115:     %% work (that the process does not grow); one should also run them
 1116:     %% manually with 1000 replaced by 1000000.
 1117: 
 1118:     M = atom_to_list(?MODULE),
 1119:     ?line check(fun() -> F1 = fun(F,N) -> ?MODULE:count_down(F, N) end,
 1120:                          F1(F1, 1000) end,
 1121:                 concat(["begin F1 = fun(F,N) -> ", M, 
 1122:                         ":count_down(F, N) end, F1(F1,1000) end."]),
 1123: 		0, ['F1'], LFH, EFH),
 1124:     ?line check(fun() -> F1 = fun(F,N) -> apply(?MODULE,count_down,[F,N]) 
 1125:                               end, F1(F1, 1000) end,
 1126:                 concat(["begin F1 = fun(F,N) -> apply(", M, 
 1127:                         ",count_down,[F, N]) end, F1(F1,1000) end."]),
 1128: 		0, ['F1'], LFH, EFH),
 1129:     ?line check(fun() -> F = fun(F,N) when N > 0 -> apply(F,[F,N-1]); 
 1130:                                 (_F,0) -> ok end, 
 1131:                          F(F, 1000)
 1132:                 end,
 1133:                 "begin F = fun(F,N) when N > 0 -> apply(F,[F,N-1]);"
 1134:                              "(_F,0) -> ok end,"
 1135:                        "F(F, 1000) end.",
 1136:                 ok, ['F'], LFH, EFH),
 1137:     ?line check(fun() -> F = fun(F,N) when N > 0 -> 
 1138:                                      apply(erlang,apply,[F,[F,N-1]]);
 1139:                                 (_F,0) -> ok end, 
 1140:                          F(F, 1000)
 1141:                 end,
 1142:                 "begin F = fun(F,N) when N > 0 ->"
 1143:                                    "apply(erlang,apply,[F,[F,N-1]]);"
 1144:                              "(_F,0) -> ok end,"
 1145:                        "F(F, 1000) end.",
 1146:                 ok, ['F'], LFH, EFH),
 1147:     ?line check(fun() -> F = count_down_fun(), 
 1148:                          SF = fun(SF, F1, N) -> F(SF, F1, N) end,
 1149:                          SF(SF, F, 1000) end,
 1150:                 concat(["begin F = ", M, ":count_down_fun(),"
 1151:                         "SF = fun(SF, F1, N) -> F(SF, F1, N) end,"
 1152:                         "SF(SF, F, 1000) end."]),
 1153:                 ok, ['F','SF'], LFH, EFH),
 1154: 
 1155: 
 1156:     ?line check(fun() -> F = fun(X) -> A = 1+X, {X,A} end, 
 1157:                          true = {2,3} == F(2) end,
 1158:                 "begin F = fun(X) -> A = 1+X, {X,A} end, 
 1159:                        true = {2,3} == F(2) end.", true, ['F'], LFH, EFH),
 1160:     check(fun() -> F = fun(X) -> erlang:'+'(X,2) end,
 1161: 		   true = 3 == F(1) end,
 1162: 	  "begin F = fun(X) -> erlang:'+'(X,2) end,"
 1163: 	  "      true = 3 == F(1) end.", true, ['F'],
 1164: 	  LFH, EFH),
 1165:     ?line check(fun() -> F = fun(X) -> byte_size(X) end,
 1166:                          ?MODULE:do_apply(F,<<"hej">>) end, 
 1167:                 concat(["begin F = fun(X) -> size(X) end,",
 1168:                         M,":do_apply(F,<<\"hej\">>) end."]),
 1169:                 3, ['F'], LFH, EFH),
 1170: 
 1171:     ?line check(fun() -> F1 = fun(X, Z) -> {X,Z} end,
 1172:                          Z = 5,
 1173:                          F2 = fun(X, Y) -> F1(Z,{X,Y}) end,
 1174:                          F3 = fun(X, Y) -> {a,F1(Z,{X,Y})} end,
 1175:                          {5,{x,y}} = F2(x,y), 
 1176:                          {a,{5,{y,x}}} = F3(y,x), 
 1177:                          {5,{5,y}} = F2(Z,y), 
 1178:                          true = {5,{x,5}} == F2(x,Z) end,
 1179:                 "begin F1 = fun(X, Z) -> {X,Z} end,
 1180:                        Z = 5,
 1181:                        F2 = fun(X, Y) -> F1(Z,{X,Y}) end,
 1182:                        F3 = fun(X, Y) -> {a,F1(Z,{X,Y})} end,
 1183:                        {5,{x,y}} = F2(x,y), 
 1184:                        {a,{5,{y,x}}} = F3(y,x), 
 1185:                        {5,{5,y}} = F2(Z,y), 
 1186:                        true = {5,{x,5}} == F2(x,Z) end.",
 1187:                 true, ['F1','Z','F2','F3'], LFH, EFH),
 1188:     ?line check(fun() -> F = fun(X) -> byte_size(X) end,
 1189:                          F2 = fun(Y) -> F(Y) end,
 1190:                          ?MODULE:do_apply(F2,<<"hej">>) end, 
 1191:                 concat(["begin F = fun(X) -> size(X) end,",
 1192:                         "F2 = fun(Y) -> F(Y) end,",
 1193:                         M,":do_apply(F2,<<\"hej\">>) end."]),
 1194:                 3, ['F','F2'], LFH, EFH),
 1195:     ?line check(fun() -> Z = 5, F = fun(X) -> {Z,X} end,
 1196:                          F2 = fun(Z) -> F(Z) end, F2(3) end,
 1197:                 "begin Z = 5, F = fun(X) -> {Z,X} end,
 1198:                        F2 = fun(Z) -> F(Z) end, F2(3) end.",
 1199:                 {5,3},['F','F2','Z'], LFH, EFH),
 1200:     ?line check(fun() -> F = fun(Z) -> Z end,
 1201:                          F2 = fun(X) -> F(X), Z = {X,X}, Z end,
 1202:                          {1,1} = F2(1), Z = 7, Z end,
 1203:                 "begin F = fun(Z) -> Z end,
 1204:                        F2 = fun(X) -> F(X), Z = {X,X}, Z end,
 1205:                        {1,1} = F2(1), Z = 7, Z end.", 7, ['F','F2','Z'], 
 1206:                 LFH, EFH),
 1207:     ?line check(fun() -> F = fun(F, N) -> [?MODULE:count_down(F,N) || X <-[1]]
 1208:                              end, F(F,2) end,
 1209:                 concat(["begin F = fun(F, N) -> [", M, 
 1210:                        ":count_down(F,N) || X <-[1]] end, F(F,2) end."]),
 1211:                 [[[0]]], ['F'], LFH, EFH),
 1212:     ok.
 1213: 
 1214: count_down(F, N) when N > 0 ->
 1215:     F(F, N-1);
 1216: count_down(_F, N) ->
 1217:     N.
 1218: 
 1219: count_down_fun() ->
 1220:     fun(SF,F,N) when N > 0 -> SF(SF,F,N-1);
 1221:        (_SF,_F,_N) -> ok
 1222:     end.
 1223: 
 1224: do_apply(F, V) ->
 1225:     F(V).
 1226: 
 1227: lfh() ->
 1228:     {eval, fun(F, As, Bs) -> local_func(F, As, Bs) end}.
 1229: 
 1230: local_func(F, As0, Bs0) when is_atom(F) ->
 1231:     {As,Bs} = erl_eval:expr_list(As0, Bs0, lfh()),
 1232:     case erlang:function_exported(?MODULE, F, length(As)) of
 1233: 	true ->
 1234: 	    {value,apply(?MODULE, F, As),Bs};
 1235: 	false ->
 1236: 	    {value,apply(shell_default, F, As),Bs}
 1237:     end.
 1238: 
 1239: lfh_value_extra() ->
 1240:     %% Not documented.
 1241:     {value, fun(F, As, a1, a2) -> local_func_value(F, As) end, [a1, a2]}.
 1242: 
 1243: lfh_value() ->
 1244:     {value, fun(F, As) -> local_func_value(F, As) end}.
 1245: 
 1246: local_func_value(F, As) when is_atom(F) ->
 1247:     case erlang:function_exported(?MODULE, F, length(As)) of
 1248: 	true ->
 1249: 	    apply(?MODULE, F, As);
 1250: 	false ->
 1251: 	    apply(shell_default, F, As)
 1252:     end.
 1253: 
 1254: efh() ->
 1255:     {value, fun(F, As) -> external_func(F, As) end}.
 1256: 
 1257: external_func({M,_}, _As) when M == nix ->
 1258:     exit({{access_not_allowed,M},[mfa]});
 1259: external_func(F, As) when is_function(F) ->
 1260:     apply(F, As);
 1261: external_func({M,F}, As) ->
 1262:     apply(M, F, As).
 1263: 
 1264: 
 1265: 
 1266: try_catch(doc) ->
 1267:     ["Test try-of-catch-after-end statement"];
 1268: try_catch(suite) -> 
 1269:     [];
 1270: try_catch(Config) when is_list(Config) ->
 1271:     %% Match in of with catch
 1272:     ?line check(fun() -> try 1 of 1 -> 2 catch _:_ -> 3 end end,
 1273: 		"try 1 of 1 -> 2 catch _:_ -> 3 end.", 2),
 1274:     ?line check(fun() -> try 1 of 1 -> 2; 3 -> 4 catch _:_ -> 5 end end,
 1275: 		"try 1 of 1 -> 2; 3 -> 4 catch _:_ -> 5 end.", 2),
 1276:     ?line check(fun() -> try 3 of 1 -> 2; 3 -> 4 catch _:_ -> 5 end end,
 1277: 		"try 3 of 1 -> 2; 3 -> 4 catch _:_ -> 5 end.", 4),
 1278:     %% Just after
 1279:     ?line check(fun () -> X = try 1 after put(try_catch, 2) end,
 1280: 			  {X,get(try_catch)} end,
 1281: 		"begin X = try 1 after put(try_catch, 2) end, "
 1282: 		"{X,get(try_catch)} end.", {1,2}),
 1283:     %% Match in of with after
 1284:     ?line check(fun() -> X = try 1 of 1 -> 2 after put(try_catch, 3) end,
 1285: 			 {X,get(try_catch)} end,
 1286: 		"begin X = try 1 of 1 -> 2 after put(try_catch, 3) end, "
 1287: 		"{X,get(try_catch)} end.", {2,3}),
 1288:     ?line check(fun() -> X = try 1 of 1 -> 2; 3 -> 4 
 1289: 			     after put(try_catch, 5) end,
 1290: 			 {X,get(try_catch)} end,
 1291: 		"begin X = try 1 of 1 -> 2; 3 -> 4 "
 1292: 		"          after put(try_catch, 5) end, "
 1293: 		"      {X,get(try_catch)} end.", {2,5}),
 1294:     ?line check(fun() -> X = try 3 of 1 -> 2; 3 -> 4 
 1295: 			     after put(try_catch, 5) end,
 1296: 			 {X,get(try_catch)} end,
 1297: 		"begin X = try 3 of 1 -> 2; 3 -> 4 "
 1298: 		"          after put(try_catch, 5) end, "
 1299: 		"      {X,get(try_catch)} end.", {4,5}),
 1300:     %% Nomatch in of
 1301:     ?line error_check("try 1 of 2 -> 3 catch _:_ -> 4 end.",
 1302: 		      {try_clause,1}),
 1303:     %% Nomatch in of with after
 1304:     ?line check(fun () -> {'EXIT',{{try_clause,1},_}} = 
 1305: 			      begin catch try 1 of 2 -> 3
 1306: 				          after put(try_catch, 4) end end,
 1307: 			  get(try_catch) end,
 1308: 		"begin {'EXIT',{{try_clause,1},_}} = "
 1309: 		"          begin catch try 1 of 2 -> 3 "
 1310: 		"                      after put(try_catch, 4) end end, "
 1311: 		"      get(try_catch) end. ", 4),
 1312:     %% Exception in try
 1313:     ?line check(fun () -> try 1=2 catch error:{badmatch,2} -> 3 end end,
 1314: 		"try 1=2 catch error:{badmatch,2} -> 3 end.", 3),
 1315:     ?line check(fun () -> try 1=2 of 3 -> 4 
 1316: 			  catch error:{badmatch,2} -> 5 end end,
 1317: 		"try 1=2 of 3 -> 4 "
 1318: 		"catch error:{badmatch,2} -> 5 end.", 5),
 1319:     %% Exception in try with after
 1320:     ?line check(fun () -> X = try 1=2 
 1321: 			      catch error:{badmatch,2} -> 3
 1322: 			      after put(try_catch, 4) end,
 1323: 			  {X,get(try_catch)} end,
 1324: 		"begin X = try 1=2 "
 1325: 		"          catch error:{badmatch,2} -> 3 "
 1326: 		"          after put(try_catch, 4) end, "
 1327: 		"      {X,get(try_catch)} end. ", {3,4}),
 1328:     ?line check(fun () -> X = try 1=2 of 3 -> 4
 1329: 			      catch error:{badmatch,2} -> 5
 1330: 			      after put(try_catch, 6) end,
 1331: 			  {X,get(try_catch)} end,
 1332: 		"begin X = try 1=2 of 3 -> 4"
 1333: 		"          catch error:{badmatch,2} -> 5 "
 1334: 		"          after put(try_catch, 6) end, "
 1335: 		"      {X,get(try_catch)} end. ", {5,6}),
 1336:     %% Uncaught exception
 1337:     ?line error_check("try 1=2 catch error:undefined -> 3 end. ",
 1338: 		      {badmatch,2}),
 1339:     ?line error_check("try 1=2 of 3 -> 4 catch error:undefined -> 5 end. ",
 1340: 		      {badmatch,2}),
 1341:     %% Uncaught exception with after
 1342:     ?line check(fun () -> {'EXIT',{{badmatch,2},_}} =
 1343: 			      begin catch try 1=2 
 1344: 					  after put(try_catch, 3) end end,
 1345: 			  get(try_catch) end,
 1346: 		"begin {'EXIT',{{badmatch,2},_}} = "
 1347: 		"          begin catch try 1=2 "
 1348: 		"                      after put(try_catch, 3) end end, "
 1349: 		"      get(try_catch) end. ", 3),
 1350:     ?line check(fun () -> {'EXIT',{{badmatch,2},_}} =
 1351: 			      begin catch try 1=2 of 3 -> 4
 1352: 					  after put(try_catch, 5) end end,
 1353: 			  get(try_catch) end,
 1354: 		"begin {'EXIT',{{badmatch,2},_}} = "
 1355: 		"          begin catch try 1=2 of 3 -> 4"
 1356: 		"                      after put(try_catch, 5) end end, "
 1357: 		"      get(try_catch) end. ", 5),
 1358:     ?line check(fun () -> {'EXIT',{{badmatch,2},_}} =
 1359: 			      begin catch try 1=2 catch error:undefined -> 3
 1360: 					  after put(try_catch, 4) end end,
 1361: 			  get(try_catch) end,
 1362: 		"begin {'EXIT',{{badmatch,2},_}} = "
 1363: 		"          begin catch try 1=2 catch error:undefined -> 3 "
 1364: 		"                      after put(try_catch, 4) end end, "
 1365: 		"      get(try_catch) end. ", 4),
 1366:     ?line check(fun () -> {'EXIT',{{badmatch,2},_}} =
 1367: 			      begin catch try 1=2 of 3 -> 4
 1368: 					  catch error:undefined -> 5
 1369: 					  after put(try_catch, 6) end end,
 1370: 			  get(try_catch) end,
 1371: 		"begin {'EXIT',{{badmatch,2},_}} = "
 1372: 		"          begin catch try 1=2 of 3 -> 4 "
 1373: 		"                      catch error:undefined -> 5 "
 1374: 		"                      after put(try_catch, 6) end end, "
 1375: 		"      get(try_catch) end. ", 6),
 1376:     ok.
 1377: 
 1378: 
 1379: eval_expr_5(doc) ->
 1380:     ["(OTP-7933)"];
 1381: eval_expr_5(suite) ->
 1382:     [];
 1383: eval_expr_5(Config) when is_list(Config) ->
 1384:     ?line {ok,Tokens ,_} =
 1385: 	erl_scan:string("if a+4 == 4 -> yes; true -> no end. "),
 1386:     ?line {ok, [Expr]} = erl_parse:parse_exprs(Tokens),
 1387:     ?line {value, no, []} = erl_eval:expr(Expr, [], none, none, none),
 1388:     ?line no = erl_eval:expr(Expr, [], none, none, value),
 1389:     try
 1390: 	erl_eval:expr(Expr, [], none, none, 4711),
 1391: 	?line function_clause = should_never_reach_here
 1392:     catch
 1393: 	error:function_clause ->
 1394: 	    ok
 1395:     end.
 1396: 
 1397: zero_width(Config) when is_list(Config) ->
 1398:     ?line check(fun() ->
 1399: 			{'EXIT',{badarg,_}} = (catch <<not_a_number:0>>),
 1400: 			ok
 1401: 		end, "begin {'EXIT',{badarg,_}} = (catch <<not_a_number:0>>), "
 1402: 		"ok end.", ok),
 1403:     ok.
 1404: 
 1405: %% Check the string in different contexts: as is; in fun; from compiled code.
 1406: check(F, String, Result) ->
 1407:     check1(F, String, Result),
 1408:     FunString = concat(["fun() -> ", no_final_dot(String), " end(). "]),
 1409:     check1(F, FunString, Result),
 1410:     CompileString = concat(["hd(lists:map(fun(_) -> ", no_final_dot(String), 
 1411:                             " end, [foo])). "]),
 1412:     check1(F, CompileString, Result).
 1413: 
 1414: check1(F, String, Result) ->
 1415:     Result = F(),
 1416:     case catch parse_and_run(String) of
 1417:         {value, Result, _} ->
 1418:             ok;
 1419:         Other ->
 1420:             test_server:fail({eval, Other, Result})
 1421:     end.
 1422: 
 1423: check(F, String, Result, BoundVars, LFH, EFH) ->
 1424:     Result = F(),
 1425:     case catch parse_and_run(String, LFH, EFH) of
 1426:         {value, Result, Bs} ->
 1427:             %% We just assume that Bs is an orddict...
 1428:             Keys = orddict:fetch_keys(Bs),
 1429:             case sort(BoundVars) == Keys of
 1430:                 true -> 
 1431:                     ok;
 1432:                 false -> 
 1433:                     test_server:fail({check, BoundVars, Keys})
 1434:             end,
 1435:             ok;
 1436:         Other ->
 1437:             test_server:fail({check, Other, Result})
 1438:     end.
 1439: 
 1440: error_check(String, Result) ->
 1441:     case catch parse_and_run(String) of
 1442:         {'EXIT', {Result,_}} ->
 1443:             ok;
 1444:         Other ->
 1445:             test_server:fail({eval, Other, Result})
 1446:     end.
 1447: 
 1448: error_check(String, Result, LFH, EFH) ->
 1449:     case catch parse_and_run(String, LFH, EFH) of
 1450:         {'EXIT', {Result,_}} ->
 1451:             ok;
 1452:         Other ->
 1453:             test_server:fail({eval, Other, Result})
 1454:     end.
 1455: 
 1456: eval_string(String) ->
 1457:     {value, Result, _} = parse_and_run(String),
 1458:     Result.
 1459: 
 1460: parse_and_run(String) ->
 1461:     {ok,Tokens,_} = erl_scan:string(String),
 1462:     {ok, [Expr]} = erl_parse:parse_exprs(Tokens),
 1463:     erl_eval:expr(Expr, []).
 1464: 
 1465: parse_and_run(String, LFH, EFH) ->
 1466:     {ok,Tokens,_} = erl_scan:string(String),
 1467:     {ok, [Expr]} = erl_parse:parse_exprs(Tokens),
 1468:     erl_eval:expr(Expr, [], LFH, EFH).
 1469: 
 1470: no_final_dot(S) ->
 1471:     case lists:reverse(S) of
 1472:         " ." ++ R -> lists:reverse(R);
 1473:         "." ++ R -> lists:reverse(R);
 1474:         _ -> S
 1475:     end.