1%% ``Licensed under the Apache License, Version 2.0 (the "License");
2%% you may not use this file except in compliance with the License.
3%% You may obtain a copy of the License at
4%%
5%%     http://www.apache.org/licenses/LICENSE-2.0
6%%
7%% Unless required by applicable law or agreed to in writing, software
8%% distributed under the License is distributed on an "AS IS" BASIS,
9%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10%% See the License for the specific language governing permissions and
11%% limitations under the License.
12%%
13%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
14%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
15%% AB. All Rights Reserved.''
16%%
17%%     $Id: sys_pre_expand.erl,v 1.1 2008/12/17 09:53:42 mikpe Exp $
18%%
19%% Purpose : Expand some source Erlang constructions. This is part of the
20%%           pre-processing phase.
21
22%% N.B. Although structs (tagged tuples) are not yet allowed in the
23%% language there is code included in pattern/2 and expr/3 (commented out)
24%% that handles them by transforming them to tuples.
25
26-module(sys_pre_expand).
27
28%% Main entry point.
29-export([module/2]).
30
31-import(ordsets, [from_list/1,add_element/2,
32		  union/1,union/2,intersection/1,intersection/2,subtract/2]).
33-import(lists,   [member/2,map/2,foldl/3,foldr/3,sort/1,reverse/1,duplicate/2]).
34
35-include("../my_include/erl_bits.hrl").
36
37-record(expand, {module=[],			%Module name
38		 parameters=undefined,		%Module parameters
39		 package="",			%Module package
40		 exports=[],			%Exports
41		 imports=[],			%Imports
42		 mod_imports,			%Module Imports
43		 compile=[],			%Compile flags
44		 records=dict:new(),		%Record definitions
45		 attributes=[],			%Attributes
46		 defined=[],			%Defined functions
47		 vcount=0,			%Variable counter
48		 func=[],			%Current function
49		 arity=[],			%Arity for current function
50		 fcount=0,			%Local fun count
51		 fun_index=0,			%Global index for funs
52		 bitdefault,
53		 bittypes
54		}).
55
56%% module(Forms, CompileOptions)
57%%	{ModuleName,Exports,TransformedForms}
58%%  Expand the forms in one module. N.B.: the lists of predefined
59%%  exports and imports are really ordsets!
60
61module(Fs, Opts) ->
62    %% Set pre-defined exported functions.
63    PreExp = [{module_info,0},{module_info,1}],
64
65    %% Set pre-defined module imports.
66    PreModImp = [{erlang,erlang},{packages,packages}],
67
68    %% Build initial expand record.
69    St0 = #expand{exports=PreExp,
70		  mod_imports=dict:from_list(PreModImp),
71		  compile=Opts,
72		  defined=PreExp,
73		  bitdefault = erl_bits:system_bitdefault(),
74		  bittypes = erl_bits:system_bittypes()
75		 },
76    %% Expand the functions.
77    {Tfs,St1} = forms(Fs, foldl(fun define_function/2, St0, Fs)),
78    {Efs,St2} = expand_pmod(Tfs, St1),
79    %% Get the correct list of exported functions.
80    Exports = case member(export_all, St2#expand.compile) of
81		  true -> St2#expand.defined;
82		  false -> St2#expand.exports
83	      end,
84    %% Generate all functions from stored info.
85    {Ats,St3} = module_attrs(St2#expand{exports = Exports}),
86    {Mfs,St4} = module_predef_funcs(St3),
87    {St4#expand.module, St4#expand.exports, Ats ++ Efs ++ Mfs,
88     St4#expand.compile}.
89
90expand_pmod(Fs0, St) ->
91    case St#expand.parameters of
92	undefined ->
93	    {Fs0,St};
94	Ps ->
95	    {Fs1,Xs,Ds} = sys_expand_pmod:forms(Fs0, Ps,
96						St#expand.exports,
97						St#expand.defined),
98	    A = length(Ps),
99	    Vs = [{var,0,V} || V <- Ps],
100	    N = {atom,0,St#expand.module},
101	    B = [{tuple,0,[N|Vs]}],
102	    F = {function,0,new,A,[{clause,0,Vs,[],B}]},
103	    As = St#expand.attributes,
104	    {[F|Fs1],St#expand{exports=add_element({new,A}, Xs),
105			       defined=add_element({new,A}, Ds),
106			       attributes = [{abstract, true} | As]}}
107    end.
108
109%% -type define_function(Form, State) -> State.
110%%  Add function to defined if form a function.
111
112define_function({function,_,N,A,_Cs}, St) ->
113    St#expand{defined=add_element({N,A}, St#expand.defined)};
114define_function(_, St) -> St.
115
116module_attrs(St) ->
117    {[{attribute,0,Name,Val} || {Name,Val} <- St#expand.attributes],St}.
118
119module_predef_funcs(St) ->
120    PreDef = [{module_info,0},{module_info,1}],
121    PreExp = PreDef,
122    {[{function,0,module_info,0,
123       [{clause,0,[],[],
124        [{call,0,{remote,0,{atom,0,erlang},{atom,0,get_module_info}},
125          [{atom,0,St#expand.module}]}]}]},
126      {function,0,module_info,1,
127       [{clause,0,[{var,0,'X'}],[],
128        [{call,0,{remote,0,{atom,0,erlang},{atom,0,get_module_info}},
129          [{atom,0,St#expand.module},{var,0,'X'}]}]}]}],
130     St#expand{defined=union(from_list(PreDef), St#expand.defined),
131	       exports=union(from_list(PreExp), St#expand.exports)}}.
132
133%% forms(Forms, State) ->
134%%	{TransformedForms,State'}
135%%  Process the forms. Attributes are lost and just affect the state.
136%%  Ignore uninteresting forms like eof and type.
137
138forms([{attribute,_,Name,Val}|Fs0], St0) ->
139    St1 = attribute(Name, Val, St0),
140    forms(Fs0, St1);
141forms([{function,L,N,A,Cs}|Fs0], St0) ->
142    {Ff,St1} = function(L, N, A, Cs, St0),
143    {Fs,St2} = forms(Fs0, St1),
144    {[Ff|Fs],St2};
145forms([_|Fs], St) -> forms(Fs, St);
146forms([], St) -> {[],St}.
147
148%% -type attribute(Attribute, Value, State) ->
149%%	State.
150%%  Process an attribute, this just affects the state.
151
152attribute(module, {Module, As}, St) ->
153    true = is_atom(Module),
154    St#expand{module=Module,
155	      parameters=As};
156attribute(module, Module, St) ->
157    true = is_atom(Module),
158    St#expand{module=Module};
159attribute(export, Es, St) ->
160    St#expand{exports=union(from_list(Es), St#expand.exports)};
161attribute(import, Is, St) ->
162    import(Is, St);
163attribute(compile, C, St) when list(C) ->
164    St#expand{compile=St#expand.compile ++ C};
165attribute(compile, C, St) ->
166    St#expand{compile=St#expand.compile ++ [C]};
167attribute(record, {Name,Defs}, St) ->
168    St#expand{records=dict:store(Name, normalise_fields(Defs),
169				 St#expand.records)};
170attribute(file, _File, St) -> St;		%This is ignored
171attribute(Name, Val, St) when list(Val) ->
172    St#expand{attributes=St#expand.attributes ++ [{Name,Val}]};
173attribute(Name, Val, St) ->
174    St#expand{attributes=St#expand.attributes ++ [{Name,[Val]}]}.
175
176function(L, N, A, Cs0, St0) ->
177    {Cs,St} = clauses(Cs0, St0#expand{func=N,arity=A,fcount=0}),
178    {{function,L,N,A,Cs},St}.
179
180%% -type clauses([Clause], State) ->
181%%	{[TransformedClause],State}.
182%%  Expand function clauses.
183
184clauses([{clause,Line,H0,G0,B0}|Cs0], St0) ->
185    {H,Hvs,_Hus,St1} = head(H0, St0),
186    {G,Gvs,_Gus,St2} = guard(G0, Hvs, St1),
187    {B,_Bvs,_Bus,St3} = exprs(B0, union(Hvs, Gvs), St2),
188    {Cs,St4} = clauses(Cs0, St3),
189    {[{clause,Line,H,G,B}|Cs],St4};
190clauses([], St) -> {[],St}.
191
192%% head(HeadPatterns, State) ->
193%%	{TransformedPatterns,Variables,UsedVariables,State'}
194
195head(As, St) -> pattern_list(As, St).
196
197%% pattern(Pattern, State) ->
198%%	{TransformedPattern,Variables,UsedVariables,State'}
199%% BITS: added used variables for bit patterns with varaible length
200%%
201
202pattern({var,_,'_'}=Var, St) ->			%Ignore anonymous variable.
203    {Var,[],[],St};
204pattern({var,_,V}=Var, St) ->
205    {Var,[V],[],St};
206pattern({char,_,_}=Char, St) ->
207    {Char,[],[],St};
208pattern({integer,_,_}=Int, St) ->
209    {Int,[],[],St};
210pattern({float,_,_}=Float, St) ->
211    {Float,[],[],St};
212pattern({atom,_,_}=Atom, St) ->
213    {Atom,[],[],St};
214pattern({string,_,_}=String, St) ->
215    {String,[],[],St};
216pattern({nil,_}=Nil, St) ->
217    {Nil,[],[],St};
218pattern({cons,Line,H,T}, St0) ->
219    {TH,THvs,Hus,St1} = pattern(H, St0),
220    {TT,TTvs,Tus,St2} = pattern(T, St1),
221    {{cons,Line,TH,TT},union(THvs, TTvs),union(Hus,Tus),St2};
222pattern({tuple,Line,Ps}, St0) ->
223    {TPs,TPsvs,Tus,St1} = pattern_list(Ps, St0),
224    {{tuple,Line,TPs},TPsvs,Tus,St1};
225%%pattern({struct,Line,Tag,Ps}, St0) ->
226%%    {TPs,TPsvs,St1} = pattern_list(Ps, St0),
227%%    {{tuple,Line,[{atom,Line,Tag}|TPs]},TPsvs,St1};
228pattern({record_index,Line,Name,Field}, St) ->
229    {index_expr(Line, Field, Name, record_fields(Name, St)),[],[],St};
230pattern({record,Line,Name,Pfs}, St0) ->
231    Fs = record_fields(Name, St0),
232    {TMs,TMsvs,Us,St1} = pattern_list(pattern_fields(Fs, Pfs), St0),
233    {{tuple,Line,[{atom,Line,Name}|TMs]},TMsvs,Us,St1};
234pattern({bin,Line,Es0}, St0) ->
235    {Es1,Esvs,Esus,St1} = pattern_bin(Es0, St0),
236    {{bin,Line,Es1},Esvs,Esus,St1};
237pattern({op,_,'++',{nil,_},R}, St) ->
238    pattern(R, St);
239pattern({op,_,'++',{cons,Li,H,T},R}, St) ->
240    pattern({cons,Li,H,{op,Li,'++',T,R}}, St);
241pattern({op,_,'++',{string,Li,L},R}, St) ->
242    pattern(string_to_conses(Li, L, R), St);
243pattern({match,Line,Pat1, Pat2}, St0) ->
244    {TH,Hvt,Hus,St1} = pattern(Pat2, St0),
245    {TT,Tvt,Tus,St2} = pattern(Pat1, St1),
246    {{match,Line,TT,TH}, union(Hvt,Tvt), union(Hus,Tus), St2};
247%% Compile-time pattern expressions, including unary operators.
248pattern({op,Line,Op,A}, St) ->
249    { erl_eval:partial_eval({op,Line,Op,A}), [], [], St};
250pattern({op,Line,Op,L,R}, St) ->
251    { erl_eval:partial_eval({op,Line,Op,L,R}), [], [], St}.
252
253pattern_list([P0|Ps0], St0) ->
254    {P,Pvs,Pus,St1} = pattern(P0, St0),
255    {Ps,Psvs,Psus,St2} = pattern_list(Ps0, St1),
256    {[P|Ps],union(Pvs, Psvs),union(Pus, Psus),St2};
257pattern_list([], St) -> {[],[],[],St}.
258
259%% guard(Guard, VisibleVariables, State) ->
260%%	{TransformedGuard,NewVariables,UsedVariables,State'}
261%%  Transform a list of guard tests. We KNOW that this has been checked
262%%  and what the guards test are. Use expr for transforming the guard
263%%  expressions.
264
265guard([G0|Gs0], Vs, St0) ->
266    {G,Hvs,Hus,St1} = guard_tests(G0, Vs, St0),
267    {Gs,Tvs,Tus,St2} = guard(Gs0, Vs, St1),
268    {[G|Gs],union(Hvs, Tvs),union(Hus, Tus),St2};
269guard([], _, St) -> {[],[],[],St}.
270
271guard_tests([Gt0|Gts0], Vs, St0) ->
272    {Gt1,Gvs,Gus,St1} = guard_test(Gt0, Vs, St0),
273    {Gts1,Gsvs,Gsus,St2} = guard_tests(Gts0, union(Gvs, Vs), St1),
274    {[Gt1|Gts1],union(Gvs, Gsvs),union(Gus, Gsus),St2};
275guard_tests([], _, St) -> {[],[],[],St}.
276
277guard_test({call,Line,{atom,_,record},[A,{atom,_,Name}]}, Vs, St) ->
278    record_test_in_guard(Line, A, Name, Vs, St);
279guard_test({call,Line,{atom,Lt,Tname},As}, Vs, St) ->
280    %% XXX This is ugly. We can remove this workaround if/when
281    %% we'll allow 'andalso' in guards. For now, we must have
282    %% different code in guards and in bodies.
283    Test = {remote,Lt,
284	    {atom,Lt,erlang},
285	    {atom,Lt,normalise_test(Tname, length(As))}},
286    put(sys_pre_expand_in_guard, yes),
287    R = expr({call,Line,Test,As}, Vs, St),
288    erase(sys_pre_expand_in_guard),
289    R;
290guard_test(Test, Vs, St) ->
291    %% XXX See the previous clause.
292    put(sys_pre_expand_in_guard, yes),
293    R = expr(Test, Vs, St),
294    erase(sys_pre_expand_in_guard),
295    R.
296
297%% record_test(Line, Term, Name, Vs, St) -> TransformedExpr
298%%  Generate code for is_record/1.
299
300record_test(Line, Term, Name, Vs, St) ->
301    case get(sys_pre_expand_in_guard) of
302	undefined ->
303	    record_test_in_body(Line, Term, Name, Vs, St);
304	yes ->
305	    record_test_in_guard(Line, Term, Name, Vs, St)
306    end.
307
308record_test_in_guard(Line, Term, Name, Vs, St) ->
309    %% Notes: (1) To keep is_record/3 properly atomic (e.g. when inverted
310    %%            using 'not'), we cannot convert it to an instruction
311    %%            sequence here. It must remain a single call.
312    %%        (2) Later passes assume that the last argument (the size)
313    %%            is a literal.
314    %%        (3) We don't want calls to erlang:is_record/3 (in the source code)
315    %%            confused we the internal instruction. (Reason: (2) above +
316    %%            code bloat.)
317    %%        (4) Xref may be run on the abstract code, so the name in the
318    %%            abstract code must be erlang:is_record/3.
319    %%        (5) To achieve both (3) and (4) at the same time, set the name
320    %%            here to erlang:is_record/3, but mark it as compiler-generated.
321    %%            The v3_core pass will change the name to erlang:internal_is_record/3.
322    Fs = record_fields(Name, St),
323    expr({call,-Line,{remote,-Line,{atom,-Line,erlang},{atom,-Line,is_record}},
324	  [Term,{atom,Line,Name},{integer,Line,length(Fs)+1}]},
325	 Vs, St).
326
327record_test_in_body(Line, Expr, Name, Vs, St0) ->
328    %% As Expr may have side effects, we must evaluate it
329    %% first and bind the value to a new variable.
330    %% We must use also handle the case that Expr does not
331    %% evaluate to a tuple properly.
332    Fs = record_fields(Name, St0),
333    {Var,St} = new_var(Line, St0),
334
335    expr({block,Line,
336	  [{match,Line,Var,Expr},
337	   {op,Line,
338	    'andalso',
339	    {call,Line,{atom,Line,is_tuple},[Var]},
340	    {op,Line,'andalso',
341	     {op,Line,'=:=',
342	      {call,Line,{atom,Line,size},[Var]},
343	      {integer,Line,length(Fs)+1}},
344	     {op,Line,'=:=',
345	      {call,Line,{atom,Line,element},[{integer,Line,1},Var]},
346	      {atom,Line,Name}}}}]}, Vs, St).
347
348normalise_test(atom, 1)      -> is_atom;
349normalise_test(binary, 1)    -> is_binary;
350normalise_test(constant, 1)  -> is_constant;
351normalise_test(float, 1)     -> is_float;
352normalise_test(function, 1)  -> is_function;
353normalise_test(integer, 1)   -> is_integer;
354normalise_test(list, 1)      -> is_list;
355normalise_test(number, 1)    -> is_number;
356normalise_test(pid, 1)       -> is_pid;
357normalise_test(port, 1)      -> is_port;
358normalise_test(reference, 1) -> is_reference;
359normalise_test(tuple, 1)     -> is_tuple;
360normalise_test(Name, _) -> Name.
361
362%% exprs(Expressions, VisibleVariables, State) ->
363%%	{TransformedExprs,NewVariables,UsedVariables,State'}
364
365exprs([E0|Es0], Vs, St0) ->
366    {E,Evs,Eus,St1} = expr(E0, Vs, St0),
367    {Es,Esvs,Esus,St2} = exprs(Es0, union(Evs, Vs), St1),
368    {[E|Es],union(Evs, Esvs),union(Eus, Esus),St2};
369exprs([], _, St) -> {[],[],[],St}.
370
371%% expr(Expression, VisibleVariables, State) ->
372%%	{TransformedExpression,NewVariables,UsedVariables,State'}
373
374expr({var,_,V}=Var, _Vs, St) ->
375    {Var,[],[V],St};
376expr({char,_,_}=Char, _Vs, St) ->
377    {Char,[],[],St};
378expr({integer,_,_}=Int, _Vs, St) ->
379    {Int,[],[],St};
380expr({float,_,_}=Float, _Vs, St) ->
381    {Float,[],[],St};
382expr({atom,_,_}=Atom, _Vs, St) ->
383    {Atom,[],[],St};
384expr({string,_,_}=String, _Vs, St) ->
385    {String,[],[],St};
386expr({nil,_}=Nil, _Vs, St) ->
387    {Nil,[],[],St};
388expr({cons,Line,H0,T0}, Vs, St0) ->
389    {H,Hvs,Hus,St1} = expr(H0, Vs, St0),
390    {T,Tvs,Tus,St2} = expr(T0, Vs, St1),
391    {{cons,Line,H,T},union(Hvs, Tvs),union(Hus, Tus),St2};
392expr({lc,Line,E0,Qs0}, Vs, St0) ->
393    {E1,Qs1,_,Lvs,Lus,St1} = lc_tq(Line, E0, Qs0, {nil,Line}, Vs, St0),
394    {{lc,Line,E1,Qs1},Lvs,Lus,St1};
395expr({tuple,Line,Es0}, Vs, St0) ->
396    {Es1,Esvs,Esus,St1} = expr_list(Es0, Vs, St0),
397    {{tuple,Line,Es1},Esvs,Esus,St1};
398%%expr({struct,Line,Tag,Es0}, Vs, St0) ->
399%%    {Es1,Esvs,Esus,St1} = expr_list(Es0, Vs, St0),
400%%    {{tuple,Line,[{atom,Line,Tag}|Es1]},Esvs,Esus,St1};
401expr({record_index,Line,Name,F}, Vs, St) ->
402    I = index_expr(Line, F, Name, record_fields(Name, St)),
403    expr(I, Vs, St);
404expr({record,Line,Name,Is}, Vs, St) ->
405    expr({tuple,Line,[{atom,Line,Name}|
406		      record_inits(record_fields(Name, St), Is)]},
407	 Vs, St);
408expr({record_field,Line,R,Name,F}, Vs, St) ->
409    I = index_expr(Line, F, Name, record_fields(Name, St)),
410    expr({call,Line,{atom,Line,element},[I,R]}, Vs, St);
411expr({record,_,R,Name,Us}, Vs, St0) ->
412    {Ue,St1} = record_update(R, Name, record_fields(Name, St0), Us, St0),
413    expr(Ue, Vs, St1);
414expr({bin,Line,Es0}, Vs, St0) ->
415    {Es1,Esvs,Esus,St1} = expr_bin(Es0, Vs, St0),
416    {{bin,Line,Es1},Esvs,Esus,St1};
417expr({block,Line,Es0}, Vs, St0) ->
418    {Es,Esvs,Esus,St1} = exprs(Es0, Vs, St0),
419    {{block,Line,Es},Esvs,Esus,St1};
420expr({'if',Line,Cs0}, Vs, St0) ->
421    {Cs,Csvss,Csuss,St1} = icr_clauses(Cs0, Vs, St0),
422    All = new_in_all(Vs, Csvss),
423    {{'if',Line,Cs},All,union(Csuss),St1};
424expr({'case',Line,E0,Cs0}, Vs, St0) ->
425    {E,Evs,Eus,St1} = expr(E0, Vs, St0),
426    {Cs,Csvss,Csuss,St2} = icr_clauses(Cs0, union(Evs, Vs), St1),
427    All = new_in_all(Vs, Csvss),
428    {{'case',Line,E,Cs},union(Evs, All),union([Eus|Csuss]),St2};
429expr({'cond',Line,Cs}, Vs, St0) ->
430    {V,St1} = new_var(Line,St0),
431    expr(cond_clauses(Cs,V), Vs, St1);
432expr({'receive',Line,Cs0}, Vs, St0) ->
433    {Cs,Csvss,Csuss,St1} = icr_clauses(Cs0, Vs, St0),
434    All = new_in_all(Vs, Csvss),
435    {{'receive',Line,Cs},All,union(Csuss),St1};
436expr({'receive',Line,Cs0,To0,ToEs0}, Vs, St0) ->
437    {To,Tovs,Tous,St1} = expr(To0, Vs, St0),
438    {ToEs,ToEsvs,_ToEsus,St2} = exprs(ToEs0, Vs, St1),
439    {Cs,Csvss,Csuss,St3} = icr_clauses(Cs0, Vs, St2),
440    All = new_in_all(Vs, [ToEsvs|Csvss]),
441    {{'receive',Line,Cs,To,ToEs},union(Tovs, All),union([Tous|Csuss]),St3};
442expr({'fun',Line,Body}, Vs, St) ->
443    fun_tq(Line, Body, Vs, St);
444%%% expr({call,_,{atom,La,this_module},[]}, _Vs, St) ->
445%%%     {{atom,La,St#expand.module}, [], [], St};
446%%% expr({call,_,{atom,La,this_package},[]}, _Vs, St) ->
447%%%     {{atom,La,list_to_atom(St#expand.package)}, [], [], St};
448%%% expr({call,_,{atom,La,this_package},[{atom,_,Name}]}, _Vs, St) ->
449%%%     M = packages:concat(St#expand.package,Name),
450%%%     {{atom,La,list_to_atom(M)}, [], [], St};
451%%% expr({call,Line,{atom,La,this_package},[A]}, Vs, St) ->
452%%%     M = {call,Line,{remote,La,{atom,La,packages},{atom,La,concat}},
453%%% 	 [{string,La,St#expand.package}, A]},
454%%%     expr({call,Line,{atom,Line,list_to_atom},[M]}, Vs, St);
455expr({call,Line,{atom,_,is_record},[A,{atom,_,Name}]}, Vs, St) ->
456    record_test(Line, A, Name, Vs, St);
457expr({call,Line,{remote,_,{atom,_,erlang},{atom,_,is_record}},
458      [A,{atom,_,Name}]}, Vs, St) ->
459    record_test(Line, A, Name, Vs, St);
460expr({call,Line,{atom,La,N},As0}, Vs, St0) ->
461    {As,Asvs,Asus,St1} = expr_list(As0, Vs, St0),
462    Ar = length(As),
463    case erl_internal:bif(N, Ar) of
464	true ->
465	    {{call,Line,{remote,La,{atom,La,erlang},{atom,La,N}},As},
466	     Asvs,Asus,St1};
467	false ->
468	    case imported(N, Ar, St1) of
469		{yes,Mod} ->
470		    {{call,Line,{remote,La,{atom,La,Mod},{atom,La,N}},As},
471		     Asvs,Asus,St1};
472		no ->
473		    case {N,Ar} of
474			{record_info,2} ->
475			    record_info_call(Line, As, St1);
476			_ ->
477			    {{call,Line,{atom,La,N},As},Asvs,Asus,St1}
478		    end
479	    end
480    end;
481expr({call,Line,{remote,Lr,M1,F},As0}, Vs, St0) ->
482    {[M2,F1|As1],Asvs,Asus,St1} = expr_list([M1,F|As0], Vs, St0),
483    {{call,Line,{remote,Lr,M2,F1},As1},Asvs,Asus,St1};
484expr({call,Line,{tuple,_,[{atom,_,_}=M,{atom,_,_}=F]},As}, Vs, St) ->
485    %% Rewrite {Mod,Function}(Args...) to Mod:Function(Args...).
486    expr({call,Line,{remote,Line,M,F},As}, Vs, St);
487expr({call,Line,F,As0}, Vs, St0) ->
488    {[Fun1|As1],Asvs,Asus,St1} = expr_list([F|As0], Vs, St0),
489    {{call,Line,Fun1,As1},Asvs,Asus,St1};
490expr({'try',Line,Es0,Scs0,Ccs0,As0}, Vs, St0) ->
491    {Es1,Esvs,Esus,St1} = exprs(Es0, Vs, St0),
492    Cvs = union(Esvs, Vs),
493    {Scs1,Scsvss,Scsuss,St2} = icr_clauses(Scs0, Cvs, St1),
494    {Ccs1,Ccsvss,Ccsuss,St3} = icr_clauses(Ccs0, Cvs, St2),
495    Csvss = Scsvss ++ Ccsvss,
496    Csuss = Scsuss ++ Ccsuss,
497    All = new_in_all(Vs, Csvss),
498    {As1,Asvs,Asus,St4} = exprs(As0, Cvs, St3),
499    {{'try',Line,Es1,Scs1,Ccs1,As1}, union([Asvs,Esvs,All]),
500     union([Esus,Asus|Csuss]), St4};
501expr({'catch',Line,E0}, Vs, St0) ->
502    %% Catch exports no new variables.
503    {E,_Evs,Eus,St1} = expr(E0, Vs, St0),
504    {{'catch',Line,E},[],Eus,St1};
505expr({match,Line,P0,E0}, Vs, St0) ->
506    {E,Evs,Eus,St1} = expr(E0, Vs, St0),
507    {P,Pvs,Pus,St2} = pattern(P0, St1),
508    {{match,Line,P,E},
509     union(subtract(Pvs, Vs), Evs),
510     union(intersection(Pvs, Vs), union(Eus,Pus)),St2};
511expr({op,L,'andalso',E1,E2}, Vs, St0) ->
512    {V,St1} = new_var(L,St0),
513    E = make_bool_switch(L,E1,V,
514			 make_bool_switch(L,E2,V,{atom,L,true},
515					  {atom,L,false}),
516			 {atom,L,false}),
517    expr(E, Vs, St1);
518expr({op,L,'orelse',E1,E2}, Vs, St0) ->
519    {V,St1} = new_var(L,St0),
520    E = make_bool_switch(L,E1,V,{atom,L,true},
521			 make_bool_switch(L,E2,V,{atom,L,true},
522					  {atom,L,false})),
523    expr(E, Vs, St1);
524expr({op,Line,'++',{lc,Ll,E0,Qs0},M0}, Vs, St0) ->
525    {E1,Qs1,M1,Lvs,Lus,St1} = lc_tq(Ll, E0, Qs0, M0, Vs, St0),
526    {{op,Line,'++',{lc,Ll,E1,Qs1},M1},Lvs,Lus,St1};
527expr({op,_,'++',{string,L1,S1},{string,_,S2}}, _Vs, St) ->
528    {{string,L1,S1 ++ S2},[],[],St};
529expr({op,Ll,'++',{string,L1,S1}=Str,R0}, Vs, St0) ->
530    {R1,Rvs,Rus,St1} = expr(R0, Vs, St0),
531    E = case R1 of
532	    {string,_,S2} -> {string,L1,S1 ++ S2};
533	    _Other when length(S1) < 8 -> string_to_conses(L1, S1, R1);
534	    _Other -> {op,Ll,'++',Str,R1}
535	end,
536    {E,Rvs,Rus,St1};
537expr({op,Ll,'++',{cons,Lc,H,T},L2}, Vs, St) ->
538    expr({cons,Ll,H,{op,Lc,'++',T,L2}}, Vs, St);
539expr({op,_,'++',{nil,_},L2}, Vs, St) ->
540    expr(L2, Vs, St);
541expr({op,Line,Op,A0}, Vs, St0) ->
542    {A,Avs,Aus,St1} = expr(A0, Vs, St0),
543    {{op,Line,Op,A},Avs,Aus,St1};
544expr({op,Line,Op,L0,R0}, Vs, St0) ->
545    {L,Lvs,Lus,St1} = expr(L0, Vs, St0),
546    {R,Rvs,Rus,St2} = expr(R0, Vs, St1),
547    {{op,Line,Op,L,R},union(Lvs, Rvs),union(Lus, Rus),St2}.
548
549expr_list([E0|Es0], Vs, St0) ->
550    {E,Evs,Eus,St1} = expr(E0, Vs, St0),
551    {Es,Esvs,Esus,St2} = expr_list(Es0, Vs, St1),
552    {[E|Es],union(Evs, Esvs),union(Eus, Esus),St2};
553expr_list([], _, St) ->
554    {[],[],[],St}.
555
556%% icr_clauses([Clause], [VisibleVariable], State) ->
557%%	{[TransformedClause],[[NewVariable]],[[UsedVariable]],State'}
558%%  Be very careful here to return the variables that are really used
559%%  and really new.
560
561icr_clauses([], _, St) ->
562    {[],[[]],[],St};
563icr_clauses(Clauses, Vs, St) ->
564    icr_clauses2(Clauses, Vs, St).
565
566icr_clauses2([{clause,Line,H0,G0,B0}|Cs0], Vs, St0) ->
567    {H,Hvs,Hus,St1} = head(H0, St0),		%Hvs is really used!
568    {G,Gvs,Gus,St2} = guard(G0, union(Hvs, Vs), St1),
569    {B,Bvs,Bus,St3} = exprs(B0, union([Vs,Hvs,Gvs]), St2),
570    New = subtract(union([Hvs,Gvs,Bvs]), Vs),	%Really new
571    Used = intersection(union([Hvs,Hus,Gus,Bus]), Vs), %Really used
572    {Cs,Csvs,Csus,St4} = icr_clauses2(Cs0, Vs, St3),
573    {[{clause,Line,H,G,B}|Cs],[New|Csvs],[Used|Csus],St4};
574icr_clauses2([], _, St) ->
575    {[],[],[],St}.
576
577%% lc_tq(Line, Expr, Qualifiers, More, [VisibleVar], State) ->
578%%	{TransExpr,[TransQual],TransMore,[NewVar],[UsedVar],State'}
579
580lc_tq(Line, E0, [{generate,Lg,P0,G0}|Qs0], M0, Vs, St0) ->
581    {G1,Gvs,Gus,St1} = expr(G0, Vs, St0),
582    {P1,Pvs,Pus,St2} = pattern(P0, St1),
583    {E1,Qs1,M1,Lvs,Lus,St3} = lc_tq(Line, E0, Qs0, M0, union(Pvs, Vs), St2),
584    {E1,[{generate,Lg,P1,G1}|Qs1],M1,
585     union(Gvs, Lvs),union([Gus,Pus,Lus]),St3};
586lc_tq(Line, E0, [F0|Qs0], M0, Vs, St0) ->
587    %% Allow record/2 and expand out as guard test.
588    case erl_lint:is_guard_test(F0) of
589	true ->
590	    {F1,Fvs,_Fus,St1} = guard_tests([F0], Vs, St0),
591	    {E1,Qs1,M1,Lvs,Lus,St2} = lc_tq(Line, E0, Qs0, M0, union(Fvs, Vs), St1),
592	    {E1,F1++Qs1,M1,Lvs,Lus,St2};
593	false ->
594	    {F1,Fvs,_Fus,St1} = expr(F0, Vs, St0),
595	    {E1,Qs1,M1,Lvs,Lus,St2} = lc_tq(Line, E0, Qs0, M0, union(Fvs, Vs), St1),
596	    {E1,[F1|Qs1],M1,Lvs,Lus,St2}
597    end;
598lc_tq(_Line, E0, [], M0, Vs, St0) ->
599    {E1,Evs,Eus,St1} = expr(E0, Vs, St0),
600    {M1,Mvs,Mus,St2} = expr(M0, Vs, St1),
601    {E1,[],M1,union(Evs, Mvs),union(Eus, Mus),St2}.
602
603%% fun_tq(Line, Body, VisibleVariables, State) ->
604%%	{Fun,NewVariables,UsedVariables,State'}
605%% Transform an "explicit" fun {'fun', Line, {clauses, Cs}} into an
606%% extended form {'fun', Line, {clauses, Cs}, Info}, unless it is the
607%% name of a BIF (erl_lint has checked that it is not an import).
608%% Process the body sequence directly to get the new and used variables.
609%% "Implicit" funs {'fun', Line, {function, F, A}} are not changed.
610
611fun_tq(Lf, {function,F,A}, Vs, St0) ->
612    {As,St1} = new_vars(A, Lf, St0),
613    Cs = [{clause,Lf,As,[],[{call,Lf,{atom,Lf,F},As}]}],
614    case erl_internal:bif(F, A) of
615	true ->
616	    fun_tq(Lf, {clauses,Cs}, Vs, St1);
617	false ->
618	    Index = St0#expand.fun_index,
619	    Uniq = erlang:hash(Cs, (1 bsl 27)-1),
620	    {Fname,St2} = new_fun_name(St1),
621	    {{'fun',Lf,{function,F,A},{Index,Uniq,Fname}},[],[],
622	     St2#expand{fun_index=Index+1}}
623    end;
624fun_tq(Lf, {clauses,Cs0}, Vs, St0) ->
625    Uniq = erlang:hash(Cs0, (1 bsl 27)-1),
626    {Cs1,_Hvss,Frees,St1} = fun_clauses(Cs0, Vs, St0),
627    Ufrees = union(Frees),
628    Index = St1#expand.fun_index,
629    {Fname,St2} = new_fun_name(St1),
630    {{'fun',Lf,{clauses,Cs1},{Index,Uniq,Fname}},[],Ufrees,
631     St2#expand{fun_index=Index+1}}.
632
633fun_clauses([{clause,L,H0,G0,B0}|Cs0], Vs, St0) ->
634    {H,Hvs,Hus,St1} = head(H0, St0),
635    {G,Gvs,Gus,St2} = guard(G0, union(Hvs, Vs), St1),
636    {B,Bvs,Bus,St3} = exprs(B0, union([Vs,Hvs,Gvs]), St2),
637    %% Free variables cannot be new anywhere in the clause.
638    Free = subtract(union([Gus,Hus,Bus]), union([Hvs,Gvs,Bvs])),
639    %%io:format(" Gus :~p~n Bvs :~p~n Bus :~p~n Free:~p~n" ,[Gus,Bvs,Bus,Free]),
640    {Cs,Hvss,Frees,St4} = fun_clauses(Cs0, Vs, St3),
641    {[{clause,L,H,G,B}|Cs],[Hvs|Hvss],[Free|Frees],St4};
642fun_clauses([], _, St) -> {[],[],[],St}.
643
644%% new_fun_name(State) -> {FunName,State}.
645
646new_fun_name(#expand{func=F,arity=A,fcount=I}=St) ->
647    Name = "-" ++ atom_to_list(F) ++ "/" ++ integer_to_list(A)
648	++ "-fun-" ++ integer_to_list(I) ++ "-",
649    {list_to_atom(Name),St#expand{fcount=I+1}}.
650
651
652%% normalise_fields([RecDef]) -> [Field].
653%%  Normalise the field definitions to always have a default value. If
654%%  none has been given then use 'undefined'.
655
656normalise_fields(Fs) ->
657    map(fun ({record_field,Lf,Field}) ->
658		{record_field,Lf,Field,{atom,Lf,undefined}};
659	    (F) -> F end, Fs).
660
661%% record_fields(RecordName, State)
662%% find_field(FieldName, Fields)
663
664record_fields(R, St) -> dict:fetch(R, St#expand.records).
665
666find_field(F, [{record_field,_,{atom,_,F},Val}|_]) -> {ok,Val};
667find_field(F, [_|Fs]) -> find_field(F, Fs);
668find_field(_, []) -> error.
669
670%% field_names(RecFields) -> [Name].
671%%  Return a list of the field names structures.
672
673field_names(Fs) ->
674    map(fun ({record_field,_,Field,_Val}) -> Field end, Fs).
675
676%% index_expr(Line, FieldExpr, Name, Fields) -> IndexExpr.
677%%  Return an expression which evaluates to the index of a
678%%  field. Currently only handle the case where the field is an
679%%  atom. This expansion must be passed through expr again.
680
681index_expr(Line, {atom,_,F}, _Name, Fs) ->
682    {integer,Line,index_expr(F, Fs, 2)}.
683
684index_expr(F, [{record_field,_,{atom,_,F},_}|_], I) -> I;
685index_expr(F, [_|Fs], I) ->
686    index_expr(F, Fs, I+1).
687
688%% pattern_fields([RecDefField], [Match]) -> [Pattern].
689%%  Build a list of match patterns for the record tuple elements.
690%%  This expansion must be passed through pattern again. N.B. We are
691%%  scanning the record definition field list!
692
693pattern_fields(Fs, Ms) ->
694    Wildcard = record_wildcard_init(Ms),
695    map(fun ({record_field,L,{atom,_,F},_}) ->
696		case find_field(F, Ms) of
697		    {ok,Match} -> Match;
698		    error when Wildcard =:= none -> {var,L,'_'};
699		    error -> Wildcard
700		end end,
701	Fs).
702
703%% record_inits([RecDefField], [Init]) -> [InitExpr].
704%%  Build a list of initialisation expressions for the record tuple
705%%  elements. This expansion must be passed through expr
706%%  again. N.B. We are scanning the record definition field list!
707
708record_inits(Fs, Is) ->
709    WildcardInit = record_wildcard_init(Is),
710    map(fun ({record_field,_,{atom,_,F},D}) ->
711		case find_field(F, Is) of
712		    {ok,Init} -> Init;
713		    error when WildcardInit =:= none -> D;
714		    error -> WildcardInit
715		end end,
716	Fs).
717
718record_wildcard_init([{record_field,_,{var,_,'_'},D}|_]) -> D;
719record_wildcard_init([_|Is]) -> record_wildcard_init(Is);
720record_wildcard_init([]) -> none.
721
722%% record_update(Record, RecordName, [RecDefField], [Update], State) ->
723%%	{Expr,State'}
724%%  Build an expression to update fields in a record returning a new
725%%  record.  Try to be smart and optimise this. This expansion must be
726%%  passed through expr again.
727
728record_update(R, Name, Fs, Us0, St0) ->
729    Line = element(2, R),
730    {Pre,Us,St1} = record_exprs(Us0, St0),
731    Nf = length(Fs),				%# of record fields
732    Nu = length(Us),				%# of update fields
733    Nc = Nf - Nu,				%# of copy fields
734
735    %% We need a new variable for the record expression
736    %% to guarantee that it is only evaluated once.
737    {Var,St2} = new_var(Line, St1),
738
739    %% Try to be intelligent about which method of updating record to use.
740    {Update,St} =
741	if
742	    Nu == 0 -> {R,St2};			%No fields updated
743	    Nu =< Nc ->				%Few fields updated
744		{record_setel(Var, Name, Fs, Us), St2};
745	    true ->			      %The wide area inbetween
746		record_match(Var, Name, Fs, Us, St2)
747	end,
748    {{block,element(2, R),Pre ++ [{match,Line,Var,R},Update]},St}.
749
750%% record_match(Record, RecordName, [RecDefField], [Update], State)
751%%  Build a 'case' expression to modify record fields.
752
753record_match(R, Name, Fs, Us, St0) ->
754    {Ps,News,St1} = record_upd_fs(Fs, Us, St0),
755    Lr = element(2, hd(Us)),
756    {{'case',Lr,R,
757      [{clause,Lr,[{tuple,Lr,[{atom,Lr,Name}|Ps]}],[],
758	[{tuple,Lr,[{atom,Lr,Name}|News]}]},
759       {clause,Lr,[{var,Lr,'_'}],[],
760	[call_error(Lr, {tuple,Lr,[{atom,Lr,badrecord},{atom,Lr,Name}]})]}
761      ]},
762     St1}.
763
764record_upd_fs([{record_field,Lf,{atom,_La,F},_Val}|Fs], Us, St0) ->
765    {P,St1} = new_var(Lf, St0),
766    {Ps,News,St2} = record_upd_fs(Fs, Us, St1),
767    case find_field(F, Us) of
768	{ok,New} -> {[P|Ps],[New|News],St2};
769	error -> {[P|Ps],[P|News],St2}
770    end;
771record_upd_fs([], _, St) -> {[],[],St}.
772
773%% record_setel(Record, RecordName, [RecDefField], [Update])
774%%  Build a nested chain of setelement calls to build the
775%%  updated record tuple.
776
777record_setel(R, Name, Fs, Us0) ->
778    Us1 = foldl(fun ({record_field,Lf,Field,Val}, Acc) ->
779			I = index_expr(Lf, Field, Name, Fs),
780			[{I,Lf,Val}|Acc]
781		end, [], Us0),
782    Us = sort(Us1),
783    Lr = element(2, hd(Us)),
784    Wildcards = duplicate(length(Fs), {var,Lr,'_'}),
785    {'case',Lr,R,
786     [{clause,Lr,[{tuple,Lr,[{atom,Lr,Name}|Wildcards]}],[],
787       [foldr(fun ({I,Lf,Val}, Acc) ->
788		      {call,Lf,{atom,Lf,setelement},[I,Acc,Val]} end,
789	      R, Us)]},
790      {clause,Lr,[{var,Lr,'_'}],[],
791       [call_error(Lr, {tuple,Lr,[{atom,Lr,badrecord},{atom,Lr,Name}]})]}]}.
792
793%% Expand a call to record_info/2. We have checked that it is not
794%% shadowed by an import.
795
796record_info_call(Line, [{atom,_Li,Info},{atom,_Ln,Name}], St) ->
797    case Info of
798	size ->
799	    {{integer,Line,1+length(record_fields(Name, St))},[],[],St};
800	fields ->
801	    {make_list(field_names(record_fields(Name, St)), Line),
802	     [],[],St}
803    end.
804
805%% Break out expressions from an record update list and bind to new
806%% variables. The idea is that we will evaluate all update expressions
807%% before starting to update the record.
808
809record_exprs(Us, St) ->
810    record_exprs(Us, St, [], []).
811
812record_exprs([{record_field,Lf,{atom,_La,_F}=Name,Val}=Field0|Us], St0, Pre, Fs) ->
813    case is_simple_val(Val) of
814	true ->
815	    record_exprs(Us, St0, Pre, [Field0|Fs]);
816	false ->
817	    {Var,St} = new_var(Lf, St0),
818	    Bind = {match,Lf,Var,Val},
819	    Field = {record_field,Lf,Name,Var},
820	    record_exprs(Us, St, [Bind|Pre], [Field|Fs])
821    end;
822record_exprs([], St, Pre, Fs) ->
823    {reverse(Pre),Fs,St}.
824
825is_simple_val({var,_,_}) -> true;
826is_simple_val({atom,_,_}) -> true;
827is_simple_val({integer,_,_}) -> true;
828is_simple_val({float,_,_}) -> true;
829is_simple_val({nil,_}) -> true;
830is_simple_val(_) -> false.
831
832%% pattern_bin([Element], State) -> {[Element],[Variable],[UsedVar],State}.
833
834pattern_bin(Es0, St) ->
835    Es1 = bin_expand_strings(Es0),
836    foldr(fun (E, Acc) -> pattern_element(E, Acc) end, {[],[],[],St}, Es1).
837
838pattern_element({bin_element,Line,Expr,Size,Type}, {Es,Esvs,Esus,St0}) ->
839    {Expr1,Vs1,Us1,St1} = pattern(Expr, St0),
840    {Size1,Vs2,Us2,St2} = pat_bit_size(Size, St1),
841    {Size2,Type1} = make_bit_type(Line, Size1,Type),
842    {[{bin_element,Line,Expr1,Size2,Type1}|Es],
843      union([Vs1,Vs2,Esvs]),union([Us1,Us2,Esus]),St2}.
844
845pat_bit_size(default, St) -> {default,[],[],St};
846pat_bit_size({atom,_La,all}=All, St) -> {All,[],[],St};
847pat_bit_size({var,_Lv,V}=Var, St) -> {Var,[],[V],St};
848pat_bit_size(Size, St) ->
849    Line = element(2, Size),
850    {value,Sz,_} = erl_eval:expr(Size, erl_eval:new_bindings()),
851    {{integer,Line,Sz},[],[],St}.
852
853make_bit_type(Line, default, Type0) ->
854    case erl_bits:set_bit_type(default, Type0) of
855	{ok,all,Bt} -> {{atom,Line,all},erl_bits:as_list(Bt)};
856	{ok,Size,Bt} -> {{integer,Line,Size},erl_bits:as_list(Bt)}
857    end;
858make_bit_type(_Line, Size, Type0) ->		%Integer or 'all'
859    {ok,Size,Bt} = erl_bits:set_bit_type(Size, Type0),
860    {Size,erl_bits:as_list(Bt)}.
861
862%% expr_bin([Element], [VisibleVar], State) ->
863%%              {[Element],[NewVar],[UsedVar],State}.
864
865expr_bin(Es0, Vs, St) ->
866    Es1 = bin_expand_strings(Es0),
867    foldr(fun (E, Acc) -> bin_element(E, Vs, Acc) end, {[],[],[],St}, Es1).
868
869bin_element({bin_element,Line,Expr,Size,Type}, Vs, {Es,Esvs,Esus,St0}) ->
870    {Expr1,Vs1,Us1,St1} = expr(Expr, Vs, St0),
871    {Size1,Vs2,Us2,St2} = if Size == default -> {default,[],[],St1};
872			     true -> expr(Size, Vs, St1)
873			  end,
874    {Size2,Type1} = make_bit_type(Line, Size1, Type),
875    {[{bin_element,Line,Expr1,Size2,Type1}|Es],
876     union([Vs1,Vs2,Esvs]),union([Us1,Us2,Esus]),St2}.
877
878bin_expand_strings(Es) ->
879    foldr(fun ({bin_element,Line,{string,_,S},default,default}, Es1) ->
880		  foldr(fun (C, Es2) ->
881				[{bin_element,Line,{char,Line,C},default,default}|Es2]
882			end, Es1, S);
883	      (E, Es1) -> [E|Es1]
884	  end, [], Es).
885
886%% new_var_name(State) -> {VarName,State}.
887
888new_var_name(St) ->
889    C = St#expand.vcount,
890    {list_to_atom("pre" ++ integer_to_list(C)),St#expand{vcount=C+1}}.
891
892%% new_var(Line, State) -> {Var,State}.
893
894new_var(L, St0) ->
895    {New,St1} = new_var_name(St0),
896    {{var,L,New},St1}.
897
898%% new_vars(Count, Line, State) -> {[Var],State}.
899%%  Make Count new variables.
900
901new_vars(N, L, St) -> new_vars(N, L, St, []).
902
903new_vars(N, L, St0, Vs) when N > 0 ->
904    {V,St1} = new_var(L, St0),
905    new_vars(N-1, L, St1, [V|Vs]);
906new_vars(0, _L, St, Vs) -> {Vs,St}.
907
908%% make_list(TermList, Line) ->	ConsTerm.
909
910make_list(Ts, Line) ->
911    foldr(fun (H, T) -> {cons,Line,H,T} end, {nil,Line}, Ts).
912
913string_to_conses(Line, Cs, Tail) ->
914    foldr(fun (C, T) -> {cons,Line,{char,Line,C},T} end, Tail, Cs).
915
916
917%% Create a case-switch on true/false, generating badarg for all other
918%% values.
919
920make_bool_switch(L, E, V, T, F) ->
921    make_bool_switch_1(L, E, V, [T], [F]).
922
923make_bool_switch_1(L, E, V, T, F) ->
924    case get(sys_pre_expand_in_guard) of
925	undefined -> make_bool_switch_body(L, E, V, T, F);
926	yes -> make_bool_switch_guard(L, E, V, T, F)
927    end.
928
929make_bool_switch_guard(_, E, _, [{atom,_,true}], [{atom,_,false}]) -> E;
930make_bool_switch_guard(L, E, V, T, F) ->
931    NegL = -abs(L),
932    {'case',NegL,E,
933     [{clause,NegL,[{atom,NegL,true}],[],T},
934      {clause,NegL,[{atom,NegL,false}],[],F},
935      {clause,NegL,[V],[],[V]}
936     ]}.
937
938make_bool_switch_body(L, E, V, T, F) ->
939    NegL = -abs(L),
940    {'case',NegL,E,
941     [{clause,NegL,[{atom,NegL,true}],[],T},
942      {clause,NegL,[{atom,NegL,false}],[],F},
943      {clause,NegL,[V],[],
944       [call_error(NegL,{tuple,NegL,[{atom,NegL,badarg},V]})]}
945     ]}.
946
947%% Expand a list of cond-clauses to a sequence of case-switches.
948
949cond_clauses([{clause,L,[],[[E]],B}],V) ->
950    make_bool_switch_1(L,E,V,B,[call_error(L,{atom,L,cond_clause})]);
951cond_clauses([{clause,L,[],[[E]],B} | Cs],V) ->
952    make_bool_switch_1(L,E,V,B,[cond_clauses(Cs,V)]).
953
954%% call_error(Line, Reason) -> Expr.
955%%  Build a call to erlang:error/1 with reason Reason.
956
957call_error(L, R) ->
958    {call,L,{remote,L,{atom,L,erlang},{atom,L,error}},[R]}.
959
960%% new_in_all(Before, RegionList) -> NewInAll
961%%  Return the variables new in all clauses.
962
963new_in_all(Before, Region) ->
964    InAll = intersection(Region),
965    subtract(InAll, Before).
966
967%% import(Line, Imports, State) ->
968%%	State'
969%% imported(Name, Arity, State) ->
970%%	{yes,Module} | no
971%%  Handle import declarations and est for imported functions. No need to
972%%  check when building imports as code is correct.
973
974import({Mod,Fs}, St) ->
975    true = is_atom(Mod),
976    Mfs = from_list(Fs),
977    St#expand{imports=add_imports(Mod, Mfs, St#expand.imports)}.
978
979add_imports(Mod, [F|Fs], Is) ->
980    add_imports(Mod, Fs, orddict:store(F, Mod, Is));
981add_imports(_, [], Is) -> Is.
982
983imported(F, A, St) ->
984    case orddict:find({F,A}, St#expand.imports) of
985	{ok,Mod} -> {yes,Mod};
986	error -> no
987    end.
988