40
format(Node) -> format(Node, #ctxt{});
41
41
format(Node) -> case catch format(Node, #ctxt{}) of
42
42
{'EXIT',_} -> io_lib:format("~p",[Node]);
46
maybe_anno(Node, Fun, Ctxt) ->
47
As = core_lib:get_anno(Node),
50
maybe_anno(Node, Fun, Ctxt, As);
52
if Line > Ctxt#ctxt.line ->
53
[io_lib:format("%% Line ~w",[Line]),
55
maybe_anno(Node, Fun, Ctxt#ctxt{line = Line}, As)
58
maybe_anno(Node, Fun, Ctxt, As)
62
maybe_anno(Node, Fun, Ctxt, As) ->
63
case strip_line(As) of
67
Ctxt1 = add_indent(Ctxt, 2),
68
Ctxt2 = add_indent(Ctxt1, 3),
72
"-| ",format_1(core_lib:make_literal(List), Ctxt2)," )"
76
strip_line([A | As]) when integer(A) ->
78
strip_line([{file,_File} | As]) ->
80
strip_line([A | As]) ->
85
get_line([L | _As]) when integer(L) ->
46
92
format(Node, Ctxt) ->
47
case core_lib:get_anno(Node) of
51
Ctxt1 = ctxt_bump_indent(Ctxt, 2),
52
Ctxt2 = ctxt_bump_indent(Ctxt1, 3),
54
format_1(Node, Ctxt1),
56
"-| ",format_1(core_lib:make_literal(List), Ctxt2)," )"
93
maybe_anno(Node, fun format_1/2, Ctxt).
60
95
format_1(#c_char{val=C}, _) -> io_lib:write_char(C);
61
96
format_1(#c_int{val=I}, _) -> integer_to_list(I);
93
128
%% Integers are also simply prefixed with "_".
94
129
[$_ | integer_to_list(V)]
96
format_1(#c_binary{segs=Segs}, Ctxt) ->
98
format_hseq(Segs, ",", ctxt_bump_indent(Ctxt, 2), fun format_bin_seg/2),
131
format_1(#c_binary{segments=Segs}, Ctxt) ->
133
format_vseq(Segs, "", ",", add_indent(Ctxt, 2),
134
fun format_bitstr/2),
101
137
format_1(#c_tuple{es=Es}, Ctxt) ->
103
format_hseq(Es, ",", ctxt_bump_indent(Ctxt, 1), fun format/2),
139
format_hseq(Es, ",", add_indent(Ctxt, 1), fun format/2),
106
142
format_1(#c_cons{hd=H,tl=T}, Ctxt) ->
107
Txt = ["["|format(H, ctxt_bump_indent(Ctxt, 1))],
108
[Txt|format_list_tail(T, ctxt_bump_indent(Ctxt, width(Txt, Ctxt)))];
143
Txt = ["["|format(H, add_indent(Ctxt, 1))],
144
[Txt|format_list_tail(T, add_indent(Ctxt, width(Txt, Ctxt)))];
109
145
format_1(#c_values{es=Es}, Ctxt) ->
110
146
format_values(Es, Ctxt);
111
147
format_1(#c_alias{var=V,pat=P}, Ctxt) ->
112
148
Txt = [format(V, Ctxt)|" = "],
113
[Txt|format(P, ctxt_bump_indent(Ctxt, width(Txt, Ctxt)))];
114
format_1(#c_let{vars=Vs,arg=A,body=B}, Ctxt) ->
115
Ctxt1 = ctxt_bump_indent(Ctxt, Ctxt#ctxt.body_indent),
117
format_values(Vs, ctxt_bump_indent(Ctxt, 4)),
123
| format(B, ctxt_bump_indent(Ctxt, 4))
149
[Txt|format(P, add_indent(Ctxt, width(Txt, Ctxt)))];
150
format_1(#c_let{vars=Vs0,arg=A,body=B}, Ctxt) ->
151
Vs = [core_lib:set_anno(V, []) || V <- Vs0],
152
case is_simple_term(A) of
154
Ctxt1 = add_indent(Ctxt, Ctxt#ctxt.body_indent),
156
format_values(Vs, add_indent(Ctxt, 4)),
162
| format(B, add_indent(Ctxt, 4))
165
Ctxt1 = add_indent(Ctxt, Ctxt#ctxt.body_indent),
167
format_values(Vs, add_indent(Ctxt, 4)),
169
format(core_lib:set_anno(A, []), Ctxt1),
172
| format(B, add_indent(Ctxt, 4))
125
175
format_1(#c_letrec{defs=Fs,body=B}, Ctxt) ->
126
Ctxt1 = ctxt_bump_indent(Ctxt, Ctxt#ctxt.body_indent),
176
Ctxt1 = add_indent(Ctxt, Ctxt#ctxt.body_indent),
128
178
nl_indent(Ctxt1),
129
179
format_funcs(Fs, Ctxt1),
132
| format(B, ctxt_bump_indent(Ctxt, 4))
182
| format(B, add_indent(Ctxt, 4))
134
184
format_1(#c_seq{arg=A,body=B}, Ctxt) ->
135
Ctxt1 = ctxt_bump_indent(Ctxt, 4),
185
Ctxt1 = add_indent(Ctxt, 4),
137
187
format(A, Ctxt1),
139
189
| format(B, Ctxt1)
141
191
format_1(#c_case{arg=A,clauses=Cs}, Ctxt) ->
142
Ctxt1 = ctxt_bump_indent(Ctxt, Ctxt#ctxt.item_indent),
192
Ctxt1 = add_indent(Ctxt, Ctxt#ctxt.item_indent),
144
format(A, ctxt_bump_indent(Ctxt, 5)),
194
format(A, add_indent(Ctxt, 5)),
146
196
nl_indent(Ctxt1),
147
197
format_clauses(Cs, Ctxt1),
163
213
format_1(#c_fname{id=I,arity=A}, _) ->
164
214
[core_atom(I),$/,integer_to_list(A)];
165
215
format_1(#c_fun{vars=Vs,body=B}, Ctxt) ->
166
Ctxt1 = ctxt_bump_indent(Ctxt, Ctxt#ctxt.body_indent),
216
Ctxt1 = add_indent(Ctxt, Ctxt#ctxt.body_indent),
168
format_hseq(Vs, ",", ctxt_bump_indent(Ctxt, 5), fun format/2),
218
format_hseq(Vs, ",", add_indent(Ctxt, 5), fun format/2),
171
221
| format(B, Ctxt1)
173
223
format_1(#c_apply{op=O,args=As}, Ctxt0) ->
174
Ctxt1 = ctxt_bump_indent(Ctxt0, 6), %"apply "
224
Ctxt1 = add_indent(Ctxt0, 6), %"apply "
175
225
Op = format(O, Ctxt1),
176
Ctxt2 = ctxt_bump_indent(Ctxt0, 4),
226
Ctxt2 = add_indent(Ctxt0, 4),
178
228
nl_indent(Ctxt2),
179
$(,format_hseq(As, ", ", ctxt_bump_indent(Ctxt2, 1), fun format/2),$)
229
$(,format_hseq(As, ", ", add_indent(Ctxt2, 1), fun format/2),$)
181
231
format_1(#c_call{module=M,name=N,args=As}, Ctxt0) ->
182
Ctxt1 = ctxt_bump_indent(Ctxt0, 5), %"call "
232
Ctxt1 = add_indent(Ctxt0, 5), %"call "
183
233
Mod = format(M, Ctxt1),
184
Ctxt2 = ctxt_bump_indent(Ctxt1, width(Mod, Ctxt1)+1),
234
Ctxt2 = add_indent(Ctxt1, width(Mod, Ctxt1)+1),
185
235
Name = format(N, Ctxt2),
186
Ctxt3 = ctxt_bump_indent(Ctxt0, 4),
236
Ctxt3 = add_indent(Ctxt0, 4),
187
237
["call ",Mod,":",Name,
188
238
nl_indent(Ctxt3),
189
$(,format_hseq(As, ", ", ctxt_bump_indent(Ctxt3, 1), fun format/2),$)
239
$(,format_hseq(As, ", ", add_indent(Ctxt3, 1), fun format/2),$)
191
241
format_1(#c_primop{name=N,args=As}, Ctxt0) ->
192
Ctxt1 = ctxt_bump_indent(Ctxt0, 7), %"primop "
242
Ctxt1 = add_indent(Ctxt0, 7), %"primop "
193
243
Name = format(N, Ctxt1),
194
Ctxt2 = ctxt_bump_indent(Ctxt0, 4),
244
Ctxt2 = add_indent(Ctxt0, 4),
196
246
nl_indent(Ctxt2),
197
$(,format_hseq(As, ", ", ctxt_bump_indent(Ctxt2, 1), fun format/2),$)
247
$(,format_hseq(As, ", ", add_indent(Ctxt2, 1), fun format/2),$)
199
249
format_1(#c_catch{body=B}, Ctxt) ->
200
Ctxt1 = ctxt_bump_indent(Ctxt, Ctxt#ctxt.body_indent),
250
Ctxt1 = add_indent(Ctxt, Ctxt#ctxt.body_indent),
202
252
nl_indent(Ctxt1),
205
255
format_1(#c_try{arg=E,vars=Vs,body=B,evars=Evs,handler=H}, Ctxt) ->
206
Ctxt1 = ctxt_bump_indent(Ctxt, Ctxt#ctxt.body_indent),
256
Ctxt1 = add_indent(Ctxt, Ctxt#ctxt.body_indent),
208
258
nl_indent(Ctxt1),
209
259
format(E, Ctxt1),
212
format_values(Vs, ctxt_bump_indent(Ctxt, 3)),
262
format_values(Vs, add_indent(Ctxt, 3)),
214
264
nl_indent(Ctxt1),
215
265
format(B, Ctxt1),
218
format_values(Evs, ctxt_bump_indent(Ctxt, 6)),
268
format_values(Evs, add_indent(Ctxt, 6)),
221
271
| format(H, Ctxt1)
223
273
format_1(#c_def{name=N,val=V}, Ctxt) ->
224
Ctxt1 = ctxt_set_bump(Ctxt, expr, Ctxt#ctxt.body_indent),
274
Ctxt1 = add_indent(set_class(Ctxt, expr), Ctxt#ctxt.body_indent),
225
275
[format(N, Ctxt),
256
306
format_funcs(Fs, Ctxt) ->
259
ctxt_set_class(Ctxt, def),
309
set_class(Ctxt, def),
262
312
format_values(Vs, Ctxt) ->
264
format_hseq(Vs, ",", ctxt_bump_indent(Ctxt, 1), fun format/2),
314
format_hseq(Vs, ",", add_indent(Ctxt, 1), fun format/2),
267
format_bin_seg(#c_bin_seg{val=V,size=S,unit=U,type=T,flags=Fs}, Ctxt0) ->
268
Vtxt = format(V, Ctxt0),
269
Ctxt1 = ctxt_bump_indent(Ctxt0, width(Vtxt, Ctxt0)+1), %":"
270
Stxt = format(S, Ctxt1),
272
if U == 1 -> ""; %This is default
273
true -> [$*|io_lib:write(U)]
276
lists:map(fun (F) -> [$-|core_atom(F)] end, Fs)
317
format_bitstr(#c_bitstr{val=V,size=S,unit=U,type=T,flags=Fs}, Ctxt0) ->
319
Ctxt1 = add_indent(Ctxt0, 2),
320
Val = format(V, Ctxt1),
321
Ctxt2 = add_indent(Ctxt1, width(Val, Ctxt1) + 2),
322
["#<", Val, ">(", format_hseq(Vs,",", Ctxt2, fun format/2), $)].
279
324
format_clauses(Cs, Ctxt) ->
280
format_vseq(Cs, "", "", ctxt_set_class(Ctxt, clause),
325
format_vseq(Cs, "", "", set_class(Ctxt, clause),
281
326
fun format_clause/2).
283
format_clause(#c_clause{pats=Ps,guard=G,body=B}, Ctxt) ->
328
format_clause(Node, Ctxt) ->
329
maybe_anno(Node, fun format_clause_1/2, Ctxt).
331
format_clause_1(#c_clause{pats=Ps,guard=G,body=B}, Ctxt) ->
284
332
Ptxt = format_values(Ps, Ctxt),
285
Ctxt2 = ctxt_bump_indent(Ctxt, Ctxt#ctxt.body_indent),
333
Ctxt2 = add_indent(Ctxt, Ctxt#ctxt.body_indent),
288
format_guard(G, ctxt_set_bump(Ctxt, expr, width(Ptxt, Ctxt) + 6)),
336
format_guard(G, add_indent(set_class(Ctxt, expr),
337
width(Ptxt, Ctxt) + 6)),
291
| format(B, ctxt_set_class(Ctxt2, expr))
340
| format(B, set_class(Ctxt2, expr))
294
343
format_guard(Node, Ctxt) ->
295
case core_lib:get_anno(Node) of
296
[] -> format_guard_1(Node, Ctxt);
298
Ctxt1 = ctxt_bump_indent(Ctxt, 2),
299
Ctxt2 = ctxt_bump_indent(Ctxt1, 3),
301
format_guard_1(Node, Ctxt1),
303
"-| ",format_1(core_lib:make_literal(List), Ctxt2)," )"
344
maybe_anno(Node, fun format_guard_1/2, Ctxt).
307
346
format_guard_1(#c_call{module=M,name=N,args=As}, Ctxt0) ->
308
Ctxt1 = ctxt_bump_indent(Ctxt0, 5), %"call "
347
Ctxt1 = add_indent(Ctxt0, 5), %"call "
309
348
Mod = format(M, Ctxt1),
310
Ctxt2 = ctxt_bump_indent(Ctxt1, width(Mod, Ctxt1)+1),
349
Ctxt2 = add_indent(Ctxt1, width(Mod, Ctxt1)+1),
311
350
Name = format(N, Ctxt2),
312
Ctxt3 = ctxt_bump_indent(Ctxt0, 4),
351
Ctxt3 = add_indent(Ctxt0, 4),
313
352
["call ",Mod,":",Name,
314
353
nl_indent(Ctxt3),
315
$(,format_vseq(As, "",",", ctxt_bump_indent(Ctxt3, 1), fun format_guard/2),$)
354
$(,format_vseq(As, "",",", add_indent(Ctxt3, 1), fun format_guard/2),$)
317
356
format_guard_1(E, Ctxt) -> format_1(E, Ctxt). %Anno already done
342
381
format_list_tail(#c_nil{anno=[]}, _) -> "]";
343
382
format_list_tail(#c_cons{anno=[],hd=H,tl=T}, Ctxt) ->
344
383
Txt = [$,|format(H, Ctxt)],
345
Ctxt1 = ctxt_bump_indent(Ctxt, width(Txt, Ctxt)),
384
Ctxt1 = add_indent(Ctxt, width(Txt, Ctxt)),
346
385
[Txt|format_list_tail(T, Ctxt1)];
347
386
format_list_tail(Tail, Ctxt) ->
348
["|",format(Tail, ctxt_bump_indent(Ctxt, 1)),"]"].
387
["|",format(Tail, add_indent(Ctxt, 1)),"]"].
350
389
indent(Ctxt) -> indent(Ctxt#ctxt.indent, Ctxt).
398
437
width(H, A, Ctxt, T);
399
438
width([], A, _, []) -> A.
401
ctxt_bump_indent(Ctxt, Dx) ->
440
add_indent(Ctxt, Dx) ->
402
441
Ctxt#ctxt{indent = Ctxt#ctxt.indent + Dx}.
404
ctxt_set_class(Ctxt, Class) ->
443
set_class(Ctxt, Class) ->
405
444
Ctxt#ctxt{class = Class}.
407
ctxt_set_bump(Ctxt, Class, Dx) ->
408
Ctxt#ctxt{class=Class,indent=Ctxt#ctxt.indent + Dx}.
410
446
core_atom(A) -> io_lib:write_string(atom_to_list(A), $').
449
is_simple_term(#c_values{es=Es}) ->
450
length(Es) < 3 andalso lists:all(fun is_simple_term/1, Es);
451
is_simple_term(#c_tuple{es=Es}) ->
452
length(Es) < 4 andalso lists:all(fun is_simple_term/1, Es);
453
is_simple_term(#c_var{}) -> true;
454
is_simple_term(#c_string{}) -> false;
455
is_simple_term(Term) -> core_lib:is_atomic(Term).