~ubuntu-branches/debian/squeeze/erlang/squeeze

« back to all changes in this revision

Viewing changes to lib/stdlib/src/ms_transform.erl

  • Committer: Bazaar Package Importer
  • Author(s): Erlang Packagers, Sergei Golovan
  • Date: 2006-12-03 17:07:44 UTC
  • mfrom: (2.1.11 feisty)
  • Revision ID: james.westby@ubuntu.com-20061203170744-rghjwupacqlzs6kv
Tags: 1:11.b.2-4
[ Sergei Golovan ]
Fixed erlang-base and erlang-base-hipe prerm scripts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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).
49
54
-define(ERR_BODYBADREC,?ERR_GENBADREC+?ERROR_BASE_BODY).
50
55
-define(ERR_GUARDMULTIFIELD,?ERR_GENMULTIFIELD+?ERROR_BASE_GUARD).
51
56
-define(ERR_BODYMULTIFIELD,?ERR_GENMULTIFIELD+?ERROR_BASE_BODY).
 
57
-define(ERR_GUARDREMOTECALL,?ERR_GENREMOTECALL+?ERROR_BASE_GUARD).
 
58
-define(ERR_BODYREMOTECALL,?ERR_GENREMOTECALL+?ERROR_BASE_BODY).
 
59
-define(ERR_GUARDBINCONSTRUCT,?ERR_GENBINCONSTRUCT+?ERROR_BASE_GUARD).
 
60
-define(ERR_BODYBINCONSTRUCT,?ERR_GENBINCONSTRUCT+?ERROR_BASE_BODY).
 
61
-define(ERR_GUARDDISALLOWEDOP,?ERR_GENDISALLOWEDOP+?ERROR_BASE_GUARD).
 
62
-define(ERR_BODYDISALLOWEDOP,?ERR_GENDISALLOWEDOP+?ERROR_BASE_BODY).
52
63
 
53
64
%%
54
65
%% Called by compiler or ets/dbg:fun2ms when errors occur
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",
72
 
                                [Name]));
 
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",
 
83
                                [Name, Arithy]));
 
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}) ->
74
90
    lists:flatten(
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}) ->
 
94
    lists:flatten(
 
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
 
100
    %% not in guards.
 
101
    lists:flatten(
 
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",
83
 
                                [Name]));
 
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",
 
109
                                [Name,Arithy]));
 
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}) ->
85
116
    lists:flatten(
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}) ->
 
120
    lists:flatten(
 
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...
 
127
    lists:flatten(
 
128
      io_lib:format("the operator ~w is not allowed in function bodies", 
 
129
                    [Operator]));
 
130
 
88
131
format_error({?ERR_UNBOUND_VARIABLE, Str}) ->
89
132
    lists:flatten(
90
133
      io_lib:format("the variable ~s is unbound, cannot translate "
100
143
    lists:flatten(
101
144
      io_lib:format("fun head contains already defined field ~w in "
102
145
                    "record type ~w",[FName, RName]));
 
146
format_error({?ERR_HEADDOLLARATOM,Atom}) ->         
 
147
    lists:flatten(
 
148
      io_lib:format("fun head contains atom ~w, which conflics with reserved "
 
149
                    "atoms in match_spec heads",[Atom]));
 
150
format_error({?ERR_HEADBINMATCH,Atom}) ->           
 
151
    lists:flatten(
 
152
      io_lib:format("fun head contains bit syntax matching of variable ~w, "
 
153
                    "which cannot be translated into match_spec", [Atom]));
103
154
format_error({?ERR_GUARDBADREC,Name}) ->            
104
155
    lists:flatten(
105
156
      io_lib:format("fun guard contains unknown record type ~w",[Name]));
155
206
%%
156
207
parse_transform(Forms, _Options) ->
157
208
    SaveFilename = setup_filename(),
158
 
    %erlang:display(Forms),
159
209
    case catch forms(Forms) of
160
210
        {'EXIT',Reason} ->
161
211
            cleanup_filename(SaveFilename),
267
317
transform_call(_Type,Line,_NoAbstractFun) ->
268
318
    throw({error,Line,?ERR_NOFUN}).
269
319
 
 
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) ->
 
324
    false.
 
325
 
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);
 
330
        false ->
 
331
            {cons, Line, ms_clause(H,Type), ms_clause_list(Line, T,Type)}
 
332
    end;
272
333
ms_clause_list(Line,[],_) ->
273
334
    {nil,Line}.
274
335
ms_clause({clause, Line, Parameters, Guards, Body},Type) ->
314
375
    tg0(Line,Body,B).
315
376
    
316
377
 
 
378
guard_top_trans({call,Line0,{atom,Line1,OldTest},Params}) ->
 
379
    case old_bool_test(OldTest,length(Params)) of
 
380
        undefined ->
 
381
            {call,Line0,{atom,Line1,OldTest},Params};
 
382
        Trans ->
 
383
            {call,Line0,{atom,Line1,Trans},Params}
 
384
    end;
 
385
guard_top_trans(Else) ->
 
386
    Else.
 
387
 
317
388
tg0(Line,[],_) ->
318
389
    {nil,Line};
 
390
tg0(Line,[H0|T],B) when B#tgd.p =:= guard ->
 
391
    H = guard_top_trans(H0),
 
392
    {cons,Line, tg(H,B), tg0(Line,T,B)};
319
393
tg0(Line,[H|T],B) ->
320
394
    {cons,Line, tg(H,B), tg0(Line,T,B)}.
321
395
    
341
415
            throw({error,Line3,{?ERR_GENBADREC+B#tgd.eb,RName}})
342
416
    end;
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
345
419
        true ->
346
420
            {tuple, Line, [{atom, Line2, FunName} | 
347
421
                           lists:map(fun(X) -> tg(X,B) end, ParaList)]};
348
422
        _ ->
349
 
            throw({error,Line,{?ERR_GENLOCALCALL+B#tgd.eb,FunName}}) 
350
 
    end;
 
423
            throw({error,Line,{?ERR_GENLOCALCALL+B#tgd.eb,
 
424
                               FunName,length(ParaList)}}) 
 
425
    end;
 
426
tg({call, Line, {remote,_,{atom,_,erlang},{atom, Line2, FunName}},ParaList},
 
427
   B) ->
 
428
    L = length(ParaList),
 
429
    case is_imported_from_erlang(FunName,L,B#tgd.p) of
 
430
        true ->
 
431
            case is_operator(FunName,L,B#tgd.p) of
 
432
                false ->
 
433
                    tg({call, Line, {atom, Line2, FunName},ParaList},B);
 
434
                true ->
 
435
                    tg(list_to_tuple([op,Line2,FunName | ParaList]),B)
 
436
                end;
 
437
        _ ->
 
438
            throw({error,Line,{?ERR_GENREMOTECALL+B#tgd.eb,erlang,
 
439
                               FunName,length(ParaList)}}) 
 
440
    end;
 
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) ->
361
454
tg({float, Line,F},_) ->
362
455
    {float,Line,F};
363
456
tg({atom,Line,A},_) ->
364
 
    {atom,Line,A};
 
457
    case atom_to_list(A) of
 
458
        [$$|_] ->
 
459
           {tuple, Line,[{atom, Line, 'const'},{atom,Line,A}]};
 
460
        _ ->
 
461
            {atom,Line,A}
 
462
    end;
365
463
tg({string,Line,S},_) ->
366
464
    {string,Line,S};
367
465
tg({var,Line,VarName},B) ->
390
488
 
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},
394
492
                                     L) ->
395
493
                                         NV = tg(Value,B),
396
494
                                         [{Key,NV}|L];
 
495
                                    ({record_field,_,{var,_,'_'},Value},
 
496
                                     L) ->
 
497
                                         NV = tg(Value,B),
 
498
                                         [{{default},NV}|L];
397
499
                                    (_,_) ->
398
 
                                         throw({error,Line,?ERR_HEADBADREC})
 
500
                                         throw({error,Line,
 
501
                                                {?ERR_GENBADREC+B#tgd.eb,
 
502
                                                 RName}})
399
503
                                 end,
400
504
                                 [],
401
505
                                 RFields),
 
506
    DefValue = case lists:keysearch({default},1,KeyList0) of
 
507
                   {value,{{default},OverriddenDefValue}} ->
 
508
                       {true,OverriddenDefValue};
 
509
                   _ ->
 
510
                       false
 
511
               end,
 
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,'_'}});
 
516
        _ ->
 
517
            ok
 
518
    end,
402
519
    case lists:keysearch(RName,1,RDefs) of
403
520
        {value, {RName, FieldList0}} ->
404
521
            FieldList1 = lists:foldl(
407
524
                                            {value, {FN, X0}} ->
408
525
                                                X0;
409
526
                                            _ ->
410
 
                                                Def
 
527
                                                case DefValue of 
 
528
                                                    {true,Overridden} ->
 
529
                                                        Overridden;
 
530
                                                    false ->
 
531
                                                        Def
 
532
                                                end
411
533
                                        end,
412
534
                                   [El | Acc]
413
535
                           end,
474
596
        _ ->
475
597
            throw({error,Line,{?ERR_GENBADREC+B#tgd.eb,RName}})
476
598
    end;
 
599
 
 
600
tg({bin_element,_Line0,{var, Line, A},_,_} = Whole,B) ->
 
601
    case lkup_bind(A, B#tgd.b) of
 
602
        undefined ->
 
603
            Whole; % exists in environment hopefully
 
604
        _AtomName ->
 
605
            throw({error,Line,{?ERR_GENBINCONSTRUCT+B#tgd.eb,A}})
 
606
    end;    
 
607
tg(default,_B) ->
 
608
    default;
 
609
tg({bin_element,Line,X,Y,Z},B) ->
 
610
    {bin_element, Line, tg(X,B), tg(Y,B), Z};
 
611
 
 
612
tg({bin,Line,List},B) ->
 
613
    {bin,Line,[tg(X,B) || X <- List]};
477
614
    
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) ->
501
638
    % youch...
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},
504
641
                                     {L,B0}) ->
505
642
                                         {NV,B1} = th(Value,B0),
506
643
                                         {[{Key,NV}|L],B1};
 
644
                                    ({record_field,_,{var,_,'_'},Value},
 
645
                                     {L,B0}) ->
 
646
                                         {NV,B1} = th(Value,B0),
 
647
                                         {[{{default},NV}|L],B1};
507
648
                                    (_,_) ->
508
649
                                         throw({error,Line,{?ERR_HEADBADREC,
509
650
                                                            RName}})
510
651
                                 end,
511
652
                                 {[],B},
512
653
                                 RFields),
 
654
    DefValue = case lists:keysearch({default},1,KeyList0) of
 
655
                   {value,{{default},OverriddenDefValue}} ->
 
656
                       OverriddenDefValue;
 
657
                   _ ->
 
658
                       {atom,Line,'_'}
 
659
               end,
 
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,'_'}});
 
664
        _ ->
 
665
            ok
 
666
    end,
513
667
    case lists:keysearch(RName,1,RDefs) of
514
668
        {value, {RName, FieldList0}} ->
515
669
            FieldList1 = lists:foldl(
518
672
                                            {value, {FN, X0}} ->
519
673
                                                X0;
520
674
                                            _ ->
521
 
                                                {atom,Line,'_'}
 
675
                                                DefValue
522
676
                                        end,
523
677
                                   [El | Acc]
524
678
                           end,
535
689
 
536
690
th({match,Line,_,_},_) -> 
537
691
    throw({error,Line,?ERR_HEADMATCH});
 
692
th({atom,Line,A},B) ->
 
693
    case atom_to_list(A) of
 
694
        [$$|NL] ->
 
695
            case (catch list_to_integer(NL)) of
 
696
                N when is_integer(N) ->
 
697
                    throw({error,Line,{?ERR_HEADDOLLARATOM,A}});
 
698
                _ ->
 
699
                    {{atom,Line,A},B}
 
700
            end;
 
701
        _ ->
 
702
            {{atom,Line,A},B}
 
703
    end;
 
704
th({bin_element,_Line0,{var, Line, A},_,_},_) ->
 
705
    throw({error,Line,{?ERR_HEADBINMATCH,A}});
 
706
 
538
707
th({var,Line,Name},B) ->
539
708
    case lkup_bind(Name,B) of
540
709
        undefined ->
606
775
            atom_to_list(Atom)
607
776
    end.
608
777
 
609
 
guard_function() ->
610
 
    BoolTest = [
611
 
                is_atom, 
612
 
                is_constant, 
613
 
                is_float, 
614
 
                is_integer, 
615
 
                is_list, 
616
 
                is_number, 
617
 
                is_pid, 
618
 
                is_port, 
619
 
                is_reference, 
620
 
                is_tuple, 
621
 
                is_binary, 
622
 
                is_function, 
623
 
                is_record, 
624
 
                is_seq_trace
625
 
               ],
626
 
    BoolFunction = ['xor' | BoolTest], 
627
 
    GuardFunction = [
628
 
                     abs, 
629
 
                     element, 
630
 
                     hd, 
631
 
                     length, 
632
 
                     node, 
633
 
                     round, 
634
 
                     size, 
635
 
                     tl, 
636
 
                     trunc, 
637
 
                     self, 
638
 
                     get_tcw |
639
 
                     BoolFunction
640
 
                    ],
641
 
    GuardFunction.
642
 
                 
643
 
is_ms_function(X,body) ->
644
 
    ActionFunction = [
645
 
                      set_seq_token,
646
 
                      get_seq_token,
647
 
                      message,
648
 
                      return_trace,
649
 
                      process_dump,
650
 
                      enable_trace,
651
 
                      disable_trace,
652
 
                      display,
653
 
                      caller,
654
 
                      set_tcw,
655
 
                      silent |
656
 
                      guard_function()
657
 
                      ],
658
 
    lists:member(X,ActionFunction);
659
 
 
660
 
is_ms_function(X,guard) ->
661
 
    lists:member(X,guard_function()).
662
 
 
663
 
 
 
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.
 
792
 
 
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.
 
808
 
 
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.
 
822
 
 
823
pseudo_guard_function(get_tcw,0) -> true;
 
824
pseudo_guard_function(_,_) -> false.
 
825
 
 
826
guard_function(X,A) ->
 
827
    real_guard_function(X,A) or pseudo_guard_function(X,A).
 
828
 
 
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.
 
843
 
 
844
bool_operator('and',2) ->
 
845
    true;
 
846
bool_operator('or',2) ->
 
847
    true;
 
848
bool_operator('xor',2) ->
 
849
    true;
 
850
bool_operator('not',1) ->
 
851
    true;
 
852
bool_operator('andalso',2) ->
 
853
    true;
 
854
bool_operator('orelse',2) ->
 
855
    true;
 
856
bool_operator(_,_) ->
 
857
    false.
 
858
 
 
859
arith_operator('+',1) ->
 
860
    true;
 
861
arith_operator('+',2) ->
 
862
    true;
 
863
arith_operator('-',1) ->
 
864
    true;
 
865
arith_operator('-',2) ->
 
866
    true;
 
867
arith_operator('*',2) ->
 
868
    true;
 
869
arith_operator('/',2) ->
 
870
    true;
 
871
arith_operator('div',2) ->
 
872
    true;
 
873
arith_operator('rem',2) ->
 
874
    true;
 
875
arith_operator('band',2) ->
 
876
    true;
 
877
arith_operator('bor',2) ->
 
878
    true;
 
879
arith_operator('bxor',2) ->
 
880
    true;
 
881
arith_operator('bnot',1) ->
 
882
    true;
 
883
arith_operator('bsl',2) ->
 
884
    true;
 
885
arith_operator('bsr',2) ->
 
886
    true;
 
887
arith_operator(_,_) ->
 
888
    false.
 
889
 
 
890
cmp_operator('>',2) ->
 
891
    true;
 
892
cmp_operator('>=',2) ->
 
893
    true;
 
894
cmp_operator('<',2) ->
 
895
    true;
 
896
cmp_operator('=<',2) ->
 
897
    true;
 
898
cmp_operator('==',2) ->
 
899
    true;
 
900
cmp_operator('=:=',2) ->
 
901
    true;
 
902
cmp_operator('/=',2) -> 
 
903
    true;
 
904
cmp_operator('=/=',2) ->
 
905
    true;
 
906
cmp_operator(_,_) ->
 
907
    false.
 
908
 
 
909
is_operator(X,A,_) ->
 
910
    bool_operator(X,A) or arith_operator(X,A) or cmp_operator(X,A).
 
911
 
 
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).
 
915
 
 
916
is_ms_function(X,A,body) ->
 
917
    action_function(X,A) or guard_function(X,A) or bool_test(X,A);
 
918
 
 
919
is_ms_function(X,A,guard) ->
 
920
    guard_function(X,A) or bool_test(X,A).
664
921
 
665
922
fixup_environment(L,B) when is_list(L) ->    
666
923
    lists:map(fun(X) ->