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