31
31
-define(ERR_HEADBADREC,7).
32
32
-define(ERR_HEADBADFIELD,8).
33
33
-define(ERR_HEADMULTIFIELD,9).
34
-define(ERR_HEADDOLLARATOM,10).
35
-define(ERR_HEADBINMATCH,11).
34
36
-define(ERR_GENMATCH,16).
35
37
-define(ERR_GENLOCALCALL,17).
36
38
-define(ERR_GENELEMENT,18).
37
39
-define(ERR_GENBADFIELD,19).
38
40
-define(ERR_GENBADREC,20).
39
41
-define(ERR_GENMULTIFIELD,21).
42
-define(ERR_GENREMOTECALL,22).
43
-define(ERR_GENBINCONSTRUCT,23).
44
-define(ERR_GENDISALLOWEDOP,24).
40
45
-define(ERR_GUARDMATCH,?ERR_GENMATCH+?ERROR_BASE_GUARD).
41
46
-define(ERR_BODYMATCH,?ERR_GENMATCH+?ERROR_BASE_BODY).
42
47
-define(ERR_GUARDLOCALCALL,?ERR_GENLOCALCALL+?ERROR_BASE_GUARD).
65
76
"fun with semicolon (;) in guard cannot be translated into match_spec";
66
77
format_error(?ERR_GUARDMATCH) ->
67
78
"fun with guard matching ('=' in guard) is illegal as match_spec as well";
68
format_error({?ERR_GUARDLOCALCALL, Name}) ->
69
lists:flatten(io_lib:format("fun containing local erlang function calls "
70
"('~w' called in guard) "
71
"cannot be translated into match_spec",
79
format_error({?ERR_GUARDLOCALCALL, Name, Arithy}) ->
80
lists:flatten(io_lib:format("fun containing the local function call "
81
"'~w/~w' (called in guard) "
82
"cannot be translated into match_spec",
84
format_error({?ERR_GUARDREMOTECALL, Module, Name, Arithy}) ->
85
lists:flatten(io_lib:format("fun containing the remote function call "
86
"'~w:~w/~w' (called in guard) "
87
"cannot be translated into match_spec",
88
[Module,Name,Arithy]));
73
89
format_error({?ERR_GUARDELEMENT, Str}) ->
75
91
io_lib:format("the language element ~s (in guard) cannot be translated "
76
92
"into match_spec", [Str]));
93
format_error({?ERR_GUARDBINCONSTRUCT, Var}) ->
95
io_lib:format("bit syntax construction with variable ~w (in guard) "
96
"cannot be translated "
97
"into match_spec", [Var]));
98
format_error({?ERR_GUARDDISALLOWEDOP, Operator}) ->
99
%% There is presently no operators that are allowed in bodies but
102
io_lib:format("the operator ~w is not allowed in guards", [Operator]));
77
103
format_error(?ERR_BODYMATCH) ->
78
104
"fun with body matching ('=' in body) is illegal as match_spec";
79
format_error({?ERR_BODYLOCALCALL, Name}) ->
80
lists:flatten(io_lib:format("fun containing local erlang function calls "
81
"('~w' called in body) "
82
"cannot be translated into match_spec",
105
format_error({?ERR_BODYLOCALCALL, Name, Arithy}) ->
106
lists:flatten(io_lib:format("fun containing the local function "
107
"call '~w/~w' (called in body) "
108
"cannot be translated into match_spec",
110
format_error({?ERR_BODYREMOTECALL, Module, Name, Arithy}) ->
111
lists:flatten(io_lib:format("fun containing the remote function call "
112
"'~w:~w/~w' (called in body) "
113
"cannot be translated into match_spec",
114
[Module,Name,Arithy]));
84
115
format_error({?ERR_BODYELEMENT, Str}) ->
86
117
io_lib:format("the language element ~s (in body) cannot be translated "
87
118
"into match_spec", [Str]));
119
format_error({?ERR_BODYBINCONSTRUCT, Var}) ->
121
io_lib:format("bit syntax construction with variable ~w (in body) "
122
"cannot be translated "
123
"into match_spec", [Var]));
124
format_error({?ERR_BODYDISALLOWEDOP, Operator}) ->
125
%% This will probably never happen, Are there op's that are allowed in
126
%% guards but not in bodies? Not at time of writing anyway...
128
io_lib:format("the operator ~w is not allowed in function bodies",
88
131
format_error({?ERR_UNBOUND_VARIABLE, Str}) ->
90
133
io_lib:format("the variable ~s is unbound, cannot translate "
267
317
transform_call(_Type,Line,_NoAbstractFun) ->
268
318
throw({error,Line,?ERR_NOFUN}).
320
% Fixup semicolons in guards
321
ms_clause_expand({clause, Line, Parameters, Guard = [_,_|_], Body}) ->
322
[ {clause, Line, Parameters, [X], Body} || X <- Guard ];
323
ms_clause_expand(_Other) ->
270
326
ms_clause_list(Line,[H|T],Type) ->
271
{cons, Line, ms_clause(H,Type), ms_clause_list(Line, T,Type)};
327
case ms_clause_expand(H) of
328
NewHead when is_list(NewHead) ->
329
ms_clause_list(Line,NewHead ++ T, Type);
331
{cons, Line, ms_clause(H,Type), ms_clause_list(Line, T,Type)}
272
333
ms_clause_list(Line,[],_) ->
274
335
ms_clause({clause, Line, Parameters, Guards, Body},Type) ->
341
415
throw({error,Line3,{?ERR_GENBADREC+B#tgd.eb,RName}})
343
417
tg({call, Line, {atom, Line2, FunName},ParaList},B) ->
344
case is_ms_function(FunName,B#tgd.p) of
418
case is_ms_function(FunName,length(ParaList), B#tgd.p) of
346
420
{tuple, Line, [{atom, Line2, FunName} |
347
421
lists:map(fun(X) -> tg(X,B) end, ParaList)]};
349
throw({error,Line,{?ERR_GENLOCALCALL+B#tgd.eb,FunName}})
423
throw({error,Line,{?ERR_GENLOCALCALL+B#tgd.eb,
424
FunName,length(ParaList)}})
426
tg({call, Line, {remote,_,{atom,_,erlang},{atom, Line2, FunName}},ParaList},
428
L = length(ParaList),
429
case is_imported_from_erlang(FunName,L,B#tgd.p) of
431
case is_operator(FunName,L,B#tgd.p) of
433
tg({call, Line, {atom, Line2, FunName},ParaList},B);
435
tg(list_to_tuple([op,Line2,FunName | ParaList]),B)
438
throw({error,Line,{?ERR_GENREMOTECALL+B#tgd.eb,erlang,
439
FunName,length(ParaList)}})
441
tg({call, Line, {remote,_,{atom,_,ModuleName},
442
{atom, _, FunName}},_ParaList},B) ->
443
throw({error,Line,{?ERR_GENREMOTECALL+B#tgd.eb,ModuleName,FunName}});
351
444
tg({cons,Line, H, T},B) ->
352
445
{cons, Line, tg(H,B), tg(T,B)};
353
446
tg({nil, Line},_B) ->
391
489
tg({record,Line,RName,RFields},B) ->
392
490
RDefs = get_records(),
393
KeyList = lists:foldl(fun({record_field,_,{atom,_,Key},Value},
491
KeyList0 = lists:foldl(fun({record_field,_,{atom,_,Key},Value},
395
493
NV = tg(Value,B),
495
({record_field,_,{var,_,'_'},Value},
398
throw({error,Line,?ERR_HEADBADREC})
501
{?ERR_GENBADREC+B#tgd.eb,
506
DefValue = case lists:keysearch({default},1,KeyList0) of
507
{value,{{default},OverriddenDefValue}} ->
508
{true,OverriddenDefValue};
512
KeyList = lists:keydelete({default},1,KeyList0),
513
case lists:keysearch({default},1,KeyList) of
514
{value,{{default},_}} ->
515
throw({error,Line,{?ERR_GENMULTIFIELD+B#tgd.eb,RName,'_'}});
402
519
case lists:keysearch(RName,1,RDefs) of
403
520
{value, {RName, FieldList0}} ->
404
521
FieldList1 = lists:foldl(
475
597
throw({error,Line,{?ERR_GENBADREC+B#tgd.eb,RName}})
600
tg({bin_element,_Line0,{var, Line, A},_,_} = Whole,B) ->
601
case lkup_bind(A, B#tgd.b) of
603
Whole; % exists in environment hopefully
605
throw({error,Line,{?ERR_GENBINCONSTRUCT+B#tgd.eb,A}})
609
tg({bin_element,Line,X,Y,Z},B) ->
610
{bin_element, Line, tg(X,B), tg(Y,B), Z};
612
tg({bin,Line,List},B) ->
613
{bin,Line,[tg(X,B) || X <- List]};
478
615
tg(T,B) when is_tuple(T), size(T) >= 2 ->
479
616
Element = element(1,T),
500
637
th({record,Line,RName,RFields},B) ->
502
639
RDefs = get_records(),
503
{KeyList,NewB} = lists:foldl(fun({record_field,_,{atom,_,Key},Value},
640
{KeyList0,NewB} = lists:foldl(fun({record_field,_,{atom,_,Key},Value},
505
642
{NV,B1} = th(Value,B0),
506
643
{[{Key,NV}|L],B1};
644
({record_field,_,{var,_,'_'},Value},
646
{NV,B1} = th(Value,B0),
647
{[{{default},NV}|L],B1};
508
649
throw({error,Line,{?ERR_HEADBADREC,
654
DefValue = case lists:keysearch({default},1,KeyList0) of
655
{value,{{default},OverriddenDefValue}} ->
660
KeyList = lists:keydelete({default},1,KeyList0),
661
case lists:keysearch({default},1,KeyList) of
662
{value,{{default},_}} ->
663
throw({error,Line,{?ERR_HEADMULTIFIELD,RName,'_'}});
513
667
case lists:keysearch(RName,1,RDefs) of
514
668
{value, {RName, FieldList0}} ->
515
669
FieldList1 = lists:foldl(
606
775
atom_to_list(Atom)
626
BoolFunction = ['xor' | BoolTest],
643
is_ms_function(X,body) ->
658
lists:member(X,ActionFunction);
660
is_ms_function(X,guard) ->
661
lists:member(X,guard_function()).
778
old_bool_test(atom,1) -> is_atom;
779
old_bool_test(constant,1) -> is_constant;
780
old_bool_test(float,1) -> is_float;
781
old_bool_test(integer,1) -> is_integer;
782
old_bool_test(list,1) -> is_list;
783
old_bool_test(number,1) -> is_number;
784
old_bool_test(pid,1) -> is_pid;
785
old_bool_test(port,1) -> is_port;
786
old_bool_test(reference,1) -> is_reference;
787
old_bool_test(tuple,1) -> is_tuple;
788
old_bool_test(binary,1) -> is_binary;
789
old_bool_test(function,1) -> is_function;
790
old_bool_test(record,2) -> is_record;
791
old_bool_test(_,_) -> undefined.
793
bool_test(is_atom,1) -> true;
794
bool_test(is_constant,1) -> true;
795
bool_test(is_float,1) -> true;
796
bool_test(is_integer,1) -> true;
797
bool_test(is_list,1) -> true;
798
bool_test(is_number,1) -> true;
799
bool_test(is_pid,1) -> true;
800
bool_test(is_port,1) -> true;
801
bool_test(is_reference,1) -> true;
802
bool_test(is_tuple,1) -> true;
803
bool_test(is_binary,1) -> true;
804
bool_test(is_function,1) -> true;
805
bool_test(is_record,2) -> true;
806
bool_test(is_seq_trace,0) -> true;
807
bool_test(_,_) -> false.
809
real_guard_function(abs,1) -> true;
810
real_guard_function(element,2) -> true;
811
real_guard_function(hd,1) -> true;
812
real_guard_function(length,1) -> true;
813
real_guard_function(node,0) -> true;
814
real_guard_function(node,1) -> true;
815
real_guard_function(round,1) -> true;
816
real_guard_function(size,1) -> true;
817
real_guard_function(tl,1) -> true;
818
real_guard_function(trunc,1) -> true;
819
real_guard_function(self,0) -> true;
820
real_guard_function(float,1) -> true;
821
real_guard_function(_,_) -> false.
823
pseudo_guard_function(get_tcw,0) -> true;
824
pseudo_guard_function(_,_) -> false.
826
guard_function(X,A) ->
827
real_guard_function(X,A) or pseudo_guard_function(X,A).
829
action_function(set_seq_token,2) -> true;
830
action_function(get_seq_token,0) -> true;
831
action_function(message,1) -> true;
832
action_function(return_trace,0) -> true;
833
action_function(process_dump,0) -> true;
834
action_function(enable_trace,1) -> true;
835
action_function(enable_trace,2) -> true;
836
action_function(disable_trace,1) -> true;
837
action_function(disable_trace,2) -> true;
838
action_function(display,1) -> true;
839
action_function(caller,0) -> true;
840
action_function(set_tcw,1) -> true;
841
action_function(silent,1) -> true;
842
action_function(_,_) -> false.
844
bool_operator('and',2) ->
846
bool_operator('or',2) ->
848
bool_operator('xor',2) ->
850
bool_operator('not',1) ->
852
bool_operator('andalso',2) ->
854
bool_operator('orelse',2) ->
856
bool_operator(_,_) ->
859
arith_operator('+',1) ->
861
arith_operator('+',2) ->
863
arith_operator('-',1) ->
865
arith_operator('-',2) ->
867
arith_operator('*',2) ->
869
arith_operator('/',2) ->
871
arith_operator('div',2) ->
873
arith_operator('rem',2) ->
875
arith_operator('band',2) ->
877
arith_operator('bor',2) ->
879
arith_operator('bxor',2) ->
881
arith_operator('bnot',1) ->
883
arith_operator('bsl',2) ->
885
arith_operator('bsr',2) ->
887
arith_operator(_,_) ->
890
cmp_operator('>',2) ->
892
cmp_operator('>=',2) ->
894
cmp_operator('<',2) ->
896
cmp_operator('=<',2) ->
898
cmp_operator('==',2) ->
900
cmp_operator('=:=',2) ->
902
cmp_operator('/=',2) ->
904
cmp_operator('=/=',2) ->
909
is_operator(X,A,_) ->
910
bool_operator(X,A) or arith_operator(X,A) or cmp_operator(X,A).
912
is_imported_from_erlang(X,A,_) ->
913
real_guard_function(X,A) or bool_test(X,A) or bool_operator(X,A) or
914
arith_operator(X,A) or cmp_operator(X,A).
916
is_ms_function(X,A,body) ->
917
action_function(X,A) or guard_function(X,A) or bool_test(X,A);
919
is_ms_function(X,A,guard) ->
920
guard_function(X,A) or bool_test(X,A).
665
922
fixup_environment(L,B) when is_list(L) ->
666
923
lists:map(fun(X) ->