4
%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
6
%% The contents of this file are subject to the Erlang Public License,
7
%% Version 1.1, (the "License"); you may not use this file except in
8
%% compliance with the License. You should have received a copy of the
9
%% Erlang Public License along with this software. If not, it can be
10
%% retrieved online at http://www.erlang.org/.
12
%% Software distributed under the License is distributed on an "AS IS"
13
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14
%% the License for the specific language governing rights and limitations
19
-module(erl_eval_SUITE).
22
-export([guard_1/1, guard_2/1,
44
%% Define to run outside of test server
46
%%-define(STANDALONE,1).
48
-import(lists,[concat/1, sort/1]).
50
-export([count_down/2, count_down_fun/0, do_apply/2,
51
local_func/3, local_func_value/2]).
54
-define(config(A,B),config(A,B)).
56
-define(line, noop, ).
60
-include("test_server.hrl").
61
-export([init_per_testcase/2, fin_per_testcase/2]).
62
% Default timetrap timeout (set in init_per_testcase).
63
-define(default_timeout, ?t:minutes(1)).
64
init_per_testcase(_Case, Config) ->
65
?line Dog = ?t:timetrap(?default_timeout),
66
[{watchdog, Dog} | Config].
67
fin_per_testcase(_Case, Config) ->
68
Dog = ?config(watchdog, Config),
69
test_server:timetrap_cancel(Dog),
74
["Test cases for the 'erl_eval' module."];
76
[guard_1, guard_2, match_pattern, string_plusplus, pattern_expr,
77
match_bin, guard_3, guard_4,
78
lc, simple_cases, unary_plus, apply_atom, otp_5269, otp_6539, otp_6543,
79
otp_6787, otp_6977, otp_7550, otp_8133, funs, try_catch, eval_expr_5].
85
guard_1(Config) when is_list(Config) ->
86
?line {ok,Tokens ,_} =
87
erl_scan:string("if a+4 == 4 -> yes; true -> no end. "),
88
?line {ok, [Expr]} = erl_parse:parse_exprs(Tokens),
89
?line no = guard_1_compiled(),
90
?line {value, no, []} = erl_eval:expr(Expr, []),
94
if a+4 == 4 -> yes; true -> no end.
97
["Similar to guard_1, but type-correct"];
100
guard_2(Config) when is_list(Config) ->
101
?line {ok,Tokens ,_} =
102
erl_scan:string("if 6+4 == 4 -> yes; true -> no end. "),
103
?line {ok, [Expr]} = erl_parse:parse_exprs(Tokens),
104
?line no = guard_2_compiled(),
105
?line {value, no, []} = erl_eval:expr(Expr, []),
108
guard_2_compiled() ->
109
if 6+4 == 4 -> yes; true -> no end.
111
string_plusplus(doc) ->
112
["OTP-3069: syntactic sugar string ++ ..."];
113
string_plusplus(suite) ->
115
string_plusplus(Config) when is_list(Config) ->
116
?line check(fun() -> case "abc" of "ab" ++ L -> L end end,
117
"case \"abc\" of \"ab\" ++ L -> L end. ",
119
?line check(fun() -> case "abcde" of "ab" ++ "cd" ++ L -> L end end,
120
"case \"abcde\" of \"ab\" ++ \"cd\" ++ L -> L end. ",
122
?line check(fun() -> case "abc" of [97, 98] ++ L -> L end end,
123
"case \"abc\" of [97, 98] ++ L -> L end. ",
127
match_pattern(doc) ->
128
["OTP-2983: match operator in pattern"];
129
match_pattern(suite) ->
131
match_pattern(Config) when is_list(Config) ->
132
?line check(fun() -> case {a, b} of {a, _X}=Y -> {x,Y} end end,
133
"case {a, b} of {a, X}=Y -> {x,Y} end. ",
135
?line check(fun() -> case {a, b} of Y={a, _X} -> {x,Y} end end,
136
"case {a, b} of Y={a, X} -> {x,Y} end. ",
138
?line check(fun() -> case {a, b} of Y={a, _X}=Z -> {Z,Y} end end,
139
"case {a, b} of Y={a, X}=Z -> {Z,Y} end. ",
141
?line check(fun() -> A = 4, B = 28, <<13:(A+(X=B))>>, X end,
142
"begin A = 4, B = 28, <<13:(A+(X=B))>>, X end.",
147
["binary match problems"];
150
match_bin(Config) when is_list(Config) ->
151
?line check(fun() -> <<"abc">> = <<"abc">> end,
152
"<<\"abc\">> = <<\"abc\">>. ",
155
<<Size,B:Size/binary,Rest/binary>> = <<2,"AB","CD">>,
158
"begin <<Size,B:Size/binary,Rest/binary>> = <<2,\"AB\",\"CD\">>, "
159
"{Size,B,Rest} end. ",
160
{2,<<"AB">>,<<"CD">>}),
164
["OTP-3144: compile-time expressions in pattern"];
165
pattern_expr(suite) ->
167
pattern_expr(Config) when is_list(Config) ->
168
?line check(fun() -> case 4 of 2+2 -> ok end end,
169
"case 4 of 2+2 -> ok end. ",
171
?line check(fun() -> case 2 of +2 -> ok end end,
172
"case 2 of +2 -> ok end. ",
180
guard_3(Config) when is_list(Config) ->
181
?line check(fun() -> if false -> false; true -> true end end,
182
"if false -> false; true -> true end.",
184
?line check(fun() -> if <<"hej">> == <<"hopp">> -> true;
185
true -> false end end,
186
"begin if <<\"hej\">> == <<\"hopp\">> -> true;
187
true -> false end end.",
189
?line check(fun() -> if <<"hej">> == <<"hej">> -> true;
190
true -> false end end,
191
"begin if <<\"hej\">> == <<\"hej\">> -> true;
192
true -> false end end.",
200
guard_4(Config) when is_list(Config) ->
201
?line check(fun() -> if {erlang,'+'}(3,a) -> true ; true -> false end end,
202
"if {erlang,'+'}(3,a) -> true ; true -> false end.",
204
?line check(fun() -> if {erlang,is_integer}(3) -> true ; true -> false end
206
"if {erlang,is_integer}(3) -> true ; true -> false end.",
208
?line check(fun() -> [X || X <- [1,2,3], erlang:is_integer(X)] end,
209
"[X || X <- [1,2,3], erlang:is_integer(X)].",
211
?line check(fun() -> if is_atom(is_integer(a)) -> true ; true -> false end
213
"if is_atom(is_integer(a)) -> true ; true -> false end.",
215
?line check(fun() -> if {erlang,is_atom}({erlang,is_integer}(a)) -> true;
216
true -> false end end,
217
"if {erlang,is_atom}({erlang,is_integer}(a)) -> true; "
218
"true -> false end.",
220
?line check(fun() -> if is_atom(3+a) -> true ; true -> false end end,
221
"if is_atom(3+a) -> true ; true -> false end.",
223
?line check(fun() -> if erlang:is_atom(3+a) -> true ; true -> false end
225
"if erlang:is_atom(3+a) -> true ; true -> false end.",
234
lc(Config) when is_list(Config) ->
235
?line check(fun() -> X = 32, [X || X <- [1,2,3]] end,
236
"begin X = 32, [X || X <- [1,2,3]] end.",
238
?line check(fun() -> X = 32,
239
[X || <<X:X>> <- [<<1:32>>,<<2:32>>,<<3:8>>]] end,
240
%% "binsize variable" ^
242
[X || <<X:X>> <- [<<1:32>>,<<2:32>>,<<3:8>>]] end.",
244
?line check(fun() -> Y = 13,[X || {X,Y} <- [{1,2}]] end,
245
"begin Y = 13,[X || {X,Y} <- [{1,2}]] end.",
247
?line error_check("begin [A || X <- [{1,2}], 1 == A] end.",
249
?line error_check("begin X = 32,
250
[{Y,W} || X <- [1,2,32,Y=4], Z <- [1,2,W=3]] end.",
252
?line error_check("begin X = 32,<<A:B>> = <<100:X>> end.",
254
?line check(fun() -> [X || X <- [1,2,3,4], not (X < 2)] end,
255
"begin [X || X <- [1,2,3,4], not (X < 2)] end.",
257
?line check(fun() -> [X || X <- [true,false], X] end,
258
"[X || X <- [true,false], X].", [true]),
262
["Simple cases, just to cover some code."];
263
simple_cases(suite) ->
265
simple_cases(Config) when is_list(Config) ->
266
?line check(fun() -> A = $C end, "A = $C.", $C),
267
%% ?line check(fun() -> A = 3.14 end, "A = 3.14.", 3.14),
268
?line check(fun() -> self() ! a, A = receive a -> true end end,
269
"begin self() ! a, A = receive a -> true end end.",
271
?line check(fun() -> c:flush(), self() ! a, self() ! b, self() ! c,
274
erlang:process_info(self(), messages),
276
"begin c:flush(), self() ! a, self() ! b, self() ! c,"
277
"receive b -> b end,"
278
"{messages, [a,c]} ="
279
" erlang:process_info(self(), messages), c:flush() end.",
281
?line check(fun() -> self() ! a, A = receive a -> true
282
after 0 -> false end end,
283
"begin self() ! a, A = receive a -> true"
284
" after 0 -> false end end.",
286
?line check(fun() -> c:flush(), self() ! a, self() ! b, self() ! c,
287
receive b -> b after 0 -> true end,
289
erlang:process_info(self(), messages),
291
"begin c:flush(), self() ! a, self() ! b, self() ! c,"
292
"receive b -> b after 0 -> true end,"
293
"{messages, [a,c]} ="
294
" erlang:process_info(self(), messages), c:flush() end.",
296
?line check(fun() -> receive _ -> true after 10 -> false end end,
297
"receive _ -> true after 10 -> false end.",
299
?line check(fun() -> F = fun(A) -> A end, true = 3 == F(3) end,
300
"begin F = fun(A) -> A end, true = 3 == F(3) end.",
302
?line check(fun() -> F = fun(A) -> A end, true = 3 == apply(F, [3]) end,
303
"begin F = fun(A) -> A end, true = 3 == apply(F,[3]) end.",
305
?line check(fun() -> catch throw(a) end, "catch throw(a).", a),
306
?line check(fun() -> catch a end, "catch a.", a),
307
?line check(fun() -> 4 == 3 end, "4 == 3.", false),
308
?line check(fun() -> not true end, "not true.", false),
309
?line check(fun() -> -3 end, "-3.", -3),
311
?line error_check("3.0 = 4.0.", {badmatch,4.0}),
312
?line check(fun() -> <<(3.0+2.0):32/float>> = <<5.0:32/float>> end,
313
"<<(3.0+2.0):32/float>> = <<5.0:32/float>>.",
316
?line check(fun() -> false andalso kludd end, "false andalso kludd.",
318
?line check(fun() -> true andalso true end, "true andalso true.",
320
?line check(fun() -> true andalso false end, "true andalso false.",
322
?line check(fun() -> true andalso kludd end, "true andalso kludd.",
324
?line error_check("kladd andalso kludd.", {badarg,kladd}),
326
?line check(fun() -> if false andalso kludd -> a; true -> b end end,
327
"if false andalso kludd -> a; true -> b end.",
329
?line check(fun() -> if true andalso true -> a; true -> b end end,
330
"if true andalso true -> a; true -> b end.",
332
?line check(fun() -> if true andalso false -> a; true -> b end end,
333
"if true andalso false -> a; true -> b end.",
336
?line check(fun() -> true orelse kludd end,
337
"true orelse kludd.", true),
338
?line check(fun() -> false orelse false end,
339
"false orelse false.", false),
340
?line check(fun() -> false orelse true end,
341
"false orelse true.", true),
342
?line check(fun() -> false orelse kludd end,
343
"false orelse kludd.", kludd),
344
?line error_check("kladd orelse kludd.", {badarg,kladd}),
345
?line error_check("[X || X <- [1,2,3], begin 1 end].",{bad_filter,1}),
346
?line error_check("[X || X <- a].",{bad_generator,a}),
348
?line check(fun() -> if true orelse kludd -> a; true -> b end end,
349
"if true orelse kludd -> a; true -> b end.", a),
350
?line check(fun() -> if false orelse false -> a; true -> b end end,
351
"if false orelse false -> a; true -> b end.", b),
352
?line check(fun() -> if false orelse true -> a; true -> b end end,
353
"if false orelse true -> a; true -> b end.", a),
355
?line check(fun() -> [X || X <- [1,2,3], X+2] end,
356
"[X || X <- [1,2,3], X+2].", []),
358
?line check(fun() -> [X || X <- [1,2,3], [X] == [X || X <- [2]]] end,
359
"[X || X <- [1,2,3], [X] == [X || X <- [2]]].",
361
?line check(fun() -> F = fun(1) -> ett; (2) -> zwei end,
362
ett = F(1), zwei = F(2) end,
363
"begin F = fun(1) -> ett; (2) -> zwei end,
364
ett = F(1), zwei = F(2) end.",
366
?line check(fun() -> F = fun(X) when X == 1 -> ett;
367
(X) when X == 2 -> zwei end,
368
ett = F(1), zwei = F(2) end,
369
"begin F = fun(X) when X == 1 -> ett;
370
(X) when X == 2 -> zwei end,
371
ett = F(1), zwei = F(2) end.",
373
?line error_check("begin F = fun(1) -> ett end, zwei = F(2) end.",
375
?line check(fun() -> if length([1]) == 1 -> yes;
377
"if length([1]) == 1 -> yes;
380
?line check(fun() -> if is_integer(3) -> true; true -> false end end,
381
"if is_integer(3) -> true; true -> false end.", true),
382
?line check(fun() -> if integer(3) -> true; true -> false end end,
383
"if integer(3) -> true; true -> false end.", true),
384
?line check(fun() -> if is_float(3) -> true; true -> false end end,
385
"if is_float(3) -> true; true -> false end.", false),
386
?line check(fun() -> if float(3) -> true; true -> false end end,
387
"if float(3) -> true; true -> false end.", false),
388
?line check(fun() -> if is_number(3) -> true; true -> false end end,
389
"if is_number(3) -> true; true -> false end.", true),
390
?line check(fun() -> if number(3) -> true; true -> false end end,
391
"if number(3) -> true; true -> false end.", true),
392
?line check(fun() -> if is_atom(a) -> true; true -> false end end,
393
"if is_atom(a) -> true; true -> false end.", true),
394
?line check(fun() -> if atom(a) -> true; true -> false end end,
395
"if atom(a) -> true; true -> false end.", true),
396
?line check(fun() -> if is_list([]) -> true; true -> false end end,
397
"if is_list([]) -> true; true -> false end.", true),
398
?line check(fun() -> if list([]) -> true; true -> false end end,
399
"if list([]) -> true; true -> false end.", true),
400
?line check(fun() -> if is_tuple({}) -> true; true -> false end end,
401
"if is_tuple({}) -> true; true -> false end.", true),
402
?line check(fun() -> if tuple({}) -> true; true -> false end end,
403
"if tuple({}) -> true; true -> false end.", true),
404
?line check(fun() -> if is_pid(self()) -> true; true -> false end end,
405
"if is_pid(self()) -> true; true -> false end.", true),
406
?line check(fun() -> if pid(self()) -> true; true -> false end end,
407
"if pid(self()) -> true; true -> false end.", true),
408
?line check(fun() -> R = make_ref(), if is_reference(R) -> true;
409
true -> false end end,
410
"begin R = make_ref(), if is_reference(R) -> true;"
411
"true -> false end end.", true),
412
?line check(fun() -> R = make_ref(), if reference(R) -> true;
413
true -> false end end,
414
"begin R = make_ref(), if reference(R) -> true;"
415
"true -> false end end.", true),
416
?line check(fun() -> if is_port(a) -> true; true -> false end end,
417
"if is_port(a) -> true; true -> false end.", false),
418
?line check(fun() -> if port(a) -> true; true -> false end end,
419
"if port(a) -> true; true -> false end.", false),
420
?line check(fun() -> if is_function(a) -> true; true -> false end end,
421
"if is_function(a) -> true; true -> false end.", false),
422
?line check(fun() -> if function(a) -> true; true -> false end end,
423
"if function(a) -> true; true -> false end.", false),
424
?line check(fun() -> if is_binary(<<>>) -> true; true -> false end end,
425
"if is_binary(<<>>) -> true; true -> false end.", true),
426
?line check(fun() -> if binary(<<>>) -> true; true -> false end end,
427
"if binary(<<>>) -> true; true -> false end.", true),
428
?line check(fun() -> if is_integer(a) == true -> yes;
430
"if is_integer(a) == true -> yes;
433
?line check(fun() -> if [] -> true; true -> false end end,
434
"if [] -> true; true -> false end.", false),
435
?line error_check("if lists:member(1,[1]) -> true; true -> false end.",
437
?line error_check("if false -> true end.", if_clause),
438
?line check(fun() -> if a+b -> true; true -> false end end,
439
"if a + b -> true; true -> false end.", false),
440
?line check(fun() -> if + b -> true; true -> false end end,
441
"if + b -> true; true -> false end.", false),
442
?line error_check("case foo of bar -> true end.", {case_clause,foo}),
443
?line error_check("case 4 of 2+a -> true; _ -> false end.",
445
?line error_check("case 4 of +a -> true; _ -> false end.",
447
?line check(fun() -> case a of
448
X when X == b -> one;
452
X when X == b -> one;
455
?line error_check("3 = 4.", {badmatch,4}),
456
?line error_check("a = 3.", {badmatch,3}),
457
%% ?line error_check("3.1 = 2.7.",{badmatch,2.7}),
458
?line error_check("$c = 4.", {badmatch,4}),
459
?line check(fun() -> $c = $c end, "$c = $c.", $c),
460
?line check(fun() -> _ = bar end, "_ = bar.", bar),
461
?line check(fun() -> A = 14, A = 14 end,
462
"begin A = 14, A = 14 end.", 14),
463
?line error_check("begin A = 14, A = 16 end.", {badmatch,16}),
464
?line error_check("\"hej\" = \"san\".", {badmatch,"san"}),
465
?line check(fun() -> "hej" = "hej" end,
466
"\"hej\" = \"hej\".", "hej"),
467
?line error_check("[] = [a].", {badmatch,[a]}),
468
?line check(fun() -> [] = [] end, "[] = [].", []),
469
?line error_check("[a] = [].", {badmatch,[]}),
470
?line error_check("{a,b} = 34.", {badmatch,34}),
471
?line check(fun() -> <<X:7>> = <<8:7>>, X end,
472
"begin <<X:7>> = <<8:7>>, X end.", 8),
473
?line error_check("<<34:32>> = \"hej\".", {badmatch,"hej"}),
474
?line check(fun() -> trunc((1 * 3 div 3 + 4 - 3) / 1) rem 2 end,
475
"begin trunc((1 * 3 div 3 + 4 - 3) / 1) rem 2 end.", 0),
476
?line check(fun() -> (2#101 band 2#10101) bor (2#110 bxor 2#010) end,
477
"(2#101 band 2#10101) bor (2#110 bxor 2#010).", 5),
478
?line check(fun() -> (2#1 bsl 4) + (2#10000 bsr 3) end,
479
"(2#1 bsl 4) + (2#10000 bsr 3).", 18),
480
?line check(fun() -> ((1<3) and ((1 =:= 2) or (1 =/= 2))) xor (1=<2) end,
481
"((1<3) and ((1 =:= 2) or (1 =/= 2))) xor (1=<2).", false),
482
?line check(fun() -> (a /= b) or (2 > 4) or (3 >= 3) end,
483
"(a /= b) or (2 > 4) or (3 >= 3).", true),
484
?line check(fun() -> "hej" ++ "san" =/= "hejsan" -- "san" end,
485
"\"hej\" ++ \"san\" =/= \"hejsan\" -- \"san\".", true),
486
?line check(fun() -> (bnot 1) < -0 end, "(bnot (+1)) < -0.", true),
490
["OTP-4929. Unary plus rejects non-numbers."];
493
unary_plus(Config) when is_list(Config) ->
494
?line check(fun() -> F = fun(X) -> + X end,
495
true = -1 == F(-1) end,
496
"begin F = fun(X) -> + X end,"
497
" true = -1 == F(-1) end.", true, ['F'], none, none),
498
?line error_check("+a.", badarith),
502
["OTP-5064. Can no longer apply atoms."];
505
apply_atom(Config) when is_list(Config) ->
506
?line error_check("[X || X <- [[1],[2]],
507
begin L = length, L(X) =:= 1 end].",
512
["OTP-5269. Bugs in the bit syntax."];
515
otp_5269(Config) when is_list(Config) ->
516
?line check(fun() -> L = 8,
517
F = fun(<<A:L,B:A>>) -> B end,
521
L = 8, F = fun(<<A:L,B:A>>) -> B end, F(<<16:8, 7:16>>)
524
?line check(fun() -> L = 8,
525
F = fun(<<L:L,B:L>>) -> B end,
529
L = 8, F = fun(<<L:L,B:L>>) -> B end, F(<<16:8, 7:16>>)
532
?line check(fun() -> L = 8, <<A:L,B:A>> = <<16:8, 7:16>>, B end,
533
"begin L = 8, <<A:L,B:A>> = <<16:8, 7:16>>, B end.",
535
?line error_check("begin L = 8, <<L:L,B:L>> = <<16:8, 7:16>> end.",
536
{badmatch,<<16:8,7:16>>}),
538
?line error_check("begin <<L:16,L:L>> = <<16:16,8:16>>, L end.",
539
{badmatch, <<16:16,8:16>>}),
540
?line check(fun() -> U = 8, (fun(<<U:U>>) -> U end)(<<32:8>>) end,
541
"begin U = 8, (fun(<<U:U>>) -> U end)(<<32:8>>) end.",
543
?line check(fun() -> U = 8, [U || <<U:U>> <- [<<32:8>>]] end,
544
"begin U = 8, [U || <<U:U>> <- [<<32:8>>]] end.",
546
?line error_check("(fun({3,<<A:32,A:32>>}) -> a end)
547
({3,<<17:32,19:32>>}).",
549
?line check(fun() -> [X || <<A:8,
550
B:A>> <- [<<16:8,19:16>>],
551
<<X:8>> <- [<<B:8>>]] end,
553
B:A>> <- [<<16:8,19:16>>],
554
<<X:8>> <- [<<B:8>>]].",
559
["OTP-6539. try/catch bugs."];
562
otp_6539(Config) when is_list(Config) ->
566
catch _:_ -> dontthinkso
569
lists:zipwith(F, [1,2], [2,3])
574
catch _:_ -> dontthinkso
577
lists:zipwith(F, [1,2], [2,3])
583
["OTP-6543. bitlevel binaries."];
586
otp_6543(Config) when is_list(Config) ->
588
<< <<X>> || <<X>> <- [1,2,3] >>
590
"<< <<X>> || <<X>> <- [1,2,3] >>.",
593
<< <<X>> || X <- [1,2,3] >>
595
"<< <<X>> || X <- [1,2,3] >>.",
598
<< <<X:8>> || <<X:2>> <= <<"hej">> >>
600
"<< <<X:8>> || <<X:2>> <= <<\"hej\">> >>.",
601
<<1,2,2,0,1,2,1,1,1,2,2,2>>),
604
<<65,X:4>> <= <<65,7:4,65,3:4,66,8:4>> >>
607
<<65,X:4>> <= <<65,7:4,65,3:4,66,8:4>> >>.",
609
?line check(fun() -> <<34:18/big>> end,
612
?line check(fun() -> <<34:18/big-unit:2>> end,
613
"<<34:18/big-unit:2>>.",
615
?line check(fun() -> <<34:18/little>> end,
618
?line case eval_string("<<34:18/native>>.") of
622
?line check(fun() -> <<34:18/big-signed>> end,
623
"<<34:18/big-signed>>.",
625
?line check(fun() -> <<34:18/little-signed>> end,
626
"<<34:18/little-signed>>.",
628
?line case eval_string("<<34:18/native-signed>>.") of
632
?line check(fun() -> <<34:18/big-unsigned>> end,
633
"<<34:18/big-unsigned>>.",
635
?line check(fun() -> <<34:18/little-unsigned>> end,
636
"<<34:18/little-unsigned>>.",
638
?line case eval_string("<<34:18/native-unsigned>>.") of
642
?line check(fun() -> <<3.14:32/float-big>> end,
643
"<<3.14:32/float-big>>.",
645
?line check(fun() -> <<3.14:32/float-little>> end,
646
"<<3.14:32/float-little>>.",
648
?line case eval_string("<<3.14:32/float-native>>.") of
649
<<64,72,245,195>> -> ok;
650
<<195,245,72,64>> -> ok
652
?line error_check("<<(<<17,3:2>>)/binary>>.", badarg),
653
?line check(fun() -> <<(<<17,3:2>>)/bitstring>> end,
654
"<<(<<17,3:2>>)/bitstring>>.",
656
?line check(fun() -> <<(<<17,3:2>>):10/bitstring>> end,
657
"<<(<<17,3:2>>):10/bitstring>>.",
659
?line check(fun() -> <<<<344:17>>/binary-unit:17>> end,
660
"<<<<344:17>>/binary-unit:17>>.",
663
?line check(fun() -> <<X:18/big>> = <<34:18/big>>, X end,
664
"begin <<X:18/big>> = <<34:18/big>>, X end.",
666
?line check(fun() -> <<X:18/big-unit:2>> = <<34:18/big-unit:2>>, X end,
667
"begin <<X:18/big-unit:2>> = <<34:18/big-unit:2>>, X end.",
669
?line check(fun() -> <<X:18/little>> = <<34:18/little>>, X end,
670
"begin <<X:18/little>> = <<34:18/little>>, X end.",
672
?line check(fun() -> <<X:18/native>> = <<34:18/native>>, X end,
673
"begin <<X:18/native>> = <<34:18/native>>, X end.",
675
?line check(fun() -> <<X:18/big-signed>> = <<34:18/big-signed>>, X end,
676
"begin <<X:18/big-signed>> = <<34:18/big-signed>>, X end.",
678
?line check(fun() -> <<X:18/little-signed>> = <<34:18/little-signed>>,
680
"begin <<X:18/little-signed>> = <<34:18/little-signed>>,
683
?line check(fun() -> <<X:18/native-signed>> = <<34:18/native-signed>>,
685
"begin <<X:18/native-signed>> = <<34:18/native-signed>>,
688
?line check(fun() -> <<X:18/big-unsigned>> = <<34:18/big-unsigned>>,
690
"begin <<X:18/big-unsigned>> = <<34:18/big-unsigned>>,
694
<<X:18/little-unsigned>> = <<34:18/little-unsigned>>,
696
"begin <<X:18/little-unsigned>> = <<34:18/little-unsigned>>,
700
<<X:18/native-unsigned>> = <<34:18/native-unsigned>>,
702
"begin <<X:18/native-unsigned>> = <<34:18/native-unsigned>>,
705
?line check(fun() -> <<X:32/float-big>> = <<2.0:32/float-big>>, X end,
706
"begin <<X:32/float-big>> = <<2.0:32/float-big>>,
709
?line check(fun() -> <<X:32/float-little>> = <<2.0:32/float-little>>,
711
"begin <<X:32/float-little>> = <<2.0:32/float-little>>,
714
?line check(fun() -> <<X:32/float-native>> = <<2.0:32/float-native>>,
716
"begin <<X:32/float-native>> = <<2.0:32/float-native>>,
722
[X || <<"hej",X:8>> <= <<"hej",8,"san",9,"hej",17,"hej">>]
724
"[X || <<\"hej\",X:8>> <=
725
<<\"hej\",8,\"san\",9,\"hej\",17,\"hej\">>].",
729
L = 8, << <<B:32>> || <<L:L,B:L>> <= <<16:8, 7:16>> >>
731
"begin L = 8, << <<B:32>> || <<L:L,B:L>> <= <<16:8, 7:16>> >>
734
%% Test the Value part of a binary segment.
735
%% "Old" bugs have been fixed (partial_eval is called on Value).
736
?line check(fun() -> [ 3 || <<17/float>> <= <<17.0/float>>] end,
737
"[ 3 || <<17/float>> <= <<17.0/float>>].",
739
?line check(fun() -> [ 3 || <<17/float>> <- [<<17.0/float>>]] end,
740
"[ 3 || <<17/float>> <- [<<17.0/float>>]].",
742
?line check(fun() -> [ X || <<17/float,X:3>> <= <<17.0/float,2:3>>] end,
743
"[ X || <<17/float,X:3>> <= <<17.0/float,2:3>>].",
746
[ foo || <<(1 bsl 1023)/float>> <= <<(1 bsl 1023)/float>>]
748
"[ foo || <<(1 bsl 1023)/float>> <= <<(1 bsl 1023)/float>>].",
751
[ foo || <<(1 bsl 1023)/float>> <- [<<(1 bsl 1023)/float>>]]
753
"[ foo || <<(1 bsl 1023)/float>> <- [<<(1 bsl 1023)/float>>]].",
755
?line error_check("[ foo || <<(1 bsl 1024)/float>> <-
756
[<<(1 bsl 1024)/float>>]].",
759
[ foo || <<(1 bsl 1024)/float>> <- [<<(1 bsl 1023)/float>>]]
761
"[ foo || <<(1 bsl 1024)/float>> <-
762
[<<(1 bsl 1023)/float>>]].",
765
[ foo || <<(1 bsl 1024)/float>> <= <<(1 bsl 1023)/float>>]
767
"[ foo || <<(1 bsl 1024)/float>> <=
768
<<(1 bsl 1023)/float>>].",
772
[{L,B} || <<L:L,B:L/float>> <= <<32:8,7:32/float>>]
775
[{L,B} || <<L:L,B:L/float>> <= <<32:8,7:32/float>>]
780
[{L,B} || <<L:L,B:L/float>> <- [<<32:8,7:32/float>>]]
783
[{L,B} || <<L:L,B:L/float>> <- [<<32:8,7:32/float>>]]
787
[foo || <<"s">> <= <<"st">>]
789
"[foo || <<\"s\">> <= <<\"st\">>].",
791
?line check(fun() -> <<_:32>> = <<17:32>> end,
792
"<<_:32>> = <<17:32>>.",
794
?line check(fun() -> [foo || <<_:32>> <= <<17:32,20:32>>] end,
795
"[foo || <<_:32>> <= <<17:32,20:32>>].",
798
?line check(fun() -> << <<X:32>> || X <- [1,2,3], X > 1 >> end,
799
"<< <<X:32>> || X <- [1,2,3], X > 1 >>.",
800
<<0,0,0,2,0,0,0,3>>),
801
?line error_check("[X || <<X>> <= [a,b]].",{bad_generator,[a,b]}),
805
["OTP-6787. bitlevel binaries."];
808
otp_6787(Config) when is_list(Config) ->
810
fun() -> <<16:(1024*1024)>> = <<16:(1024*1024)>> end,
811
"<<16:(1024*1024)>> = <<16:(1024*1024)>>.",
816
["OTP-6977. ++ bug."];
819
otp_6977(Config) when is_list(Config) ->
821
fun() -> (fun([$X] ++ _) -> ok end)("X") end,
822
"(fun([$X] ++ _) -> ok end)(\"X\").",
827
["OTP-7550. Support for UTF-8, UTF-16, UTF-32."];
828
otp_7550(Config) when is_list(Config) ->
832
fun() -> <<65>> = <<65/utf8>> end,
833
"<<65>> = <<65/utf8>>.",
836
fun() -> <<350/utf8>> = <<197,158>> end,
837
"<<350/utf8>> = <<197,158>>.",
840
fun() -> <<$b,$j,$\303,$\266,$r,$n>> = <<"bj\366rn"/utf8>> end,
841
"<<$b,$j,$\303,$\266,$r,$n>> = <<\"bj\366rn\"/utf8>>.",
842
<<$b,$j,$\303,$\266,$r,$n>>),
846
fun() -> <<0,65>> = <<65/utf16>> end,
847
"<<0,65>> = <<65/utf16>>.",
850
fun() -> <<16#D8,16#08,16#DF,16#45>> = <<16#12345/utf16>> end,
851
"<<16#D8,16#08,16#DF,16#45>> = <<16#12345/utf16>>.",
852
<<16#D8,16#08,16#DF,16#45>>),
854
fun() -> <<16#08,16#D8,16#45,16#DF>> = <<16#12345/little-utf16>> end,
855
"<<16#08,16#D8,16#45,16#DF>> = <<16#12345/little-utf16>>.",
856
<<16#08,16#D8,16#45,16#DF>>),
859
fun() -> <<350/utf16>> = <<1,94>> end,
860
"<<350/utf16>> = <<1,94>>.",
863
fun() -> <<350/little-utf16>> = <<94,1>> end,
864
"<<350/little-utf16>> = <<94,1>>.",
867
fun() -> <<16#12345/utf16>> = <<16#D8,16#08,16#DF,16#45>> end,
868
"<<16#12345/utf16>> = <<16#D8,16#08,16#DF,16#45>>.",
869
<<16#D8,16#08,16#DF,16#45>>),
871
fun() -> <<16#12345/little-utf16>> = <<16#08,16#D8,16#45,16#DF>> end,
872
"<<16#12345/little-utf16>> = <<16#08,16#D8,16#45,16#DF>>.",
873
<<16#08,16#D8,16#45,16#DF>>),
877
fun() -> <<16#12345/utf32>> = <<16#0,16#01,16#23,16#45>> end,
878
"<<16#12345/utf32>> = <<16#0,16#01,16#23,16#45>>.",
879
<<16#0,16#01,16#23,16#45>>),
881
fun() -> <<16#0,16#01,16#23,16#45>> = <<16#12345/utf32>> end,
882
"<<16#0,16#01,16#23,16#45>> = <<16#12345/utf32>>.",
883
<<16#0,16#01,16#23,16#45>>),
885
fun() -> <<16#12345/little-utf32>> = <<16#45,16#23,16#01,16#00>> end,
886
"<<16#12345/little-utf32>> = <<16#45,16#23,16#01,16#00>>.",
887
<<16#45,16#23,16#01,16#00>>),
889
fun() -> <<16#12345/little-utf32>> end,
890
"<<16#12345/little-utf32>>.",
891
<<16#45,16#23,16#01,16#00>>),
895
fun() -> <<16#41,16#12345/utf32,16#0391:16,16#2E:8>> end,
896
"<<16#41,16#12345/utf32,16#0391:16,16#2E:8>>.",
897
<<16#41,16#00,16#01,16#23,16#45,16#03,16#91,16#2E>>),
902
["OTP-8133. Bit comprehension bug."];
905
otp_8133(Config) when is_list(Config) ->
910
is_integer(N) -> <<N/integer>>;
914
try << << (E(V))/binary >> || V <- [1,2,3,a] >>
920
if is_integer(N) -> <<N/integer>>;
924
try << << (E(V))/binary >> || V <- [1,2,3,a] >>
933
is_integer(N) -> <<N/integer>>;
934
true -> erlang:error(foo)
937
try << << (E(V))/binary >> || V <- [1,2,3,a] >>
938
catch error:foo -> ok
943
if is_integer(N) -> <<N/integer>>;
944
true -> erlang:error(foo)
947
try << << (E(V))/binary >> || V <- [1,2,3,a] >>
948
catch error:foo -> ok
955
["Simple cases, just to cover some code."];
958
funs(Config) when is_list(Config) ->
960
do_funs(lfh(), none),
961
do_funs(lfh(), efh()),
963
?line error_check("nix:foo().", {access_not_allowed,nix}, lfh(), efh()),
964
?line error_check("bar().", undef, none, none),
966
?line check(fun() -> F1 = fun(F,N) -> ?MODULE:count_down(F, N) end,
968
"begin F1 = fun(F,N) -> count_down(F, N) end,"
970
0, ['F1'], lfh(), none),
972
?line check(fun() -> F1 = fun(F,N) -> ?MODULE:count_down(F, N) end,
974
"begin F1 = fun(F,N) -> count_down(F, N) end,"
976
0, ['F1'], lfh_value(), none),
978
?line check(fun() -> F1 = fun(F,N) -> ?MODULE:count_down(F, N) end,
980
"begin F1 = fun(F,N) -> count_down(F, N) end,"
982
0, ['F1'], lfh_value_extra(), none),
984
?line check(fun() -> F1 = fun(F,N) -> ?MODULE:count_down(F, N) end,
986
"begin F1 = fun(F,N) -> count_down(F, N) end,"
988
0, ['F1'], {?MODULE,local_func_value}, none),
989
%% This is not documented, and only for backward compatibility (good!).
990
B0 = erl_eval:new_bindings(),
991
?line check(fun() -> is_function(?MODULE:count_down_fun()) end,
992
"begin is_function(count_down_fun()) end.",
993
true, [], {?MODULE,local_func,[B0]},none),
995
EF = fun({timer,sleep}, As) when length(As) == 1 -> exit({got_it,sleep});
996
({M,F}, As) -> apply(M, F, As)
999
?line error_check("apply(timer, sleep, [1]).", got_it, none, EFH),
1000
?line error_check("begin F = fun(T) -> timer:sleep(T) end,F(1) end.",
1002
?line error_check("fun c/1.", undef),
1003
?line error_check("fun a:b/0().", undef),
1007
lists:usort([run_many_args(SAs) || SAs <- many_args(MaxArgs)]),
1008
?line {'EXIT',{{argument_limit,_},_}} =
1009
(catch run_many_args(many_args1(MaxArgs+1))),
1012
run_many_args({S, As}) ->
1013
apply(eval_string(S), As) =:= As.
1016
[many_args1(I) || I <- lists:seq(1, N)].
1020
tl(lists:flatten([","++P++integer_to_list(E) || E <- L]))
1022
L = lists:seq(1, N),
1024
S = lists:flatten(io_lib:format("fun(~s) -> [~s] end.", [T, T])),
1027
do_funs(LFH, EFH) ->
1028
%% LFH is not really used by these examples...
1030
%% These tests do not prove that tail recursive functions really
1031
%% work (that the process does not grow); one should also run them
1032
%% manually with 1000 replaced by 1000000.
1034
M = atom_to_list(?MODULE),
1035
?line check(fun() -> F1 = fun(F,N) -> ?MODULE:count_down(F, N) end,
1037
concat(["begin F1 = fun(F,N) -> ", M,
1038
":count_down(F, N) end, F1(F1,1000) end."]),
1039
0, ['F1'], LFH, EFH),
1040
?line check(fun() -> F1 = fun(F,N) -> apply(?MODULE,count_down,[F,N])
1041
end, F1(F1, 1000) end,
1042
concat(["begin F1 = fun(F,N) -> apply(", M,
1043
",count_down,[F, N]) end, F1(F1,1000) end."]),
1044
0, ['F1'], LFH, EFH),
1045
?line check(fun() -> F1 = fun(F,N) -> {?MODULE,count_down}(F,N)
1046
end, F1(F1, 1000) end,
1047
concat(["begin F1 = fun(F,N) -> {", M,
1048
",count_down}(F, N) end, F1(F1,1000) end."]),
1049
0, ['F1'], LFH, EFH),
1050
?line check(fun() -> F = fun(F,N) when N > 0 -> apply(F,[F,N-1]);
1054
"begin F = fun(F,N) when N > 0 -> apply(F,[F,N-1]);"
1057
ok, ['F'], LFH, EFH),
1058
?line check(fun() -> F = fun(F,N) when N > 0 ->
1059
apply(erlang,apply,[F,[F,N-1]]);
1063
"begin F = fun(F,N) when N > 0 ->"
1064
"apply(erlang,apply,[F,[F,N-1]]);"
1067
ok, ['F'], LFH, EFH),
1068
?line check(fun() -> F = count_down_fun(),
1069
SF = fun(SF, F1, N) -> F(SF, F1, N) end,
1070
SF(SF, F, 1000) end,
1071
concat(["begin F = ", M, ":count_down_fun(),"
1072
"SF = fun(SF, F1, N) -> F(SF, F1, N) end,"
1073
"SF(SF, F, 1000) end."]),
1074
ok, ['F','SF'], LFH, EFH),
1077
?line check(fun() -> F = fun(X) -> A = 1+X, {X,A} end,
1078
true = {2,3} == F(2) end,
1079
"begin F = fun(X) -> A = 1+X, {X,A} end,
1080
true = {2,3} == F(2) end.", true, ['F'], LFH, EFH),
1081
?line check(fun() -> F = fun(X) -> {erlang,'+'}(X,2) end,
1082
true = 3 == F(1) end,
1083
"begin F = fun(X) -> {erlang,'+'}(X,2) end,"
1084
" true = 3 == F(1) end.", true, ['F'],
1086
?line check(fun() -> F = fun(X) -> byte_size(X) end,
1087
?MODULE:do_apply(F,<<"hej">>) end,
1088
concat(["begin F = fun(X) -> size(X) end,",
1089
M,":do_apply(F,<<\"hej\">>) end."]),
1090
3, ['F'], LFH, EFH),
1092
?line check(fun() -> F1 = fun(X, Z) -> {X,Z} end,
1094
F2 = fun(X, Y) -> F1(Z,{X,Y}) end,
1095
F3 = fun(X, Y) -> {a,F1(Z,{X,Y})} end,
1096
{5,{x,y}} = F2(x,y),
1097
{a,{5,{y,x}}} = F3(y,x),
1098
{5,{5,y}} = F2(Z,y),
1099
true = {5,{x,5}} == F2(x,Z) end,
1100
"begin F1 = fun(X, Z) -> {X,Z} end,
1102
F2 = fun(X, Y) -> F1(Z,{X,Y}) end,
1103
F3 = fun(X, Y) -> {a,F1(Z,{X,Y})} end,
1104
{5,{x,y}} = F2(x,y),
1105
{a,{5,{y,x}}} = F3(y,x),
1106
{5,{5,y}} = F2(Z,y),
1107
true = {5,{x,5}} == F2(x,Z) end.",
1108
true, ['F1','Z','F2','F3'], LFH, EFH),
1109
?line check(fun() -> F = fun(X) -> byte_size(X) end,
1110
F2 = fun(Y) -> F(Y) end,
1111
?MODULE:do_apply(F2,<<"hej">>) end,
1112
concat(["begin F = fun(X) -> size(X) end,",
1113
"F2 = fun(Y) -> F(Y) end,",
1114
M,":do_apply(F2,<<\"hej\">>) end."]),
1115
3, ['F','F2'], LFH, EFH),
1116
?line check(fun() -> Z = 5, F = fun(X) -> {Z,X} end,
1117
F2 = fun(Z) -> F(Z) end, F2(3) end,
1118
"begin Z = 5, F = fun(X) -> {Z,X} end,
1119
F2 = fun(Z) -> F(Z) end, F2(3) end.",
1120
{5,3},['F','F2','Z'], LFH, EFH),
1121
?line check(fun() -> F = fun(Z) -> Z end,
1122
F2 = fun(X) -> F(X), Z = {X,X}, Z end,
1123
{1,1} = F2(1), Z = 7, Z end,
1124
"begin F = fun(Z) -> Z end,
1125
F2 = fun(X) -> F(X), Z = {X,X}, Z end,
1126
{1,1} = F2(1), Z = 7, Z end.", 7, ['F','F2','Z'],
1128
?line check(fun() -> F = fun(F, N) -> [?MODULE:count_down(F,N) || X <-[1]]
1130
concat(["begin F = fun(F, N) -> [", M,
1131
":count_down(F,N) || X <-[1]] end, F(F,2) end."]),
1132
[[[0]]], ['F'], LFH, EFH),
1134
%% Tests for a bug found by the Dialyzer - used to crash.
1135
?line check(fun() -> Pmod = erl_eval_helper:new(42), Pmod:add(5) end,
1136
"begin Pmod = erl_eval_helper:new(42), Pmod:add(5) end.",
1138
['Pmod'], LFH, EFH),
1139
?line check(fun() -> Pmod = erl_eval_helper:new(42), B = Pmod:add(7), B end,
1140
"begin Pmod = erl_eval_helper:new(42), B = Pmod:add(7), B end.",
1142
['B','Pmod'], LFH, EFH),
1146
count_down(F, N) when N > 0 ->
1148
count_down(_F, N) ->
1152
fun(SF,F,N) when N > 0 -> SF(SF,F,N-1);
1160
{eval, fun(F, As, Bs) -> local_func(F, As, Bs) end}.
1162
local_func(F, As0, Bs0) when is_atom(F) ->
1163
{As,Bs} = erl_eval:expr_list(As0, Bs0, {eval,lfh()}),
1164
case erlang:function_exported(?MODULE, F, length(As)) of
1166
{value,apply(?MODULE, F, As),Bs};
1168
{value,apply(shell_default, F, As),Bs}
1171
lfh_value_extra() ->
1173
{value, fun(F, As) -> local_func_value(F, As) end, []}.
1176
{value, fun(F, As) -> local_func_value(F, As) end}.
1178
local_func_value(F, As) when is_atom(F) ->
1179
case erlang:function_exported(?MODULE, F, length(As)) of
1181
apply(?MODULE, F, As);
1183
apply(shell_default, F, As)
1187
{value, fun(F, As) -> external_func(F, As) end}.
1189
external_func({M,_}, _As) when M == nix ->
1190
exit({{access_not_allowed,M},[mfa]});
1191
external_func(F, As) when is_function(F) ->
1193
external_func({M,F}, As) ->
1199
["Test try-of-catch-after-end statement"];
1202
try_catch(Config) when is_list(Config) ->
1203
%% Match in of with catch
1204
?line check(fun() -> try 1 of 1 -> 2 catch _:_ -> 3 end end,
1205
"try 1 of 1 -> 2 catch _:_ -> 3 end.", 2),
1206
?line check(fun() -> try 1 of 1 -> 2; 3 -> 4 catch _:_ -> 5 end end,
1207
"try 1 of 1 -> 2; 3 -> 4 catch _:_ -> 5 end.", 2),
1208
?line check(fun() -> try 3 of 1 -> 2; 3 -> 4 catch _:_ -> 5 end end,
1209
"try 3 of 1 -> 2; 3 -> 4 catch _:_ -> 5 end.", 4),
1211
?line check(fun () -> X = try 1 after put(try_catch, 2) end,
1212
{X,get(try_catch)} end,
1213
"begin X = try 1 after put(try_catch, 2) end, "
1214
"{X,get(try_catch)} end.", {1,2}),
1215
%% Match in of with after
1216
?line check(fun() -> X = try 1 of 1 -> 2 after put(try_catch, 3) end,
1217
{X,get(try_catch)} end,
1218
"begin X = try 1 of 1 -> 2 after put(try_catch, 3) end, "
1219
"{X,get(try_catch)} end.", {2,3}),
1220
?line check(fun() -> X = try 1 of 1 -> 2; 3 -> 4
1221
after put(try_catch, 5) end,
1222
{X,get(try_catch)} end,
1223
"begin X = try 1 of 1 -> 2; 3 -> 4 "
1224
" after put(try_catch, 5) end, "
1225
" {X,get(try_catch)} end.", {2,5}),
1226
?line check(fun() -> X = try 3 of 1 -> 2; 3 -> 4
1227
after put(try_catch, 5) end,
1228
{X,get(try_catch)} end,
1229
"begin X = try 3 of 1 -> 2; 3 -> 4 "
1230
" after put(try_catch, 5) end, "
1231
" {X,get(try_catch)} end.", {4,5}),
1233
?line error_check("try 1 of 2 -> 3 catch _:_ -> 4 end.",
1235
%% Nomatch in of with after
1236
?line check(fun () -> {'EXIT',{{try_clause,1},_}} =
1237
begin catch try 1 of 2 -> 3
1238
after put(try_catch, 4) end end,
1240
"begin {'EXIT',{{try_clause,1},_}} = "
1241
" begin catch try 1 of 2 -> 3 "
1242
" after put(try_catch, 4) end end, "
1243
" get(try_catch) end. ", 4),
1245
?line check(fun () -> try 1=2 catch error:{badmatch,2} -> 3 end end,
1246
"try 1=2 catch error:{badmatch,2} -> 3 end.", 3),
1247
?line check(fun () -> try 1=2 of 3 -> 4
1248
catch error:{badmatch,2} -> 5 end end,
1249
"try 1=2 of 3 -> 4 "
1250
"catch error:{badmatch,2} -> 5 end.", 5),
1251
%% Exception in try with after
1252
?line check(fun () -> X = try 1=2
1253
catch error:{badmatch,2} -> 3
1254
after put(try_catch, 4) end,
1255
{X,get(try_catch)} end,
1256
"begin X = try 1=2 "
1257
" catch error:{badmatch,2} -> 3 "
1258
" after put(try_catch, 4) end, "
1259
" {X,get(try_catch)} end. ", {3,4}),
1260
?line check(fun () -> X = try 1=2 of 3 -> 4
1261
catch error:{badmatch,2} -> 5
1262
after put(try_catch, 6) end,
1263
{X,get(try_catch)} end,
1264
"begin X = try 1=2 of 3 -> 4"
1265
" catch error:{badmatch,2} -> 5 "
1266
" after put(try_catch, 6) end, "
1267
" {X,get(try_catch)} end. ", {5,6}),
1268
%% Uncaught exception
1269
?line error_check("try 1=2 catch error:undefined -> 3 end. ",
1271
?line error_check("try 1=2 of 3 -> 4 catch error:undefined -> 5 end. ",
1273
%% Uncaught exception with after
1274
?line check(fun () -> {'EXIT',{{badmatch,2},_}} =
1276
after put(try_catch, 3) end end,
1278
"begin {'EXIT',{{badmatch,2},_}} = "
1279
" begin catch try 1=2 "
1280
" after put(try_catch, 3) end end, "
1281
" get(try_catch) end. ", 3),
1282
?line check(fun () -> {'EXIT',{{badmatch,2},_}} =
1283
begin catch try 1=2 of 3 -> 4
1284
after put(try_catch, 5) end end,
1286
"begin {'EXIT',{{badmatch,2},_}} = "
1287
" begin catch try 1=2 of 3 -> 4"
1288
" after put(try_catch, 5) end end, "
1289
" get(try_catch) end. ", 5),
1290
?line check(fun () -> {'EXIT',{{badmatch,2},_}} =
1291
begin catch try 1=2 catch error:undefined -> 3
1292
after put(try_catch, 4) end end,
1294
"begin {'EXIT',{{badmatch,2},_}} = "
1295
" begin catch try 1=2 catch error:undefined -> 3 "
1296
" after put(try_catch, 4) end end, "
1297
" get(try_catch) end. ", 4),
1298
?line check(fun () -> {'EXIT',{{badmatch,2},_}} =
1299
begin catch try 1=2 of 3 -> 4
1300
catch error:undefined -> 5
1301
after put(try_catch, 6) end end,
1303
"begin {'EXIT',{{badmatch,2},_}} = "
1304
" begin catch try 1=2 of 3 -> 4 "
1305
" catch error:undefined -> 5 "
1306
" after put(try_catch, 6) end end, "
1307
" get(try_catch) end. ", 6),
1313
eval_expr_5(suite) ->
1315
eval_expr_5(Config) when is_list(Config) ->
1316
?line {ok,Tokens ,_} =
1317
erl_scan:string("if a+4 == 4 -> yes; true -> no end. "),
1318
?line {ok, [Expr]} = erl_parse:parse_exprs(Tokens),
1319
?line {value, no, []} = erl_eval:expr(Expr, [], none, none, none),
1320
?line no = erl_eval:expr(Expr, [], none, none, value),
1322
erl_eval:expr(Expr, [], none, none, 4711),
1323
?line function_clause = should_never_reach_here
1325
error:function_clause ->
1329
%% Check the string in different contexts: as is; in fun; from compiled code.
1330
check(F, String, Result) ->
1331
check1(F, String, Result),
1332
FunString = concat(["fun() -> ", no_final_dot(String), " end(). "]),
1333
check1(F, FunString, Result),
1334
CompileString = concat(["hd(lists:map(fun(_) -> ", no_final_dot(String),
1335
" end, [foo])). "]),
1336
check1(F, CompileString, Result).
1338
check1(F, String, Result) ->
1340
case catch parse_and_run(String) of
1341
{value, Result, _} ->
1344
test_server:fail({eval, Other, Result})
1347
check(F, String, Result, BoundVars, LFH, EFH) ->
1349
case catch parse_and_run(String, LFH, EFH) of
1350
{value, Result, Bs} ->
1351
%% We just assume that Bs is an orddict...
1352
Keys = orddict:fetch_keys(Bs),
1353
case sort(BoundVars) == Keys of
1357
test_server:fail({check, BoundVars, Keys})
1361
test_server:fail({check, Other, Result})
1364
error_check(String, Result) ->
1365
case catch parse_and_run(String) of
1366
{'EXIT', {Result,_}} ->
1369
test_server:fail({eval, Other, Result})
1372
error_check(String, Result, LFH, EFH) ->
1373
case catch parse_and_run(String, LFH, EFH) of
1374
{'EXIT', {Result,_}} ->
1377
test_server:fail({eval, Other, Result})
1380
eval_string(String) ->
1381
{value, Result, _} = parse_and_run(String),
1384
parse_and_run(String) ->
1385
{ok,Tokens,_} = erl_scan:string(String),
1386
{ok, [Expr]} = erl_parse:parse_exprs(Tokens),
1387
erl_eval:expr(Expr, []).
1389
parse_and_run(String, LFH, EFH) ->
1390
{ok,Tokens,_} = erl_scan:string(String),
1391
{ok, [Expr]} = erl_parse:parse_exprs(Tokens),
1392
erl_eval:expr(Expr, [], LFH, EFH).
1395
case lists:reverse(S) of
1396
" ." ++ R -> lists:reverse(R);
1397
"." ++ R -> lists:reverse(R);