summaryrefslogtreecommitdiff
path: root/lib/stdlib/src/qlc_pt.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/stdlib/src/qlc_pt.erl')
-rw-r--r--lib/stdlib/src/qlc_pt.erl604
1 files changed, 305 insertions, 299 deletions
diff --git a/lib/stdlib/src/qlc_pt.erl b/lib/stdlib/src/qlc_pt.erl
index 7cf631d85d..91bc9e4693 100644
--- a/lib/stdlib/src/qlc_pt.erl
+++ b/lib/stdlib/src/qlc_pt.erl
@@ -21,7 +21,7 @@
%%% Purpose: Implements the qlc Parse Transform.
--export([parse_transform/2, transform_from_evaluator/2,
+-export([parse_transform/2, transform_from_evaluator/2,
transform_expression/2]).
-include_lib("stdlib/include/ms_transform.hrl").
@@ -29,10 +29,9 @@
-define(APIMOD, qlc).
-define(Q, q).
-%% Also in qlc.erl.
--define(QLC_Q(L1, L2, L3, L4, LC, Os),
- {call,L1,{remote,L2,{atom,L3,?APIMOD},{atom,L4,?Q}},[LC | Os]}).
--define(IMP_Q(L1, L2, LC, Os), {call,L,{atom,L2,?Q},[LC | Os]}).
+-define(QLC_Q(A1, A2, A3, A4, LC, Os),
+ {call,A1,{remote,A2,{atom,A3,?APIMOD},{atom,A4,?Q}},[LC | Os]}).
+-define(IMP_Q(A1, A2, LC, Os), {call,Anno,{atom,A2,?Q},[LC | Os]}).
%% Also in qlc.erl.
-record(qlc_lc, % qlc:q/1,2, a query handle
@@ -83,11 +82,11 @@ parse_transform(Forms0, Options) ->
true ->
%% The returned value should conform to the types, but
%% need not evaluate to anything meaningful.
- L = anno0(),
- {tuple,_,Fs0} = abstr(#qlc_lc{}, L),
+ Anno = anno0(),
+ {tuple,_,Fs0} = abstr(#qlc_lc{}, Anno),
F = fun(_Id, LC, A) ->
- Init = simple(L, 'V', LC, L),
- {{tuple,L,set_field(#qlc_lc.lc, Fs0, Init)}, A}
+ Init = simple(Anno, 'V', LC, Anno),
+ {{tuple,Anno,set_field(#qlc_lc.lc, Fs0, Init)}, A}
end,
{Forms1,ok} = qlc_mapfold(F, ok, Forms, State),
Forms1;
@@ -145,12 +144,13 @@ called_from_type_checker(Options) ->
lists:member(type_checker, Options).
transform_expression(LC, Bs0, WithLintErrors) ->
- L = anno1(),
- As = [{var,L,V} || {V,_Val} <- Bs0],
+ Anno = anno1(),
+ As = [{var,Anno,V} || {V,_Val} <- Bs0],
Ar = length(As),
- F = {function,L,bar,Ar,[{clause,L,As,[],[?QLC_Q(L, L, L, L, LC, [])]}]},
- Forms0 = [{attribute,L,file,{"foo",L}},
- {attribute,L,module,foo}, F],
+ F = {function,Anno,bar,Ar,
+ [{clause,Anno,As,[],[?QLC_Q(Anno, Anno, Anno, Anno, LC, [])]}]},
+ Forms0 = [{attribute,Anno,file,{"foo",Anno}},
+ {attribute,Anno,module,foo}, F],
{Forms, FormsNoShadows, State} = initiate(Forms0, false),
NodeInfo = State#state.node_info,
Options = [],
@@ -160,7 +160,7 @@ transform_expression(LC, Bs0, WithLintErrors) ->
[] ->
{NewForms,_State1} = transform(FormsNoShadows, State),
NewForms1 = restore_anno(NewForms, NodeInfo),
- {function,L,bar,Ar,[{clause,L,As,[],[NF]}]} =
+ {function,Anno,bar,Ar,[{clause,Anno,As,[],[NF]}]} =
lists:last(NewForms1),
{ok,NF};
Errors when WithLintErrors ->
@@ -219,11 +219,11 @@ integers(I, L) when is_integer(I), I > ?ILIM ->
integers(_, L) ->
L.
--define(I(I), {integer, L, I}).
--define(A(A), {atom, L, A}).
--define(V(V), {var, L, V}).
--define(ABST_NO_MORE, {nil, L}).
--define(ABST_MORE(Obj, Cont), {cons, L, Obj, Cont}).
+-define(I(I), {integer, Anno, I}).
+-define(A(A), {atom, Anno, A}).
+-define(V(V), {var, Anno, V}).
+-define(ABST_NO_MORE, {nil, Anno}).
+-define(ABST_MORE(Obj, Cont), {cons, Anno, Obj, Cont}).
%% Qualifier identifier.
%% The first one encountered in a QLC has no=1.
@@ -262,9 +262,9 @@ mforms(L) ->
lists:sort([{File,[M]} || {File,Ms} <- L, M <- Ms]).
mforms2(Tag, L) ->
- Line = anno0(),
+ Anno = anno0(),
ML = lists:flatmap(fun({File,Ms}) ->
- [[{attribute,Line,file,{File,0}}, {Tag,M}] ||
+ [[{attribute,Anno,file,{File,0}}, {Tag,M}] ||
M <- Ms]
end, lists:sort(L)),
lists:flatten(lists:sort(ML)).
@@ -292,8 +292,8 @@ record_attributes(Forms) ->
%%
compile_messages(Forms, FormsNoShadows, Options, State) ->
%% The qlc module cannot handle binary generators.
- BGenF = fun(_QId,{b_generate,Line,_P,_LE}=BGen, GA, A) ->
- M = {loc(Line),?APIMOD,binary_generator},
+ BGenF = fun(_QId,{b_generate,Anno,_P,_LE}=BGen, GA, A) ->
+ M = {loc(Anno),?APIMOD,binary_generator},
{BGen,[{get(?QLC_FILE),[M]}|GA],A};
(_QId, Q, GA, A) ->
{Q,GA,A}
@@ -314,7 +314,7 @@ compile_messages(Forms, FormsNoShadows, Options, State) ->
{Errors,Warnings}.
badarg(Forms, State) ->
- F = fun(_Id, {lc,_L,_E,_Qs}=LC, Es) ->
+ F = fun(_Id, {lc,_A,_E,_Qs}=LC, Es) ->
{LC,Es};
(Id, A, Es) ->
E = {get_lcid_line(Id),?APIMOD,not_a_query_list_comprehension},
@@ -372,7 +372,7 @@ genvar_pos(Location, S) ->
%%
intro_variables(FormsNoShadows, State) ->
NodeInfo = State#state.node_info,
- Fun = fun(QId, {T,_L,P0,_E0}=Q, {GVs,QIds}, Foo) when T =:= b_generate;
+ Fun = fun(QId, {T,_A,P0,_E0}=Q, {GVs,QIds}, Foo) when T =:= b_generate;
T =:= generate ->
PVs = qlc:var_ufold(fun({var,_,V}) -> {QId,V} end, P0),
{Q,{ordsets:to_list(PVs) ++ GVs,[{QId,[]} | QIds]},Foo};
@@ -381,12 +381,12 @@ intro_variables(FormsNoShadows, State) ->
%% where E is an LC expression consisting of a
%% template mentioning all variables occurring in F.
Vs = ordsets:to_list(qlc:vars(Filter0)),
- AnyLine = anno0(),
- Vars = [{var,AnyLine,V} || V <- Vs],
- LC = embed_vars(Vars, AnyLine),
+ AnyAnno = anno0(),
+ Vars = [{var,AnyAnno,V} || V <- Vs],
+ LC = embed_vars(Vars, AnyAnno),
LC1 = intro_anno(LC, before, QId, NodeInfo),
LC2 = intro_anno(LC, 'after', QId, NodeInfo),
- Filter = {block,AnyLine,[LC1,Filter0,LC2]},
+ Filter = {block,AnyAnno,[LC1,Filter0,LC2]},
{Filter,{GVs,[{QId,[]} | QIds]},Foo}
end,
Acc0 = {[],[]},
@@ -417,7 +417,7 @@ intro_variables(FormsNoShadows, State) ->
intro_anno(LC, Where, QId, NodeInfo) ->
Data = {QId,Where},
Fun = fun(Anno) ->
- Location = erl_anno:location(Anno),
+ Location = loc(Anno),
true = ets:insert(NodeInfo, {Location,Data}),
Anno
end,
@@ -481,14 +481,14 @@ bitstr_options() ->
%%
used_genvar_check(FormsNoShadows, State) ->
NodeInfo = State#state.node_info,
- F = fun(QId, {T, Ln, _P, LE}=Q, {QsIVs0, Exprs0}, IVsSoFar0)
+ F = fun(QId, {T, AnnoQ, _P, LE}=Q, {QsIVs0, Exprs0}, IVsSoFar0)
when T =:= b_generate; T =:= generate ->
F = fun(Var) ->
{var, Anno0, OrigVar} =
undo_no_shadows(Var, State),
{var, Anno, _} = NewVar = save_anno(Var, NodeInfo),
- Location0 = erl_anno:location(Anno0),
- Location = erl_anno:location(Anno),
+ Location0 = loc(Anno0),
+ Location = loc(Anno),
[{Location, Data}] =
ets:lookup(NodeInfo, Location),
Pos = {Location0,get(?QLC_FILE),OrigVar},
@@ -500,7 +500,7 @@ used_genvar_check(FormsNoShadows, State) ->
lists:member(V, IVsSoFar0)],
Exprs = case Vs of
[] -> Exprs0;
- _ -> [embed_vars(Vs, Ln) | Exprs0]
+ _ -> [embed_vars(Vs, AnnoQ) | Exprs0]
end,
{QsIVs,IVsSoFar} = q_intro_vars(QId, QsIVs0, IVsSoFar0),
{Q, {QsIVs, Exprs}, IVsSoFar};
@@ -606,7 +606,7 @@ q_intro_vars(QId, [{QId, IVs} | QsIVs], IVsSoFar) -> {QsIVs, IVs ++ IVsSoFar}.
%% There is one special case when calling the fun stored in the 'lc'
%% field returns something else:
%% - If the QLC has the form [Var || Var <- LE] and there are no
-%% options to qlc:q/2, a tuple {simple_v1, P, LEf, Line} is returned.
+%% options to qlc:q/2, a tuple {simple_v1, P, LEf, Anno} is returned.
%% The objects returned are the objects returned by the generator
%% (calling LEf returns the objects generated by LE).
@@ -634,13 +634,13 @@ transform(FormsNoShadows, State) ->
(QId, F, Dict, Foo) ->
{F,maps:put(QId, F, Dict),Foo}
end, maps:new(), [], FormsNoShadows, State),
- {_,Source} = qlc_mapfold(fun(Id, {lc,_L,E,_Qs}=LC, Dict) ->
+ {_,Source} = qlc_mapfold(fun(Id, {lc,_A,E,_Qs}=LC, Dict) ->
{LC,maps:put(Id, E, Dict)}
end, Source0, FormsNoShadows, State),
%% Unused variables introduced in filters are not optimized away.
- F2 = fun(Id, {lc,_L,E,Qs}, {IntroVs0,XWarn0}) ->
+ F2 = fun(Id, {lc,_A,E,Qs}, {IntroVs0,XWarn0}) ->
LcNo = get_lcid_no(Id),
LcL = get_lcid_line(Id),
[RL,Fun,Go,NGV,S0,RL0,Go0,AT,Err] =
@@ -661,7 +661,7 @@ transform(FormsNoShadows, State) ->
{QCs, AllIVs} = lists:mapfoldl(F, [], IntroVs_Qs),
Dependencies = qualifier_dependencies(Qs, IntroVs),
- L = no_compiler_warning(LcL),
+ Anno = no_compiler_warning(LcL),
{EqColumnConstants, EqualColumnConstants,
ExtraConsts, SizeInfo} =
constants_and_sizes(Qs, E, Dependencies, AllIVs, State),
@@ -672,41 +672,41 @@ transform(FormsNoShadows, State) ->
%% But there are a few cases where qlc finds more... (r12b).
FWarn = warn_failing_qualifiers(Qs, AllIVs, Dependencies,
State),
- JQs = join_quals(JoinInfo, QCs, L, LcNo, ExtraConsts, AllVars),
+ JQs = join_quals(JoinInfo, QCs, Anno, LcNo, ExtraConsts, AllVars),
XQCs = QCs ++ JQs,
Cs0 = clauses(XQCs, RL, Fun, Go, NGV, Err, AllIVs, State),
- Template = template(E, RL, Fun, Go, AT, L, AllIVs, State),
- Fin = final(RL, AllIVs, L, State),
- FunC = {'fun',L,{clauses,Fin ++ Template ++ Cs0}},
+ Template = template(E, RL, Fun, Go, AT, Anno, AllIVs, State),
+ Fin = final(RL, AllIVs, Anno, State),
+ FunC = {'fun',Anno,{clauses,Fin ++ Template ++ Cs0}},
As0 = pack_args(abst_vars([S0, RL0, Fun, Go0
| replace(AllIVs, AllIVs, nil)],
- L), L, State),
- AsW = abst_vars([S0, RL0, Go0], L),
- FunW = {'fun',L,{clauses,[{clause,L,AsW,[],
- [{match,L,{var,L,Fun},FunC},
- {call,L,{var,L,Fun},As0}]}]}},
+ Anno), Anno, State),
+ AsW = abst_vars([S0, RL0, Go0], Anno),
+ FunW = {'fun',Anno,{clauses,[{clause,Anno,AsW,[],
+ [{match,Anno,{var,Anno,Fun},FunC},
+ {call,Anno,{var,Anno,Fun},As0}]}]}},
OrigE0 = map_get(Id, Source),
OrigE = undo_no_shadows(OrigE0, State),
- QCode = qcode(OrigE, XQCs, Source, L, State),
- Qdata = qdata(XQCs, L),
+ QCode = qcode(OrigE, XQCs, Source, Anno, State),
+ Qdata = qdata(XQCs, Anno),
TemplateInfo =
template_columns(Qs, E, AllIVs, Dependencies, State),
%% ExtraConsts should be used by match_spec_quals.
MSQs = match_spec_quals(E, Dependencies, Qs, State),
- Opt = opt_info(TemplateInfo, SizeInfo, JoinInfo, MSQs, L,
+ Opt = opt_info(TemplateInfo, SizeInfo, JoinInfo, MSQs, Anno,
EqColumnConstants, EqualColumnConstants),
LCTuple =
case qlc_kind(OrigE, Qs, State) of
qlc ->
- {tuple,L,[?A(qlc_v1),FunW,QCode,Qdata,Opt]};
- {simple, PL, LE, V} ->
- Init = closure(LE, L),
- simple(L, V, Init, PL)
+ {tuple,Anno,[?A(qlc_v1),FunW,QCode,Qdata,Opt]};
+ {simple, PAnno, LE, V} ->
+ Init = closure(LE, Anno),
+ simple(Anno, V, Init, PAnno)
end,
- LCFun = {'fun',L,{clauses,[{clause,L,[],[],[LCTuple]}]}},
- {tuple,_,Fs0} = abstr(#qlc_lc{}, L),
+ LCFun = {'fun',Anno,{clauses,[{clause,Anno,[],[],[LCTuple]}]}},
+ {tuple,_,Fs0} = abstr(#qlc_lc{}, Anno),
Fs = set_field(#qlc_lc.lc, Fs0, LCFun),
- {{tuple,L,Fs},{RestIntroVs,FWarn++XWarn++XWarn0}}
+ {{tuple,Anno,Fs},{RestIntroVs,FWarn++XWarn++XWarn0}}
end,
{NForms,{[],XW}} = qlc_mapfold(F2, {IntroVars,[]}, ModifiedForms1, State),
display_forms(NForms),
@@ -788,30 +788,30 @@ warn_failing_qualifiers(Qualifiers, AllIVs, Dependencies, State) ->
-define(TNO, 0).
-define(TID, #qid{lcid = template, no = ?TNO}).
-opt_info(TemplateInfo, Sizes, JoinInfo, MSQs, L,
+opt_info(TemplateInfo, Sizes, JoinInfo, MSQs, Anno,
EqColumnConstants0, EqualColumnConstants0) ->
- SzCls = [{clause,L,[?I(C)],[],[?I(Sz)]} || {C,Sz} <- lists:sort(Sizes)]
- ++ [{clause,L,[?V('_')],[],[?A(undefined)]}],
- S = [{size, {'fun', L, {clauses, SzCls}}}],
- J = case JoinInfo of [] -> []; _ -> [{join, abstr(JoinInfo, L)}] end,
+ SzCls = [{clause,Anno,[?I(C)],[],[?I(Sz)]} || {C,Sz} <- lists:sort(Sizes)]
+ ++ [{clause,Anno,[?V('_')],[],[?A(undefined)]}],
+ S = [{size, {'fun', Anno, {clauses, SzCls}}}],
+ J = case JoinInfo of [] -> []; _ -> [{join, abstr(JoinInfo, Anno)}] end,
%% Superfluous clauses may be emitted:
TCls0 = lists:append(
- [[{clause,L,[abstr(Col, L),EqType],[],
- [abstr(TemplCols, L)]} ||
+ [[{clause,Anno,[abstr(Col, Anno),EqType],[],
+ [abstr(TemplCols, Anno)]} ||
{Col,TemplCols} <- TemplateColumns]
|| {EqType, TemplateColumns} <- TemplateInfo]),
- TCls = lists:sort(TCls0) ++ [{clause,L,[?V('_'),?V('_')],[],[{nil,L}]}],
- T = [{template, {'fun', L, {clauses, TCls}}}],
+ TCls = lists:sort(TCls0) ++ [{clause,Anno,[?V('_'),?V('_')],[],[{nil,Anno}]}],
+ T = [{template, {'fun', Anno, {clauses, TCls}}}],
%% The template may also have a constant function (IdNo = 0).
%% Only constant template columns are interesting.
EqColumnConstants = opt_column_constants(EqColumnConstants0),
- CCs = opt_constants(L, EqColumnConstants),
- EqC = {constants,{'fun',L,{clauses,CCs}}},
+ CCs = opt_constants(Anno, EqColumnConstants),
+ EqC = {constants,{'fun',Anno,{clauses,CCs}}},
EqualColumnConstants = opt_column_constants(EqualColumnConstants0),
- ECCs = opt_constants(L, EqualColumnConstants),
- EqualC = {equal_constants,{'fun',L,{clauses,ECCs}}},
+ ECCs = opt_constants(Anno, EqualColumnConstants),
+ EqualC = {equal_constants,{'fun',Anno,{clauses,ECCs}}},
C = [EqC | [EqualC || true <- [CCs =/= ECCs]]],
%% Comparisons yield more constant columns than matchings.
@@ -820,41 +820,41 @@ opt_info(TemplateInfo, Sizes, JoinInfo, MSQs, L,
ConstColsFamily = family_list(ConstCols),
NSortedCols0 = [{IdNo,hd(lists:seq(1, length(Cols)+1)--Cols)} ||
{IdNo,Cols} <- ConstColsFamily],
- NCls = [{clause,L,[?I(IdNo)],[],[?I(N-1)]} ||
+ NCls = [{clause,Anno,[?I(IdNo)],[],[?I(N-1)]} ||
{IdNo,N} <- NSortedCols0, N > 0]
- ++ [{clause,L,[?V('_')],[],[?I(0)]}],
- N = [{n_leading_constant_columns,{'fun',L,{clauses,NCls}}}],
+ ++ [{clause,Anno,[?V('_')],[],[?I(0)]}],
+ N = [{n_leading_constant_columns,{'fun',Anno,{clauses,NCls}}}],
- ConstCls = [{clause,L,[?I(IdNo)],[],[abstr(Cols,L)]} ||
+ ConstCls = [{clause,Anno,[?I(IdNo)],[],[abstr(Cols,Anno)]} ||
{IdNo,Cols} <- ConstColsFamily]
- ++ [{clause,L,[?V('_')],[],[{nil,L}]}],
- CC = [{constant_columns,{'fun',L,{clauses,ConstCls}}}],
+ ++ [{clause,Anno,[?V('_')],[],[{nil,Anno}]}],
+ CC = [{constant_columns,{'fun',Anno,{clauses,ConstCls}}}],
- MSCls = [{clause,L,[?I(G)],[],[{tuple,L,[MS,abstr(Fs,L)]}]} ||
+ MSCls = [{clause,Anno,[?I(G)],[],[{tuple,Anno,[MS,abstr(Fs,Anno)]}]} ||
{G,MS,Fs} <- MSQs]
- ++ [{clause,L,[?V('_')],[],[?A(undefined)]}],
- MS = [{match_specs, {'fun',L,{clauses,MSCls}}}],
+ ++ [{clause,Anno,[?V('_')],[],[?A(undefined)]}],
+ MS = [{match_specs, {'fun',Anno,{clauses,MSCls}}}],
- Cls = [{clause,L,[?A(Tag)],[],[V]} ||
+ Cls = [{clause,Anno,[?A(Tag)],[],[V]} ||
{Tag,V} <- lists:append([J, S, T, C, N, CC, MS])]
- ++ [{clause,L,[?V('_')],[],[?A(undefined)]}],
- {'fun', L, {clauses, Cls}}.
+ ++ [{clause,Anno,[?V('_')],[],[?A(undefined)]}],
+ {'fun', Anno, {clauses, Cls}}.
opt_column_constants(ColumnConstants0) ->
[CC || {{IdNo,_Col},Const,_FilNs}=CC <- ColumnConstants0,
(IdNo =/= ?TNO) or (length(Const) =:= 1)].
-opt_constants(L, ColumnConstants) ->
+opt_constants(Anno, ColumnConstants) ->
Ns = lists:usort([IdNo || {{IdNo,_Col},_Const,_FilNs} <- ColumnConstants]),
- [{clause,L,[?I(IdNo)],[],[column_fun(ColumnConstants, IdNo, L)]}
+ [{clause,Anno,[?I(IdNo)],[],[column_fun(ColumnConstants, IdNo, Anno)]}
|| IdNo <- Ns]
- ++ [{clause,L,[?V('_')],[],[?A(no_column_fun)]}].
+ ++ [{clause,Anno,[?V('_')],[],[?A(no_column_fun)]}].
abstr(Term, Anno) ->
erl_parse:abstract(Term, loc(Anno)).
%% Extra generators are introduced for join.
-join_quals(JoinInfo, QCs, L, LcNo, ExtraConstants, AllVars) ->
+join_quals(JoinInfo, QCs, Anno, LcNo, ExtraConstants, AllVars) ->
{LastGoI, LastSI} =
lists:foldl(fun({_QId,{_QIVs,{{fil,_},GoI,SI}}},
{GoI0, _SI0}) when GoI >= GoI0 ->
@@ -891,18 +891,18 @@ join_quals(JoinInfo, QCs, L, LcNo, ExtraConstants, AllVars) ->
QId#qid.no =:= Q2],
{QId1,Op,P1,GV1,QIVs1++QIVs2,QId2,P2}
end || {Q1, Q2, Op} <- lists:usort(QNums)],
- Aux = abst_vars(aux_vars(['F','H','O','C'], LcNo, AllVars), L),
+ Aux = abst_vars(aux_vars(['F','H','O','C'], LcNo, AllVars), Anno),
F = fun({QId1,Op,P1,GV1,QIVs,QId2,P2}, {QId,GoI,SI}) ->
AP1 = anon_pattern(P1),
AP2 = anon_pattern(P2),
Cs1 = join_handle_constants(QId1, ExtraConstants),
Cs2 = join_handle_constants(QId2, ExtraConstants),
- H1 = join_handle(AP1, L, Aux, Cs1),
- H2 = join_handle(AP2, L, Aux, Cs2),
+ H1 = join_handle(AP1, Anno, Aux, Cs1),
+ H2 = join_handle(AP2, Anno, Aux, Cs2),
%% Op is not used.
Join = {join,Op,QId1#qid.no,QId2#qid.no,H1,H2,Cs1,Cs2},
G = {NQId=QId#qid{no = QId#qid.no + 1},
- {QIVs,{{gen,{cons,L,P1,P2},Join,GV1},GoI,SI}}},
+ {QIVs,{{gen,{cons,Anno,P1,P2},Join,GV1},GoI,SI}}},
A = {NQId, GoI + 3, SI + 2},
{G, A}
end,
@@ -915,12 +915,12 @@ join_qnums(Cols) ->
%% Variables occurring only once are replaced by '_'.
anon_pattern(P) ->
MoreThanOnce = lists:usort(occ_vars(P) -- qlc:vars(P)),
- {AP, foo} = var_mapfold(fun({var, L, V}, A) ->
+ {AP, foo} = var_mapfold(fun({var, Anno, V}, A) ->
case lists:member(V, MoreThanOnce) of
true ->
- {{var, L, V}, A};
+ {{var, Anno, V}, A};
false ->
- {{var, L, '_'}, A}
+ {{var, Anno, '_'}, A}
end
end, foo, P),
AP.
@@ -931,10 +931,10 @@ anon_pattern(P) ->
%% in order to determine if key-sorting the operands can be avoided.
%%
%% No objects will be filtered out if the pattern is just a variable.
-join_handle(AP, L, [F, H, O, C], Constants) ->
+join_handle(AP, Anno, [F, H, O, C], Constants) ->
case {AP, Constants} of
{{var, _, _}, []} ->
- {'fun',L,{clauses,[{clause,L,[H],[],[H]}]}};
+ {'fun',Anno,{clauses,[{clause,Anno,[H],[],[H]}]}};
_ ->
A = anno0(),
G0 = [begin
@@ -942,18 +942,19 @@ join_handle(AP, L, [F, H, O, C], Constants) ->
list2op([{op,A,Op,Con,Call} || {Con,Op} <- Cs], 'or')
end || {Col,Cs} <- Constants],
G = if G0 =:= [] -> G0; true -> [G0] end,
- CC1 = {clause,L,[AP],G,[{cons,L,O,closure({call,L,F,[F,C]},L)}]},
- CC2 = {clause,L,[?V('_')],[],[{call,L,F,[F,C]}]},
- Case = {'case',L,O,[CC1,CC2]},
- Cls = [{clause,L,[?V('_'),{nil,L}],[],[{nil,L}]},
- {clause,L,[F,{cons,L,O,C}],[],[Case]},
- {clause,L,[F,C],[[{call,L,?A(is_function),[C]}]],
- [{call,L,F,[F,{call,L,C,[]}]}]},
- {clause,L,[?V('_'),C],[],[C]}],
- Fun = {'fun', L, {clauses, Cls}},
- {'fun',L,{clauses,[{clause,L,[H],[],[{match,L,F,Fun},
- closure({call,L,F,[F,H]},
- L)]}]}}
+ CC1 = {clause,Anno,[AP],G,
+ [{cons,Anno,O,closure({call,Anno,F,[F,C]},Anno)}]},
+ CC2 = {clause,Anno,[?V('_')],[],[{call,Anno,F,[F,C]}]},
+ Case = {'case',Anno,O,[CC1,CC2]},
+ Cls = [{clause,Anno,[?V('_'),{nil,Anno}],[],[{nil,Anno}]},
+ {clause,Anno,[F,{cons,Anno,O,C}],[],[Case]},
+ {clause,Anno,[F,C],[[{call,Anno,?A(is_function),[C]}]],
+ [{call,Anno,F,[F,{call,Anno,C,[]}]}]},
+ {clause,Anno,[?V('_'),C],[],[C]}],
+ Fun = {'fun', Anno, {clauses, Cls}},
+ {'fun',Anno,{clauses,[{clause,Anno,[H],[],
+ [{match,Anno,F,Fun},
+ closure({call,Anno,F,[F,H]}, Anno)]}]}}
end.
join_handle_constants(QId, ExtraConstants) ->
@@ -1021,7 +1022,7 @@ template_columns(Qs0, E0, AllIVs, Dependencies, State) ->
MatchColumns = eq_columns2(Qs, AllIVs, Dependencies, State),
Equal = template_cols(EqualColumns),
Match = template_cols(MatchColumns),
- L = anno0(),
+ Anno = anno0(),
if
Match =:= Equal ->
[{?V('_'), Match}];
@@ -1050,16 +1051,16 @@ template_as_pattern(E) ->
P = simple_template(E),
{?TID,foo,foo,{gen,P,{nil,anno0()}}}.
-simple_template({call,L,{remote,_,{atom,_,erlang},{atom,_,element}}=Call,
+simple_template({call,Anno,{remote,_,{atom,_,erlang},{atom,_,element}}=Call,
[{integer,_,I}=A1,A2]}) when I > 0 ->
%% This kludge is known by pattern/5 below.
- {call, L, Call, [A1, simple_template(A2)]};
+ {call, Anno, Call, [A1, simple_template(A2)]};
simple_template({var, _, _}=E) ->
E;
-simple_template({tuple, L, Es}) ->
- {tuple, L, [simple_template(E) || E <- Es]};
-simple_template({cons, L, H, T}) ->
- {cons, L, simple_template(H), simple_template(T)};
+simple_template({tuple, Anno, Es}) ->
+ {tuple, Anno, [simple_template(E) || E <- Es]};
+simple_template({cons, Anno, H, T}) ->
+ {cons, Anno, simple_template(H), simple_template(T)};
simple_template(E) ->
case catch erl_parse:normalise(E) of
{'EXIT', _} -> unique_var();
@@ -1152,17 +1153,17 @@ pattern_as_template({var,_,'_'}, TemplVar) ->
{TemplVar, TemplVar};
pattern_as_template({var,_,_}=V, _TemplVar) ->
{V, V};
-pattern_as_template({match,L,E,{var,_,'_'}}, TemplVar) ->
- {TemplVar, {match,L,E,TemplVar}};
-pattern_as_template({match,L,{var,_,'_'},E}, TemplVar) ->
- {TemplVar, {match,L,E,TemplVar}};
+pattern_as_template({match,Anno,E,{var,_,'_'}}, TemplVar) ->
+ {TemplVar, {match,Anno,E,TemplVar}};
+pattern_as_template({match,Anno,{var,_,'_'},E}, TemplVar) ->
+ {TemplVar, {match,Anno,E,TemplVar}};
pattern_as_template({match,_,_E,{var,_,_}=V}=P, _TemplVar) ->
{V, P};
pattern_as_template({match,_,{var,_,_}=V,_E}=P, _TemplVar) ->
{V, P};
pattern_as_template(E, TemplVar) ->
- L = anno0(),
- {TemplVar, {match, L, E, TemplVar}}.
+ Anno = anno0(),
+ {TemplVar, {match, Anno, E, TemplVar}}.
%% Tries to find columns which are compared or matched against
%% constant values or other columns. To that end unification is used.
@@ -1645,8 +1646,8 @@ match_in_pattern(E, F, _BF) ->
-define(ANON_VAR(N), N).
anon_var(E, AnonI) ->
- var_mapfold(fun({var, L, '_'}, N) ->
- {{var, L, ?ANON_VAR(N)}, N+1};
+ var_mapfold(fun({var, Anno, '_'}, N) ->
+ {{var, Anno, ?ANON_VAR(N)}, N+1};
(Var, N) -> {Var, N}
end, AnonI, E).
@@ -1709,15 +1710,17 @@ filter1({op, _, Op, L, R}, Fs, FS) when Op =:= 'or';
filter1(L, Fs, FS) ++ filter1(R, Fs, FS);
filter1({atom,_,Atom}, _Fs, _FS) when Atom =/= true ->
[];
-filter1({call,L,{remote,_,{atom,_,erlang},{atom,_,is_record}},[T,R]},
+filter1({call,Anno,{remote,_,{atom,_,erlang},{atom,_,is_record}},[T,R]},
Fs, FS) ->
- filter1({op,L,'=:=',{call,L,{remote,L,{atom,L,erlang},{atom,L,element}},
- [{integer,L,1},T]},R},
+ filter1({op,Anno,'=:=',
+ {call,Anno,{remote,Anno,{atom,Anno,erlang},{atom,Anno,element}},
+ [{integer,Anno,1},T]},R},
Fs, FS);
%% erlang:is_record/3 (the size information is ignored):
-filter1({call,L,{remote,L1,{atom,_,erlang}=M,{atom,L2,is_record}},[T,R,_Sz]},
- Fs, FS) ->
- filter1({call,L,{remote,L1,M,{atom,L2,is_record}},[T,R]}, Fs, FS);
+filter1({call,Anno,{remote,Anno1,{atom,_,erlang}=M,{atom,Anno2,is_record}},
+ [T,R,_Sz]}, Fs, FS) ->
+ filter1({call,Anno,{remote,Anno1,M,{atom,Anno2,is_record}},[T,R]},
+ Fs, FS);
filter1(_E, Fs, _FS) ->
Fs.
@@ -1753,12 +1756,12 @@ safe_filter1(_E, _Fs, _FS) ->
%% Substitutions:
%% M:F() for {M,F}(); erlang:F() for F(); is_record() for record().
-pre_expand({call,L1,{atom,L2,record},As}) ->
- pre_expand({call,L1,{atom,L2,is_record},As});
-pre_expand({call,L,{atom,_,_}=F,As}) ->
- pre_expand({call,L,{remote,L,{atom,L,erlang},F},As});
-pre_expand({call,L,{tuple,_,[M,F]},As}) ->
- pre_expand({call,L,{remote,L,M,F},As});
+pre_expand({call,Anno1,{atom,Anno2,record},As}) ->
+ pre_expand({call,Anno1,{atom,Anno2,is_record},As});
+pre_expand({call,Anno,{atom,_,_}=F,As}) ->
+ pre_expand({call,Anno,{remote,Anno,{atom,Anno,erlang},F},As});
+pre_expand({call,Anno,{tuple,_,[M,F]},As}) ->
+ pre_expand({call,Anno,{remote,Anno,M,F},As});
pre_expand(T) when is_tuple(T) ->
list_to_tuple(pre_expand(tuple_to_list(T)));
pre_expand([E | Es]) ->
@@ -1905,7 +1908,7 @@ element_calls(E, F, _BF, _Imported) ->
unique_var() ->
{var, anno0(), make_ref()}.
-is_unique_var({var, _L, V}) ->
+is_unique_var({var, _A, V}) ->
is_reference(V).
expand_pattern_records(P, State) ->
@@ -1923,10 +1926,10 @@ expand_expr_records(E, State) ->
NE.
%% Partial evaluation.
-pe({op,Line,Op,A}) ->
- erl_eval:partial_eval({op,Line,Op,pe(A)});
-pe({op,Line,Op,L,R}) ->
- erl_eval:partial_eval({op,Line,Op,pe(L),pe(R)});
+pe({op,Anno,Op,A}) ->
+ erl_eval:partial_eval({op,Anno,Op,pe(A)});
+pe({op,Anno,Op,L,R}) ->
+ erl_eval:partial_eval({op,Anno,Op,pe(L),pe(R)});
pe(T) when is_tuple(T) ->
list_to_tuple(pe(tuple_to_list(T)));
pe([E | Es]) ->
@@ -2038,7 +2041,7 @@ deref_op('=:=', '=:=') ->
deref_op(_, _) ->
'=='.
-%%% Note: usort works; {integer,L,3} does not match {float,L,3.0}.
+%%% Note: usort works; {integer,A,3} does not match {float,A,3.0}.
var_values(Var, Frame) ->
[{Value, Op} ||
@@ -2278,14 +2281,14 @@ bindings_subset(F1, F2, Imp) ->
%% not to have guard semantics, affected filters will have to be
%% recognized and excluded here as well.
try_ms(E, P, Fltr, State) ->
- L = anno1(),
- Fun = {'fun',L,{clauses,[{clause,L,[P],[[Fltr]],[E]}]}},
- Expr = {call,L,{remote,L,{atom,L,ets},{atom,L,fun2ms}},[Fun]},
- Form = {function,L,foo,0,[{clause,L,[],[],[Expr]}]},
+ Anno = anno1(),
+ Fun = {'fun',Anno,{clauses,[{clause,Anno,[P],[[Fltr]],[E]}]}},
+ Expr = {call,Anno,{remote,Anno,{atom,Anno,ets},{atom,Anno,fun2ms}},[Fun]},
+ Form = {function,Anno,foo,0,[{clause,Anno,[],[],[Expr]}]},
X = ms_transform:parse_transform(State#state.records ++ [Form], []),
case catch
begin
- {function,L,foo,0,[{clause,L,[],[],[MS0]}]} = lists:last(X),
+ {function,Anno,foo,0,[{clause,Anno,[],[],[MS0]}]} = lists:last(X),
MS = erl_parse:normalise(var2const(MS0)),
XMS = ets:match_spec_compile(MS),
true = ets:is_compiled_ms(XMS),
@@ -2314,27 +2317,27 @@ qual_data(Qualifiers) ->
set_field(Pos, Fs, Data) ->
lists:sublist(Fs, Pos-1) ++ [Data] ++ lists:nthtail(Pos, Fs).
-qdata([{#qid{no = QIdNo},{_QIVs,{{gen,_P,LE,_GV},GoI,SI}}} | QCs], L) ->
+qdata([{#qid{no = QIdNo},{_QIVs,{{gen,_P,LE,_GV},GoI,SI}}} | QCs], Anno) ->
Init = case LE of
{join, Op, Q1, Q2, H1, H2, Cs1_0, Cs2_0} ->
Cs1 = qcon(Cs1_0),
Cs2 = qcon(Cs2_0),
- %% -- R12B-3: {nil,L}
- %% R12B-4 --: {atom,L,v1}
- Compat = {atom,L,v1}, % meant for redundant match spec
- CF = closure({tuple,L,[Cs1,Cs2,Compat]}, L),
- {tuple,L,[?A(join),?A(Op),?I(Q1),?I(Q2),H1,H2,CF]};
+ %% -- R12B-3: {nil,Anno}
+ %% R12B-4 --: {atom,Anno,v1}
+ Compat = {atom,Anno,v1}, % meant for redundant match spec
+ CF = closure({tuple,Anno,[Cs1,Cs2,Compat]}, Anno),
+ {tuple,Anno,[?A(join),?A(Op),?I(Q1),?I(Q2),H1,H2,CF]};
_ ->
- closure(LE, L)
+ closure(LE, Anno)
end,
%% Create qual_data (see qlc.erl):
- {cons,L,{tuple,L,[?I(QIdNo),?I(GoI),?I(SI),{tuple,L,[?A(gen),Init]}]},
- qdata(QCs, L)};
-qdata([{#qid{no = QIdNo},{_QIVs,{{fil,_F},GoI,SI}}} | QCs], L) ->
+ {cons,Anno,{tuple,Anno,[?I(QIdNo),?I(GoI),?I(SI),{tuple,Anno,[?A(gen),Init]}]},
+ qdata(QCs, Anno)};
+qdata([{#qid{no = QIdNo},{_QIVs,{{fil,_F},GoI,SI}}} | QCs], Anno) ->
%% Create qual_data (see qlc.erl):
- {cons,L,{tuple,L,[?I(QIdNo),?I(GoI),?I(SI),?A(fil)]},qdata(QCs, L)};
-qdata([], L) ->
- {nil,L}.
+ {cons,Anno,{tuple,Anno,[?I(QIdNo),?I(GoI),?I(SI),?A(fil)]},qdata(QCs, Anno)};
+qdata([], Anno) ->
+ {nil,Anno}.
qcon(Cs) ->
A = anno0(),
@@ -2348,15 +2351,15 @@ qcon1(ConstOps) ->
%% The original code (in Source) is used for filters and the template
%% since the translated code can have QLCs and we don't want them to
%% be visible.
-qcode(E, QCs, Source, L, State) ->
+qcode(E, QCs, Source, Anno, State) ->
CL = [begin
Bin = term_to_binary(C, [compressed]),
- {bin, L, [{bin_element, L,
- {string, L, binary_to_list(Bin)},
+ {bin, Anno, [{bin_element, Anno,
+ {string, Anno, binary_to_list(Bin)},
default, default}]}
end || {_,C} <- lists:keysort(1, [{qlc:template_state(),E} |
qcode(QCs, Source, State)])],
- {'fun', L, {clauses, [{clause, L, [], [], [{tuple, L, CL}]}]}}.
+ {'fun', Anno, {clauses, [{clause, Anno, [], [], [{tuple, Anno, CL}]}]}}.
qcode([{_QId, {_QIvs, {{gen,P,_LE,_GV}, GoI, _SI}}} | QCs], Source, State) ->
[{GoI,undo_no_shadows(P, State)} | qcode(QCs, Source, State)];
@@ -2366,149 +2369,150 @@ qcode([{QId, {_QIVs, {{fil,_F}, GoI, _SI}}} | QCs], Source, State) ->
qcode([], _Source, _State) ->
[].
-closure(Code, L) ->
- {'fun',L,{clauses,[{clause,L,[],[],[Code]}]}}.
+closure(Code, Anno) ->
+ {'fun',Anno,{clauses,[{clause,Anno,[],[],[Code]}]}}.
-simple(L, Var, Init, Anno) ->
- {tuple,L,[?A(simple_v1),?A(Var),Init,abstr(loc(Anno), Anno)]}.
+simple(Anno1, Var, Init, Anno) ->
+ {tuple,Anno1,[?A(simple_v1),?A(Var),Init,abstr(loc(Anno), Anno)]}.
clauses([{QId,{QIVs,{QualData,GoI,S}}} | QCs], RL, Fun, Go, NGV, E, IVs,St) ->
?DEBUG("QIVs = ~p~n", [QIVs]),
?DEBUG("IVs = ~p~n", [IVs]),
?DEBUG("GoI = ~p, S = ~p~n", [GoI, S]),
- L = no_compiler_warning(get_lcid_line(QId#qid.lcid)),
+ Anno = no_compiler_warning(get_lcid_line(QId#qid.lcid)),
Cs = case QualData of
{gen,P,_LE,GV} ->
- generator(S, QIVs, P, GV, NGV, E, IVs, RL, Fun, Go,GoI,L,St);
+ generator(S, QIVs, P, GV, NGV, E, IVs, RL, Fun,
+ Go, GoI, Anno, St);
{fil,F} ->
- filter(F, L, QIVs, S, RL, Fun, Go, GoI, IVs, St)
+ filter(F, Anno, QIVs, S, RL, Fun, Go, GoI, IVs, St)
end,
Cs ++ clauses(QCs, RL, Fun, Go, NGV, E, IVs, St);
clauses([], _RL, _Fun, _Go, _NGV, _IVs, _E, _St) ->
[].
-final(RL, IVs, L, State) ->
+final(RL, IVs, Anno, State) ->
IAs = replace(IVs, IVs, '_'),
- AsL = pack_args([?I(0) | abst_vars([RL, '_', '_'] ++ IAs, L)], L, State),
- Grd = [is_list_c(RL, L)],
- Rev = {call,L,{remote,L,?A(lists),?A(reverse)},[?V(RL)]},
- CL = {clause,L,AsL,[Grd],[Rev]},
- AsF = pack_args([?I(0) | abst_vars(['_', '_', '_'] ++ IAs, L)], L, State),
- CF = {clause,L,AsF,[],[?ABST_NO_MORE]},
+ AsL = pack_args([?I(0) | abst_vars([RL, '_', '_'] ++ IAs, Anno)], Anno, State),
+ Grd = [is_list_c(RL, Anno)],
+ Rev = {call,Anno,{remote,Anno,?A(lists),?A(reverse)},[?V(RL)]},
+ CL = {clause,Anno,AsL,[Grd],[Rev]},
+ AsF = pack_args([?I(0) | abst_vars(['_', '_', '_'] ++ IAs, Anno)], Anno, State),
+ CF = {clause,Anno,AsF,[],[?ABST_NO_MORE]},
[CL, CF].
-template(E, RL, Fun, Go, AT, L, IVs, State) ->
+template(E, RL, Fun, Go, AT, Anno, IVs, State) ->
I = qlc:template_state(), GoI = qlc:template_state(),
- ARL = {cons,L,E,abst_vars(RL, L)},
- Next = next(Go, GoI, L),
- As0 = abst_vars([RL, Fun, Go] ++ IVs, L),
- As = pack_args([?I(I) | As0], L, State),
- NAs = pack_args([Next, ARL] ++ abst_vars([Fun, Go] ++ IVs, L), L, State),
- Grd = [is_list_c(RL, L)],
- CL = {clause,L,As,[Grd],[{call,L,?V(Fun),NAs}]},
+ ARL = {cons,Anno,E,abst_vars(RL, Anno)},
+ Next = next(Go, GoI, Anno),
+ As0 = abst_vars([RL, Fun, Go] ++ IVs, Anno),
+ As = pack_args([?I(I) | As0], Anno, State),
+ NAs = pack_args([Next, ARL] ++ abst_vars([Fun, Go] ++ IVs, Anno), Anno, State),
+ Grd = [is_list_c(RL, Anno)],
+ CL = {clause,Anno,As,[Grd],[{call,Anno,?V(Fun),NAs}]},
%% Extra careful here or arguments will be lifted into a wide fun.
- F = case split_args([Next | As0], L, State) of
+ F = case split_args([Next | As0], Anno, State) of
{ArgsL, ArgsT} ->
- Call = {call,L,?V(Fun),ArgsL++[{var,L,AT}]},
- {block,L,
- [{match,L,{var,L,AT},ArgsT},
- {'fun',L,{clauses,[{clause,L,[],[],[Call]}]}}]};
+ Call = {call,Anno,?V(Fun),ArgsL++[{var,Anno,AT}]},
+ {block,Anno,
+ [{match,Anno,{var,Anno,AT},ArgsT},
+ {'fun',Anno,{clauses,[{clause,Anno,[],[],[Call]}]}}]};
FNAs ->
- {'fun',L,{clauses,[{clause,L,[],[],[{call,L,?V(Fun),FNAs}]}]}}
+ {'fun',Anno,{clauses,[{clause,Anno,[],[],[{call,Anno,?V(Fun),FNAs}]}]}}
end,
- CF = {clause,L,As,[],[?ABST_MORE(E, F)]},
+ CF = {clause,Anno,As,[],[?ABST_MORE(E, F)]},
[CL,CF].
-generator(S, QIVs, P, GV, NGV, E, IVs, RL, Fun, Go, GoI, L, State) ->
- ComAs = abst_vars([RL, Fun, Go], L),
- InitC = generator_init(S, L, GV, RL, Fun, Go, GoI, IVs, State),
- As = [?I(S + 1)| ComAs ++ abst_vars(replace(QIVs -- [GV], IVs, '_'), L)],
+generator(S, QIVs, P, GV, NGV, E, IVs, RL, Fun, Go, GoI, Anno, State) ->
+ ComAs = abst_vars([RL, Fun, Go], Anno),
+ InitC = generator_init(S, Anno, GV, RL, Fun, Go, GoI, IVs, State),
+ As = [?I(S + 1)| ComAs ++ abst_vars(replace(QIVs -- [GV], IVs, '_'), Anno)],
- MatchS = next(Go, GoI + 1, L),
- AsM0 = [MatchS | ComAs ++ abst_vars(replace([GV], IVs, NGV), L)],
- AsM = pack_args(AsM0, L, State),
+ MatchS = next(Go, GoI + 1, Anno),
+ AsM0 = [MatchS | ComAs ++ abst_vars(replace([GV], IVs, NGV), Anno)],
+ AsM = pack_args(AsM0, Anno, State),
ContS = ?I(S + 1),
QIVs__GV = QIVs -- [GV],
Tmp = replace([GV], replace(QIVs__GV, IVs, nil), NGV),
- AsC = pack_args([ContS | ComAs ++ abst_vars(Tmp, L)], L, State),
+ AsC = pack_args([ContS | ComAs ++ abst_vars(Tmp, Anno)], Anno, State),
- DoneS = next(Go, GoI, L),
- AsD0 = [DoneS | ComAs ++ abst_vars(replace(QIVs, IVs, nil), L)],
- AsD = pack_args(AsD0, L, State),
+ DoneS = next(Go, GoI, Anno),
+ AsD0 = [DoneS | ComAs ++ abst_vars(replace(QIVs, IVs, nil), Anno)],
+ AsD = pack_args(AsD0, Anno, State),
- CsL = generator_list(P, GV, NGV, As, AsM, AsC, AsD, Fun, L, State),
- CsF = generator_cont(P, GV, NGV, E, As, AsM, AsC, AsD, Fun, L, State),
+ CsL = generator_list(P, GV, NGV, As, AsM, AsC, AsD, Fun, Anno, State),
+ CsF = generator_cont(P, GV, NGV, E, As, AsM, AsC, AsD, Fun, Anno, State),
[InitC | CsL ++ CsF].
-generator_init(S, L, GV, RL, Fun, Go, GoI, IVs, State) ->
- As0 = abst_vars([RL, Fun, Go] ++ replace([GV], IVs, '_'), L),
- As = pack_args([?I(S) | As0], L, State),
- Next = next(Go, GoI + 2, L),
- NAs = pack_args([?I(S + 1) | replace([?V('_')], As0, Next)], L, State),
- {clause,L,As,[],[{call,L,?V(Fun),NAs}]}.
-
-generator_list(P, GV, NGV, As, AsM, AsC, AsD, Fun, L, State) ->
- As1 = pack_args(replace([?V(GV)], As, {cons,L,P,?V(NGV)}), L, State),
- As2 = pack_args(replace([?V(GV)], As, {cons,L,?V('_'),?V(NGV)}), L,State),
- As3 = pack_args(replace([?V(GV)], As, {nil,L}), L, State),
- CM = {clause,L,As1,[],[{call,L,?V(Fun),AsM}]},
- CC = {clause,L,As2,[],[{call,L,?V(Fun),AsC}]},
- CD = {clause,L,As3,[],[{call,L,?V(Fun),AsD}]},
+generator_init(S, Anno, GV, RL, Fun, Go, GoI, IVs, State) ->
+ As0 = abst_vars([RL, Fun, Go] ++ replace([GV], IVs, '_'), Anno),
+ As = pack_args([?I(S) | As0], Anno, State),
+ Next = next(Go, GoI + 2, Anno),
+ NAs = pack_args([?I(S + 1) | replace([?V('_')], As0, Next)], Anno, State),
+ {clause,Anno,As,[],[{call,Anno,?V(Fun),NAs}]}.
+
+generator_list(P, GV, NGV, As, AsM, AsC, AsD, Fun, Anno, State) ->
+ As1 = pack_args(replace([?V(GV)], As, {cons,Anno,P,?V(NGV)}), Anno, State),
+ As2 = pack_args(replace([?V(GV)], As, {cons,Anno,?V('_'),?V(NGV)}), Anno,State),
+ As3 = pack_args(replace([?V(GV)], As, {nil,Anno}), Anno, State),
+ CM = {clause,Anno,As1,[],[{call,Anno,?V(Fun),AsM}]},
+ CC = {clause,Anno,As2,[],[{call,Anno,?V(Fun),AsC}]},
+ CD = {clause,Anno,As3,[],[{call,Anno,?V(Fun),AsD}]},
[CM, CC, CD].
%% The clause 'CE' was added in R11B. The version of the generated was
%% however not incremented.
-generator_cont(P, GV, NGV, E, As0, AsM, AsC, AsD, Fun, L, State) ->
- As = pack_args(As0, L, State),
+generator_cont(P, GV, NGV, E, As0, AsM, AsC, AsD, Fun, Anno, State) ->
+ As = pack_args(As0, Anno, State),
CF1 = ?ABST_MORE(P, ?V(NGV)),
CF2 = ?ABST_MORE(?V('_'), ?V(NGV)),
CF3 = ?ABST_NO_MORE,
CF4 = ?V(E),
- CM = {clause,L,[CF1],[],[{call,L,?V(Fun),AsM}]},
- CC = {clause,L,[CF2],[],[{call,L,?V(Fun),AsC}]},
- CD = {clause,L,[CF3],[],[{call,L,?V(Fun),AsD}]},
- CE = {clause,L,[CF4],[],[CF4]},
+ CM = {clause,Anno,[CF1],[],[{call,Anno,?V(Fun),AsM}]},
+ CC = {clause,Anno,[CF2],[],[{call,Anno,?V(Fun),AsC}]},
+ CD = {clause,Anno,[CF3],[],[{call,Anno,?V(Fun),AsD}]},
+ CE = {clause,Anno,[CF4],[],[CF4]},
Cls = [CM, CC, CD, CE],
- B = {'case',L,{call,L,?V(GV),[]},Cls},
- [{clause,L,As,[],[B]}].
+ B = {'case',Anno,{call,Anno,?V(GV),[]},Cls},
+ [{clause,Anno,As,[],[B]}].
-filter(E, L, QIVs, S, RL, Fun, Go, GoI, IVs, State) ->
+filter(E, Anno, QIVs, S, RL, Fun, Go, GoI, IVs, State) ->
IAs = replace(QIVs, IVs, '_'),
- As = pack_args([?I(S) | abst_vars([RL, Fun, Go] ++ IAs, L)], L, State),
- NAs = abst_vars([RL, Fun, Go] ++ IVs, L),
- TNext = next(Go, GoI + 1, L),
- FNext = next(Go, GoI, L),
- NAsT = pack_args([TNext | NAs], L, State),
- NAsF = pack_args([FNext | NAs], L, State),
+ As = pack_args([?I(S) | abst_vars([RL, Fun, Go] ++ IAs, Anno)], Anno, State),
+ NAs = abst_vars([RL, Fun, Go] ++ IVs, Anno),
+ TNext = next(Go, GoI + 1, Anno),
+ FNext = next(Go, GoI, Anno),
+ NAsT = pack_args([TNext | NAs], Anno, State),
+ NAsF = pack_args([FNext | NAs], Anno, State),
%% This is the "guard semantics" used in ordinary list
%% comprehension: if a filter looks like a guard test, it returns
%% 'false' rather than fails.
Body = case is_guard_test(E, State) of
true ->
- CT = {clause,L,[],[[E]],[{call,L,?V(Fun),NAsT}]},
- CF = {clause,L,[],[[?A(true)]],[{call,L,?V(Fun),NAsF}]},
- [{'if',L,[CT,CF]}];
+ CT = {clause,Anno,[],[[E]],[{call,Anno,?V(Fun),NAsT}]},
+ CF = {clause,Anno,[],[[?A(true)]],[{call,Anno,?V(Fun),NAsF}]},
+ [{'if',Anno,[CT,CF]}];
false ->
- CT = {clause,L,[?A(true)],[],[{call,L,?V(Fun),NAsT}]},
- CF = {clause,L,[?A(false)],[],[{call,L,?V(Fun),NAsF}]},
- [{'case',L,E,[CT,CF]}]
+ CT = {clause,Anno,[?A(true)],[],[{call,Anno,?V(Fun),NAsT}]},
+ CF = {clause,Anno,[?A(false)],[],[{call,Anno,?V(Fun),NAsF}]},
+ [{'case',Anno,E,[CT,CF]}]
end,
- [{clause,L,As,[],Body}].
+ [{clause,Anno,As,[],Body}].
-pack_args(Args, L, State) ->
- case split_args(Args, L, State) of
+pack_args(Args, Anno, State) ->
+ case split_args(Args, Anno, State) of
{ArgsL, ArgsT} ->
ArgsL ++ [ArgsT];
_ ->
Args
end.
-split_args(Args, L, State) when length(Args) > State#state.maxargs ->
+split_args(Args, Anno, State) when length(Args) > State#state.maxargs ->
{lists:sublist(Args, State#state.maxargs-1),
- {tuple,L,lists:nthtail(State#state.maxargs-1, Args)}};
-split_args(Args, _L, _State) ->
+ {tuple,Anno,lists:nthtail(State#state.maxargs-1, Args)}};
+split_args(Args, _Anno, _State) ->
Args.
%% Replace every element in IEs that is a member of Es by R, keep all
@@ -2519,11 +2523,11 @@ replace(Es, IEs, R) ->
false -> E
end || E <- IEs].
-is_list_c(V, L) ->
- {call,L,?A(is_list),[?V(V)]}.
+is_list_c(V, Anno) ->
+ {call,Anno,?A(is_list),[?V(V)]}.
-next(Go, GoI, L) ->
- {call,L,?A(element),[?I(GoI),?V(Go)]}.
+next(Go, GoI, Anno) ->
+ {call,Anno,?A(element),[?I(GoI),?V(Go)]}.
aux_vars(Vars, LcN, AllVars) ->
[aux_var(Name, LcN, 0, 1, AllVars) || Name <- Vars].
@@ -2552,9 +2556,9 @@ anno1() ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
qual_fold(Fun, GlobAcc0, Acc0, Forms, State) ->
- F = fun(Id, {lc,L,E,Qs0}, GA0) ->
+ F = fun(Id, {lc,Anno,E,Qs0}, GA0) ->
{Qs,GA,_NA} = qual_fold(Qs0, Fun, GA0, Acc0, Id, 1, []),
- {{lc,L,E,Qs},GA};
+ {{lc,Anno,E,Qs},GA};
(_Id, Expr, GA) ->
{Expr,GA}
end,
@@ -2576,19 +2580,21 @@ qlcmf([E0 | Es0], F, Imp, A0, No0) ->
{E, A1, No1} = qlcmf(E0, F, Imp, A0, No0),
{Es, A, No} = qlcmf(Es0, F, Imp, A1, No1),
{[E | Es], A, No};
-qlcmf(?QLC_Q(L1, L2, L3, L4, LC0, Os0), F, Imp, A0, No0) when length(Os0) < 2 ->
+qlcmf(?QLC_Q(Anno1, Anno2, Anno3, Anno4, LC0, Os0), F, Imp, A0, No0)
+ when length(Os0) < 2 ->
{Os, A1, No1} = qlcmf(Os0, F, Imp, A0, No0),
{LC, A2, No} = qlcmf(LC0, F, Imp, A1, No1), % nested...
- NL = make_lcid(L1, No),
+ NL = make_lcid(Anno1, No),
{T, A} = F(NL, LC, A2),
- {?QLC_Q(L1, L2, L3, L4, T, Os), A, No + 1};
-qlcmf(?IMP_Q(L1, L2, LC0, Os0), F, Imp=true, A0, No0) when length(Os0) < 2 ->
+ {?QLC_Q(Anno1, Anno2, Anno3, Anno4, T, Os), A, No + 1};
+qlcmf(?IMP_Q(Anno1, Anno2, LC0, Os0), F, Imp=true, A0, No0)
+ when length(Os0) < 2 ->
{Os, A1, No1} = qlcmf(Os0, F, Imp, A0, No0),
{LC, A2, No} = qlcmf(LC0, F, Imp, A1, No1), % nested...
- NL = make_lcid(L, No),
+ NL = make_lcid(Anno, No),
{T, A} = F(NL, LC, A2),
- {?IMP_Q(L1, L2, T, Os), A, No + 1};
-qlcmf({attribute,_L,file,{File,_Line}}=Attr, _F, _Imp, A, No) ->
+ {?IMP_Q(Anno1, Anno2, T, Os), A, No + 1};
+qlcmf({attribute,_Anno,file,{File,_Line}}=Attr, _F, _Imp, A, No) ->
put(?QLC_FILE, File),
{Attr, A, No};
qlcmf(T, F, Imp, A0, No0) when is_tuple(T) ->
@@ -2598,7 +2604,7 @@ qlcmf(T, _F, _Imp, A, No) ->
{T, A, No}.
occ_vars(E) ->
- qlc:var_fold(fun({var,_L,V}) -> V end, [], E).
+ qlc:var_fold(fun({var,_A,V}) -> V end, [], E).
%% Every Anno is replaced by a unique number. The number is used in a
%% table that holds data about the abstract node where Anno resides.
@@ -2607,7 +2613,7 @@ occ_vars(E) ->
save_anno(Abstr, NodeInfo) ->
F = fun(Anno) ->
N = next_slot(NodeInfo),
- Location = erl_anno:location(Anno),
+ Location = loc(Anno),
Data = {N, #{location => Location}},
true = ets:insert(NodeInfo, Data),
erl_anno:new(N)
@@ -2625,7 +2631,7 @@ next_slot(T) ->
restore_anno(Abstr, NodeInfo) ->
F = fun(Anno) ->
- Location = erl_anno:location(Anno),
+ Location = loc(Anno),
case ets:lookup(NodeInfo, Location) of
[{Location, Data}] ->
OrigLocation = maps:get(location, Data),
@@ -2690,45 +2696,45 @@ nos([E0 | Es0], S0) ->
{E, S1} = nos(E0, S0),
{Es, S} = nos(Es0, S1),
{[E | Es], S};
-nos({'fun',L,{clauses,Cs}}, S) ->
+nos({'fun',Anno,{clauses,Cs}}, S) ->
NCs = [begin
{H, S1} = nos_pattern(H0, S),
{[G, B], _} = nos([G0, B0], S1),
- {clause,Ln,H,G,B}
- end || {clause,Ln,H0,G0,B0} <- Cs],
- {{'fun',L,{clauses,NCs}}, S};
-nos({named_fun,Loc,Name,Cs}, S) ->
- {{var,NLoc,NName}, S1} = case Name of
+ {clause,CAnno,H,G,B}
+ end || {clause,CAnno,H0,G0,B0} <- Cs],
+ {{'fun',Anno,{clauses,NCs}}, S};
+nos({named_fun,Anno,Name,Cs}, S) ->
+ {{var,NAnno,NName}, S1} = case Name of
'_' ->
S;
Name ->
- nos_pattern({var,Loc,Name}, S)
+ nos_pattern({var,Anno,Name}, S)
end,
NCs = [begin
{H, S2} = nos_pattern(H0, S1),
{[G, B], _} = nos([G0, B0], S2),
- {clause,CLoc,H,G,B}
- end || {clause,CLoc,H0,G0,B0} <- Cs],
- {{named_fun,NLoc,NName,NCs}, S};
-nos({lc,L,E0,Qs0}, S) ->
+ {clause,CAnno,H,G,B}
+ end || {clause,CAnno,H0,G0,B0} <- Cs],
+ {{named_fun,NAnno,NName,NCs}, S};
+nos({lc,Anno,E0,Qs0}, S) ->
%% QLCs as well as LCs. It is OK to modify LCs as long as they
%% occur within QLCs--the warning messages have already been found
%% by compile_errors.
- F = fun({T,Ln,P0,LE0}, QS0) when T =:= b_generate; T =:= generate ->
+ F = fun({T,GAnno,P0,LE0}, QS0) when T =:= b_generate; T =:= generate ->
{LE, _} = nos(LE0, QS0),
{P, QS} = nos_pattern(P0, QS0),
- {{T,Ln,P,LE}, QS};
+ {{T,GAnno,P,LE}, QS};
(Filter, QS) ->
nos(Filter, QS)
end,
{Qs, S1} = lists:mapfoldl(F, S, Qs0),
{E, _} = nos(E0, S1),
- {{lc,L,E,Qs}, S};
-nos({var,L,V}=Var, {_LI,Vs,UV,_A,_Sg,State}=S) when V =/= '_' ->
+ {{lc,Anno,E,Qs}, S};
+nos({var,Anno,V}=Var, {_LI,Vs,UV,_A,_Sg,State}=S) when V =/= '_' ->
case used_var(V, Vs, UV) of
{true, VN} ->
- nos_var(L, V, State),
- {{var,L,VN}, S};
+ nos_var(Anno, V, State),
+ {{var,Anno,VN}, S};
false ->
{Var, S}
end;
@@ -2746,7 +2752,7 @@ nos_pattern([P0 | Ps0], S0, PVs0) ->
{P, S1, PVs1} = nos_pattern(P0, S0, PVs0),
{Ps, S, PVs} = nos_pattern(Ps0, S1, PVs1),
{[P | Ps], S, PVs};
-nos_pattern({var,L,V}, {LI,Vs0,UV,A,Sg,State}, PVs0) when V =/= '_' ->
+nos_pattern({var,Anno,V}, {LI,Vs0,UV,A,Sg,State}, PVs0) when V =/= '_' ->
{Name, Vs, PVs} =
case lists:keyfind(V, 1, PVs0) of
{V, VN} ->
@@ -2760,8 +2766,8 @@ nos_pattern({var,L,V}, {LI,Vs0,UV,A,Sg,State}, PVs0) when V =/= '_' ->
end,
{N, Vs1, [{V,VN} | PVs0]}
end,
- nos_var(L, V, State),
- {{var,L,Name}, {LI,Vs,UV,A,Sg,State}, PVs};
+ nos_var(Anno, V, State),
+ {{var,Anno,Name}, {LI,Vs,UV,A,Sg,State}, PVs};
nos_pattern(T, S0, PVs0) when is_tuple(T) ->
{TL, S, PVs} = nos_pattern(tuple_to_list(T), S0, PVs0),
{list_to_tuple(TL), S, PVs};
@@ -2770,7 +2776,7 @@ nos_pattern(T, S, PVs) ->
nos_var(Anno, Name, State) ->
NodeInfo = State#state.node_info,
- Location = erl_anno:location(Anno),
+ Location = loc(Anno),
case ets:lookup(NodeInfo, Location) of
[{Location, #{name := _}}] ->
true;
@@ -2807,7 +2813,7 @@ undo_no_shadows(E, State) ->
var_map(fun(Anno) -> undo_no_shadows1(Anno, State) end, E).
undo_no_shadows1({var, Anno, _}=Var, State) ->
- Location = erl_anno:location(Anno),
+ Location = loc(Anno),
NodeInfo = State#state.node_info,
case ets:lookup(NodeInfo, Location) of
[{Location, #{name := Name}}] ->
@@ -2831,31 +2837,31 @@ get_lcid_line({_No, Line}) ->
qid(LCId, No) ->
#qid{no = No, lcid = LCId}.
-abst_vars([V | Vs], L) ->
- [abst_vars(V, L) | abst_vars(Vs, L)];
-abst_vars([], _L) ->
+abst_vars([V | Vs], Anno) ->
+ [abst_vars(V, Anno) | abst_vars(Vs, Anno)];
+abst_vars([], _Anno) ->
[];
-abst_vars(nil, L) ->
- {nil,L};
-abst_vars(V, L) ->
- {var,L,V}.
+abst_vars(nil, Anno) ->
+ {nil,Anno};
+abst_vars(V, Anno) ->
+ {var,Anno,V}.
-embed_vars(Vars, L) ->
- embed_expr({tuple,L,Vars}, L).
+embed_vars(Vars, Anno) ->
+ embed_expr({tuple,Anno,Vars}, Anno).
%% -> [Expr || _ <- []] on abstract format.
-embed_expr(Expr, L) ->
- {lc,L,Expr,[{generate,L,{var,L,'_'},{nil,L}}]}.
+embed_expr(Expr, Anno) ->
+ {lc,Anno,Expr,[{generate,Anno,{var,Anno,'_'},{nil,Anno}}]}.
%% Doesn't handle binaries very well, but don't bother for now.
var2const(E) ->
- var_map(fun({var, L, V}) -> {atom, L, V} end, E).
+ var_map(fun({var, A, V}) -> {atom, A, V} end, E).
var_map(F, {var, _, _}=V) ->
F(V);
-var_map(F, {named_fun,NLoc,NName,Cs}) ->
- {var,Loc,Name} = F({var,NLoc,NName}),
- {named_fun,Loc,Name,var_map(F, Cs)};
+var_map(F, {named_fun,NAnno,NName,Cs}) ->
+ {var,Anno,Name} = F({var,NAnno,NName}),
+ {named_fun,Anno,Name,var_map(F, Cs)};
var_map(F, T) when is_tuple(T) ->
list_to_tuple(var_map(F, tuple_to_list(T)));
var_map(F, [E | Es]) ->