1 | | --- ../apache-couchdb-1.3.0.orig/configure 2013-03-30 09:46:50.000000000 -0500 |
2 | | +++ ./configure 2013-04-05 10:12:43.000000000 -0500 |
3 | | @@ -18448,7 +18448,7 @@ |
4 | | as_fn_error $? "$erlang_version_error" "$LINENO" 5 |
5 | | fi |
6 | | |
7 | | -if test $minor_version -lt 7 -o $minor_version -gt 9; then |
8 | | +if test $minor_version -lt 7; then |
9 | | as_fn_error $? "$erlang_version_error" "$LINENO" 5 |
10 | | fi |
11 | | |
12 | | --- ../apache-couchdb-1.3.0.orig/src/mochiweb/Makefile.in 2013-03-30 09:46:48.000000000 -0500 |
13 | | +++ ./src/mochiweb/Makefile.in 2013-04-05 10:12:43.000000000 -0500 |
14 | | @@ -282,6 +282,7 @@ |
15 | | @USE_NATIVE_MOCHIJSON_TRUE@MOCHIJSON_ERLC_FLAGS = +native |
16 | | mochiwebebindir = $(localerlanglibdir)/mochiweb-1.4.1/ebin |
17 | | mochiweb_file_collection = \ |
18 | | + pmod_pt.erl \ |
19 | | mochifmt.erl \ |
20 | | mochifmt_records.erl \ |
21 | | mochifmt_std.erl \ |
22 | | @@ -320,6 +321,7 @@ |
23 | | reloader.erl |
24 | | |
25 | | mochiwebebin_make_generated_file_list = \ |
26 | | + pmod_pt.beam \ |
27 | | mochifmt.beam \ |
28 | | mochifmt_records.beam \ |
29 | | mochifmt_std.beam \ |
30 | | @@ -587,8 +589,10 @@ |
31 | | mochijson2.beam: mochijson2.erl |
32 | | $(ERLC) $(ERLC_FLAGS) $(MOCHIJSON_ERLC_FLAGS) $< |
33 | | |
34 | | +mochifmt_records.beam mochifmt_std.beam mochiweb_request.beam mochiweb_response.beam: pmod_pt.beam |
35 | | + |
36 | | %.beam: %.erl |
37 | | - $(ERLC) $(ERLC_FLAGS) $< |
38 | | + $(ERLC) $(ERLC_FLAGS) -pa . $< |
39 | | |
40 | | # Tell versions [3.59,3.63) of GNU make to not export all variables. |
41 | | # Otherwise a system limit (for SysV at least) may be exceeded. |
42 | | --- ../apache-couchdb-1.3.0.orig/src/mochiweb/mochifmt_records.erl 2013-03-30 09:46:38.000000000 -0500 |
43 | | +++ ./src/mochiweb/mochifmt_records.erl 2013-04-05 10:12:43.000000000 -0500 |
44 | | @@ -13,6 +13,8 @@ |
45 | | -author('bob@mochimedia.com'). |
46 | | -export([get_value/2]). |
47 | | |
48 | | +-compile({parse_transform, pmod_pt}). |
49 | | + |
50 | | get_value(Key, Rec) when is_tuple(Rec) and is_atom(element(1, Rec)) -> |
51 | | try begin |
52 | | Atom = list_to_existing_atom(Key), |
53 | | --- ../apache-couchdb-1.3.0.orig/src/mochiweb/mochifmt_std.erl 2013-03-30 09:46:38.000000000 -0500 |
54 | | +++ ./src/mochiweb/mochifmt_std.erl 2013-04-05 10:12:43.000000000 -0500 |
55 | | @@ -7,6 +7,8 @@ |
56 | | -author('bob@mochimedia.com'). |
57 | | -export([format/2, get_value/2, format_field/2, get_field/2, convert_field/2]). |
58 | | |
59 | | +-compile({parse_transform, pmod_pt}). |
60 | | + |
61 | | format(Format, Args) -> |
62 | | mochifmt:format(Format, Args, THIS). |
63 | | |
64 | | --- ../apache-couchdb-1.3.0.orig/src/mochiweb/mochiweb_request.erl 2013-03-30 09:46:38.000000000 -0500 |
65 | | +++ ./src/mochiweb/mochiweb_request.erl 2013-04-05 10:12:43.000000000 -0500 |
66 | | @@ -23,6 +23,8 @@ |
67 | | -export([accepted_encodings/1]). |
68 | | -export([accepts_content_type/1]). |
69 | | |
70 | | +-compile({parse_transform, pmod_pt}). |
71 | | + |
72 | | -define(SAVE_QS, mochiweb_request_qs). |
73 | | -define(SAVE_PATH, mochiweb_request_path). |
74 | | -define(SAVE_RECV, mochiweb_request_recv). |
75 | | --- ../apache-couchdb-1.3.0.orig/src/mochiweb/mochiweb_response.erl 2013-03-30 09:46:38.000000000 -0500 |
76 | | +++ ./src/mochiweb/mochiweb_response.erl 2013-04-05 10:12:43.000000000 -0500 |
77 | | @@ -11,6 +11,8 @@ |
78 | | -export([get_header_value/1, get/1, dump/0]). |
79 | | -export([send/1, write_chunk/1]). |
80 | | |
81 | | +-compile({parse_transform, pmod_pt}). |
82 | | + |
83 | | %% @spec get_header_value(string() | atom() | binary()) -> string() | undefined |
84 | | %% @doc Get the value of the given response header. |
85 | | get_header_value(K) -> |
86 | | --- ../apache-couchdb-1.3.0.orig/src/mochiweb/pmod_pt.erl 1969-12-31 18:00:00.000000000 -0600 |
87 | | +++ ./src/mochiweb/pmod_pt.erl 2013-04-05 10:12:43.000000000 -0500 |
88 | | @@ -0,0 +1,463 @@ |
89 | | +%% |
90 | | +%% %CopyrightBegin% |
91 | | +%% |
92 | | +%% Copyright Ericsson AB 2013. All Rights Reserved. |
93 | | +%% |
94 | | +%% The contents of this file are subject to the Erlang Public License, |
95 | | +%% Version 1.1, (the "License"); you may not use this file except in |
96 | | +%% compliance with the License. You should have received a copy of the |
97 | | +%% Erlang Public License along with this software. If not, it can be |
98 | | +%% retrieved online at http://www.erlang.org/. |
99 | | +%% |
100 | | +%% Software distributed under the License is distributed on an "AS IS" |
101 | | +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See |
102 | | +%% the License for the specific language governing rights and limitations |
103 | | +%% under the License. |
104 | | +%% |
105 | | +%% %CopyrightEnd% |
106 | | +%% |
107 | | + |
108 | | +-module(pmod_pt). |
109 | | +-export([parse_transform/2, |
110 | | + format_error/1]). |
111 | | + |
112 | | +%% Expand function definition forms of parameterized module. |
113 | | +%% The code is based on the code in sys_expand_pmod which used to be |
114 | | +%% included in the compiler, but details are different because |
115 | | +%% sys_pre_expand has not been run. In particular: |
116 | | +%% |
117 | | +%% * Record definitions are still present and must be handled. |
118 | | +%% |
119 | | +%% * (Syntatic) local calls may actually be calls to an imported |
120 | | +%% funtion or a BIF. It is a local call if and only if there |
121 | | +%% is a definition for the function in the module. |
122 | | +%% |
123 | | +%% * When we introduce the module parameters and 'THIS' in each |
124 | | +%% function, we must artificially use it to avoid a warning for |
125 | | +%% unused variables. |
126 | | +%% |
127 | | +%% * On the other hand, we don't have to worry about module_info/0,1 |
128 | | +%% because they have not been added yet. |
129 | | + |
130 | | +-record(pmod, {parameters, |
131 | | + defined |
132 | | + }). |
133 | | + |
134 | | +parse_transform(Forms0, _Options) -> |
135 | | + put(?MODULE, []), |
136 | | + Forms = transform(Forms0), |
137 | | + case erase(?MODULE) of |
138 | | + [] -> |
139 | | + Forms; |
140 | | + [_|_]=Errors -> |
141 | | + File = get_file(Forms), |
142 | | + {error,[{File,Errors}],[]} |
143 | | + end. |
144 | | + |
145 | | +format_error(extends_self) -> |
146 | | + "cannot extend from self"; |
147 | | +format_error(define_instance) -> |
148 | | + "defining instance function not allowed in parameterized module". |
149 | | + |
150 | | +add_error(Line, Error) -> |
151 | | + put(?MODULE, get(?MODULE) ++ [{Line,?MODULE,Error}]). |
152 | | + |
153 | | +get_file([{attribute,_,file,{File,_}}|_]) -> File; |
154 | | +get_file([_|T]) -> get_file(T). |
155 | | + |
156 | | +transform(Forms0) -> |
157 | | + Def = collect_defined(Forms0), |
158 | | + {Base,ModAs,Forms1} = attribs(Forms0, [], undefined, []), |
159 | | + {Mod,Ps0} = case ModAs of |
160 | | + {M0,P0} -> {M0,P0}; |
161 | | + M0 -> {M0,undefined} |
162 | | + end, |
163 | | + Forms2 = case Ps0 of |
164 | | + undefined -> |
165 | | + Forms1; |
166 | | + _ -> |
167 | | + pmod_expand(Forms1, Mod, Base, Ps0, Def) |
168 | | + end, |
169 | | + |
170 | | + %% Add new functions. |
171 | | + NewFs0 = maybe_extend(Base, Mod, Ps0), |
172 | | + NewExps = collect_defined(NewFs0), |
173 | | + Forms3 = add_attributes(Forms2, [{attribute,0,export,NewExps}]), |
174 | | + add_new_funcs(Forms3, NewFs0). |
175 | | + |
176 | | +pmod_expand(Forms0, Mod, Base, Ps0, Def) -> |
177 | | + Ps = if is_atom(Base) -> |
178 | | + ['BASE' | Ps0]; |
179 | | + true -> |
180 | | + Ps0 |
181 | | + end, |
182 | | + St0 = #pmod{parameters=Ps,defined=gb_sets:from_list(Def)}, |
183 | | + {Forms1,_} = forms(Forms0, St0), |
184 | | + Forms2 = update_exps(Forms1), |
185 | | + Forms3 = update_forms(Forms2), |
186 | | + NewFs0 = add_instance(Mod, Ps, []), |
187 | | + NewFs = ensure_new(Base, Ps0, NewFs0), |
188 | | + Forms = add_new_funcs(Forms3, NewFs), |
189 | | + NewExps = collect_defined(NewFs), |
190 | | + add_attributes(Forms, [{attribute,0,export,NewExps}]). |
191 | | + |
192 | | +add_attributes([{attribute,_,module,_}=F|Fs], Attrs) -> |
193 | | + [F|Attrs++Fs]; |
194 | | +add_attributes([F|Fs], Attrs) -> |
195 | | + [F|add_attributes(Fs, Attrs)]. |
196 | | + |
197 | | +add_new_funcs([{eof,_}|_]=Fs, NewFs) -> |
198 | | + NewFs ++ Fs; |
199 | | +add_new_funcs([F|Fs], Es) -> |
200 | | + [F|add_new_funcs(Fs, Es)]. |
201 | | + |
202 | | +maybe_extend([], _, _) -> |
203 | | + %% No 'extends' attribute. |
204 | | + []; |
205 | | +maybe_extend(Base, _Mod, undefined) -> |
206 | | + %% There is a an 'extends' attribute; the module is not parameterized. |
207 | | + Name = '$handle_undefined_function', |
208 | | + Args = [{var,0,'Func'},{var,0,'Args'}], |
209 | | + Body = [make_apply({atom,0,Base}, {var,0,'Func'}, {var,0,'Args'})], |
210 | | + F = {function,0,Name,2,[{clause,0,Args,[],Body}]}, |
211 | | + [F]; |
212 | | +maybe_extend(Base, Mod, Ps) -> |
213 | | + %% There is a an 'extends' attribute; the module is parameterized. |
214 | | + Name = '$handle_undefined_function', |
215 | | + Args = [{var,0,'Func'},{var,0,'Args'}], |
216 | | + DontCares = [{var,0,'_'} || _ <- Ps], |
217 | | + TuplePs = {tuple,0,[{atom,0,Mod},{var,0,'BaseVars'}|DontCares]}, |
218 | | + G = [{call,0,{atom,0,is_atom}, |
219 | | + [{call,0,{atom,0,element}, |
220 | | + [{integer,0,1},{var,0,'BaseVars'}]}]}], |
221 | | + FixedArgs = make_lists_rev([{var,0,'Rs'}, |
222 | | + {cons,0,{var,0,'BaseVars'},{nil,0}}]), |
223 | | + Body = [{'case',0,make_lists_rev([{var,0,'Args'}]), |
224 | | + [{clause,0,[{cons,0,TuplePs,{var,0,'Rs'}}],[G], |
225 | | + [make_apply({atom,0,Base}, {var,0,'Func'}, FixedArgs)]}, |
226 | | + {clause,0,[{var,0,'_'}],[], |
227 | | + [make_apply({atom,0,Base}, {var,0,'Func'}, {var,0,'Args'})]} |
228 | | + ]}], |
229 | | + F = {function,0,Name,2,[{clause,0,Args,[],Body}]}, |
230 | | + [F]. |
231 | | + |
232 | | +make_apply(M, F, A) -> |
233 | | + {call,0,{remote,0,{atom,0,erlang},{atom,0,apply}},[M,F,A]}. |
234 | | + |
235 | | +make_lists_rev(As) -> |
236 | | + {call,0,{remote,0,{atom,0,lists},{atom,0,reverse}},As}. |
237 | | + |
238 | | +ensure_new(Base, Ps, Fs) -> |
239 | | + case has_new(Fs) of |
240 | | + true -> |
241 | | + Fs; |
242 | | + false -> |
243 | | + add_new(Base, Ps, Fs) |
244 | | + end. |
245 | | + |
246 | | +has_new([{function,_L,new,_A,_Cs} | _Fs]) -> |
247 | | + true; |
248 | | +has_new([_ | Fs]) -> |
249 | | + has_new(Fs); |
250 | | +has_new([]) -> |
251 | | + false. |
252 | | + |
253 | | +add_new(Base, Ps, Fs) -> |
254 | | + Vs = [{var,0,V} || V <- Ps], |
255 | | + As = if is_atom(Base) -> |
256 | | + [{call,0,{remote,0,{atom,0,Base},{atom,0,new}},Vs} | Vs]; |
257 | | + true -> |
258 | | + Vs |
259 | | + end, |
260 | | + Body = [{call,0,{atom,0,instance},As}], |
261 | | + add_func(new, Vs, Body, Fs). |
262 | | + |
263 | | +add_instance(Mod, Ps, Fs) -> |
264 | | + Vs = [{var,0,V} || V <- Ps], |
265 | | + AbsMod = [{tuple,0,[{atom,0,Mod}|Vs]}], |
266 | | + add_func(instance, Vs, AbsMod, Fs). |
267 | | + |
268 | | +add_func(Name, Args, Body, Fs) -> |
269 | | + A = length(Args), |
270 | | + F = {function,0,Name,A,[{clause,0,Args,[],Body}]}, |
271 | | + [F|Fs]. |
272 | | + |
273 | | +collect_defined(Fs) -> |
274 | | + [{N,A} || {function,_,N,A,_} <- Fs]. |
275 | | + |
276 | | +attribs([{attribute,Line,module,{Mod,_}=ModAs}|T], Base, _, Acc) -> |
277 | | + attribs(T, Base, ModAs, [{attribute,Line,module,Mod}|Acc]); |
278 | | +attribs([{attribute,_,module,Mod}=H|T], Base, _, Acc) -> |
279 | | + attribs(T, Base, Mod, [H|Acc]); |
280 | | +attribs([{attribute,Line,extends,Base}|T], Base0, Ps, Acc) when is_atom(Base) -> |
281 | | + Mod = case Ps of |
282 | | + {Mod0,_} -> Mod0; |
283 | | + Mod0 -> Mod0 |
284 | | + end, |
285 | | + case Mod of |
286 | | + Base -> |
287 | | + add_error(Line, extends_self), |
288 | | + attribs(T, Base0, Ps, Acc); |
289 | | + _ -> |
290 | | + attribs(T, Base, Ps, Acc) |
291 | | + end; |
292 | | +attribs([H|T], Base, Ps, Acc) -> |
293 | | + attribs(T, Base, Ps, [H|Acc]); |
294 | | +attribs([], Base, Ps, Acc) -> |
295 | | + {Base,Ps,lists:reverse(Acc)}. |
296 | | + |
297 | | +%% This is extremely simplistic for now; all functions get an extra |
298 | | +%% parameter, whether they need it or not, except for static functions. |
299 | | + |
300 | | +update_function_name({F,A}) when F =/= new -> |
301 | | + {F,A+1}; |
302 | | +update_function_name(E) -> |
303 | | + E. |
304 | | + |
305 | | +update_forms([{function,L,N,A,Cs}|Fs]) when N =/= new -> |
306 | | + [{function,L,N,A+1,Cs}|update_forms(Fs)]; |
307 | | +update_forms([F|Fs]) -> |
308 | | + [F|update_forms(Fs)]; |
309 | | +update_forms([]) -> |
310 | | + []. |
311 | | + |
312 | | +update_exps([{attribute,Line,export,Es0}|T]) -> |
313 | | + Es = [update_function_name(E) || E <- Es0], |
314 | | + [{attribute,Line,export,Es}|update_exps(T)]; |
315 | | +update_exps([H|T]) -> |
316 | | + [H|update_exps(T)]; |
317 | | +update_exps([]) -> |
318 | | + []. |
319 | | + |
320 | | +%% Process the program forms. |
321 | | + |
322 | | +forms([F0|Fs0],St0) -> |
323 | | + {F1,St1} = form(F0,St0), |
324 | | + {Fs1,St2} = forms(Fs0,St1), |
325 | | + {[F1|Fs1],St2}; |
326 | | +forms([], St0) -> |
327 | | + {[], St0}. |
328 | | + |
329 | | +%% Only function definitions are of interest here. State is not updated. |
330 | | +form({function,Line,instance,_Arity,_Clauses}=F,St) -> |
331 | | + add_error(Line, define_instance), |
332 | | + {F,St}; |
333 | | +form({function,Line,Name0,Arity0,Clauses0},St) when Name0 =/= new -> |
334 | | + {Name,Arity,Clauses} = function(Name0, Arity0, Clauses0, St), |
335 | | + {{function,Line,Name,Arity,Clauses},St}; |
336 | | +%% Pass anything else through |
337 | | +form(F,St) -> {F,St}. |
338 | | + |
339 | | +function(Name, Arity, Clauses0, St) -> |
340 | | + Clauses1 = clauses(Clauses0,St), |
341 | | + {Name,Arity,Clauses1}. |
342 | | + |
343 | | +clauses([C|Cs],#pmod{parameters=Ps}=St) -> |
344 | | + {clause,L,H,G,B0} = clause(C,St), |
345 | | + T = {tuple,L,[{var,L,V} || V <- ['_'|Ps]]}, |
346 | | + B = [{match,L,{var,L,'_'},{var,L,V}} || V <- ['THIS'|Ps]] ++ B0, |
347 | | + [{clause,L,H++[{match,L,T,{var,L,'THIS'}}],G,B}|clauses(Cs,St)]; |
348 | | +clauses([],_St) -> []. |
349 | | + |
350 | | +clause({clause,Line,H,G,B0},St) -> |
351 | | + %% We never update H and G, so we will just copy them. |
352 | | + B1 = exprs(B0,St), |
353 | | + {clause,Line,H,G,B1}. |
354 | | + |
355 | | +pattern_grp([{bin_element,L1,E1,S1,T1} | Fs],St) -> |
356 | | + S2 = case S1 of |
357 | | + default -> |
358 | | + default; |
359 | | + _ -> |
360 | | + expr(S1,St) |
361 | | + end, |
362 | | + T2 = case T1 of |
363 | | + default -> |
364 | | + default; |
365 | | + _ -> |
366 | | + bit_types(T1) |
367 | | + end, |
368 | | + [{bin_element,L1,expr(E1,St),S2,T2} | pattern_grp(Fs,St)]; |
369 | | +pattern_grp([],_St) -> |
370 | | + []. |
371 | | + |
372 | | +bit_types([]) -> |
373 | | + []; |
374 | | +bit_types([Atom | Rest]) when is_atom(Atom) -> |
375 | | + [Atom | bit_types(Rest)]; |
376 | | +bit_types([{Atom, Integer} | Rest]) when is_atom(Atom), is_integer(Integer) -> |
377 | | + [{Atom, Integer} | bit_types(Rest)]. |
378 | | + |
379 | | +exprs([E0|Es],St) -> |
380 | | + E1 = expr(E0,St), |
381 | | + [E1|exprs(Es,St)]; |
382 | | +exprs([],_St) -> []. |
383 | | + |
384 | | +expr({var,_L,_V}=Var,_St) -> |
385 | | + Var; |
386 | | +expr({integer,_Line,_I}=Integer,_St) -> Integer; |
387 | | +expr({float,_Line,_F}=Float,_St) -> Float; |
388 | | +expr({atom,_Line,_A}=Atom,_St) -> Atom; |
389 | | +expr({string,_Line,_S}=String,_St) -> String; |
390 | | +expr({char,_Line,_C}=Char,_St) -> Char; |
391 | | +expr({nil,_Line}=Nil,_St) -> Nil; |
392 | | +expr({cons,Line,H0,T0},St) -> |
393 | | + H1 = expr(H0,St), |
394 | | + T1 = expr(T0,St), |
395 | | + {cons,Line,H1,T1}; |
396 | | +expr({lc,Line,E0,Qs0},St) -> |
397 | | + Qs1 = lc_bc_quals(Qs0,St), |
398 | | + E1 = expr(E0,St), |
399 | | + {lc,Line,E1,Qs1}; |
400 | | +expr({bc,Line,E0,Qs0},St) -> |
401 | | + Qs1 = lc_bc_quals(Qs0,St), |
402 | | + E1 = expr(E0,St), |
403 | | + {bc,Line,E1,Qs1}; |
404 | | +expr({tuple,Line,Es0},St) -> |
405 | | + Es1 = expr_list(Es0,St), |
406 | | + {tuple,Line,Es1}; |
407 | | +expr({record_index,_,_,_}=RI, _St) -> |
408 | | + RI; |
409 | | +expr({record,Line,Name,Is0},St) -> |
410 | | + Is = record_fields(Is0,St), |
411 | | + {record,Line,Name,Is}; |
412 | | +expr({record,Line,E0,Name,Is0},St) -> |
413 | | + E = expr(E0,St), |
414 | | + Is = record_fields(Is0,St), |
415 | | + {record,Line,E,Name,Is}; |
416 | | +expr({record_field,Line,E0,Name,Key},St) -> |
417 | | + E = expr(E0,St), |
418 | | + {record_field,Line,E,Name,Key}; |
419 | | +expr({block,Line,Es0},St) -> |
420 | | + Es1 = exprs(Es0,St), |
421 | | + {block,Line,Es1}; |
422 | | +expr({'if',Line,Cs0},St) -> |
423 | | + Cs1 = icr_clauses(Cs0,St), |
424 | | + {'if',Line,Cs1}; |
425 | | +expr({'case',Line,E0,Cs0},St) -> |
426 | | + E1 = expr(E0,St), |
427 | | + Cs1 = icr_clauses(Cs0,St), |
428 | | + {'case',Line,E1,Cs1}; |
429 | | +expr({'receive',Line,Cs0},St) -> |
430 | | + Cs1 = icr_clauses(Cs0,St), |
431 | | + {'receive',Line,Cs1}; |
432 | | +expr({'receive',Line,Cs0,To0,ToEs0},St) -> |
433 | | + To1 = expr(To0,St), |
434 | | + ToEs1 = exprs(ToEs0,St), |
435 | | + Cs1 = icr_clauses(Cs0,St), |
436 | | + {'receive',Line,Cs1,To1,ToEs1}; |
437 | | +expr({'try',Line,Es0,Scs0,Ccs0,As0},St) -> |
438 | | + Es1 = exprs(Es0,St), |
439 | | + Scs1 = icr_clauses(Scs0,St), |
440 | | + Ccs1 = icr_clauses(Ccs0,St), |
441 | | + As1 = exprs(As0,St), |
442 | | + {'try',Line,Es1,Scs1,Ccs1,As1}; |
443 | | +expr({'fun',_,{function,_,_,_}}=ExtFun,_St) -> |
444 | | + ExtFun; |
445 | | +expr({'fun',Line,Body},St) -> |
446 | | + case Body of |
447 | | + {clauses,Cs0} -> |
448 | | + Cs1 = fun_clauses(Cs0,St), |
449 | | + {'fun',Line,{clauses,Cs1}}; |
450 | | + {function,F,A} = Function -> |
451 | | + {F1,A1} = update_function_name({F,A}), |
452 | | + if A1 =:= A -> |
453 | | + {'fun',Line,Function}; |
454 | | + true -> |
455 | | + %% Must rewrite local fun-name to a fun that does a |
456 | | + %% call with the extra THIS parameter. |
457 | | + As = make_vars(A, Line), |
458 | | + As1 = As ++ [{var,Line,'THIS'}], |
459 | | + Call = {call,Line,{atom,Line,F1},As1}, |
460 | | + Cs = [{clause,Line,As,[],[Call]}], |
461 | | + {'fun',Line,{clauses,Cs}} |
462 | | + end; |
463 | | + {function,_M,_F,_A} = Fun4 -> %This is an error in lint! |
464 | | + {'fun',Line,Fun4} |
465 | | + end; |
466 | | +expr({call,Lc,{atom,_,instance}=Name,As0},St) -> |
467 | | + %% All local functions 'instance(...)' are static by definition, |
468 | | + %% so they do not take a 'THIS' argument when called |
469 | | + As1 = expr_list(As0,St), |
470 | | + {call,Lc,Name,As1}; |
471 | | +expr({call,Lc,{atom,_,new}=Name,As0},St) -> |
472 | | + %% All local functions 'new(...)' are static by definition, |
473 | | + %% so they do not take a 'THIS' argument when called |
474 | | + As1 = expr_list(As0,St), |
475 | | + {call,Lc,Name,As1}; |
476 | | +expr({call,Lc,{atom,_Lf,F}=Atom,As0}, #pmod{defined=Def}=St) -> |
477 | | + As1 = expr_list(As0,St), |
478 | | + case gb_sets:is_member({F,length(As0)}, Def) of |
479 | | + false -> |
480 | | + %% BIF or imported function. |
481 | | + {call,Lc,Atom,As1}; |
482 | | + true -> |
483 | | + %% Local function call - needs THIS parameter. |
484 | | + {call,Lc,Atom,As1 ++ [{var,0,'THIS'}]} |
485 | | + end; |
486 | | +expr({call,Line,F0,As0},St) -> |
487 | | + %% Other function call |
488 | | + F1 = expr(F0,St), |
489 | | + As1 = expr_list(As0,St), |
490 | | + {call,Line,F1,As1}; |
491 | | +expr({'catch',Line,E0},St) -> |
492 | | + E1 = expr(E0,St), |
493 | | + {'catch',Line,E1}; |
494 | | +expr({match,Line,P,E0},St) -> |
495 | | + E1 = expr(E0,St), |
496 | | + {match,Line,P,E1}; |
497 | | +expr({bin,Line,Fs},St) -> |
498 | | + Fs2 = pattern_grp(Fs,St), |
499 | | + {bin,Line,Fs2}; |
500 | | +expr({op,Line,Op,A0},St) -> |
501 | | + A1 = expr(A0,St), |
502 | | + {op,Line,Op,A1}; |
503 | | +expr({op,Line,Op,L0,R0},St) -> |
504 | | + L1 = expr(L0,St), |
505 | | + R1 = expr(R0,St), |
506 | | + {op,Line,Op,L1,R1}; |
507 | | +%% The following are not allowed to occur anywhere! |
508 | | +expr({remote,Line,M0,F0},St) -> |
509 | | + M1 = expr(M0,St), |
510 | | + F1 = expr(F0,St), |
511 | | + {remote,Line,M1,F1}. |
512 | | + |
513 | | +expr_list([E0|Es],St) -> |
514 | | + E1 = expr(E0,St), |
515 | | + [E1|expr_list(Es,St)]; |
516 | | +expr_list([],_St) -> []. |
517 | | + |
518 | | +record_fields([{record_field,L,K,E0}|T],St) -> |
519 | | + E = expr(E0,St), |
520 | | + [{record_field,L,K,E}|record_fields(T,St)]; |
521 | | +record_fields([],_) -> []. |
522 | | + |
523 | | +icr_clauses([C0|Cs],St) -> |
524 | | + C1 = clause(C0,St), |
525 | | + [C1|icr_clauses(Cs,St)]; |
526 | | +icr_clauses([],_St) -> []. |
527 | | + |
528 | | +lc_bc_quals([{generate,Line,P,E0}|Qs],St) -> |
529 | | + E1 = expr(E0,St), |
530 | | + [{generate,Line,P,E1}|lc_bc_quals(Qs,St)]; |
531 | | +lc_bc_quals([{b_generate,Line,P,E0}|Qs],St) -> |
532 | | + E1 = expr(E0,St), |
533 | | + [{b_generate,Line,P,E1}|lc_bc_quals(Qs,St)]; |
534 | | +lc_bc_quals([E0|Qs],St) -> |
535 | | + E1 = expr(E0,St), |
536 | | + [E1|lc_bc_quals(Qs,St)]; |
537 | | +lc_bc_quals([],_St) -> []. |
538 | | + |
539 | | +fun_clauses([C0|Cs],St) -> |
540 | | + C1 = clause(C0,St), |
541 | | + [C1|fun_clauses(Cs,St)]; |
542 | | +fun_clauses([],_St) -> []. |
543 | | + |
544 | | +make_vars(N, L) -> |
545 | | + make_vars(1, N, L). |
546 | | + |
547 | | +make_vars(N, M, L) when N =< M -> |
548 | | + V = list_to_atom("X"++integer_to_list(N)), |
549 | | + [{var,L,V} | make_vars(N + 1, M, L)]; |
550 | | +make_vars(_, _, _) -> |
551 | | + []. |