Skip to content

Commit 1531a18

Browse files
committed
[EEP 78] Implement multi comprehensions in compiler
1 parent dfe64f8 commit 1531a18

File tree

4 files changed

+51
-24
lines changed

4 files changed

+51
-24
lines changed

lib/compiler/src/v3_core.erl

+26-18
Original file line numberDiff line numberDiff line change
@@ -710,12 +710,12 @@ expr({cons,L,H0,T0}, St0) ->
710710
{annotate_cons(A, H1, T1, St1),Eps,St1};
711711
expr({lc,L,E,Qs0}, St0) ->
712712
{Qs1,St1} = preprocess_quals(L, Qs0, St0),
713-
lc_tq(L, E, Qs1, #c_literal{anno=lineno_anno(L, St1),val=[]}, St1);
713+
lc_tq(L, wrap_list(E), Qs1, #c_literal{anno=lineno_anno(L, St1),val=[]}, St1);
714714
expr({bc,L,E,Qs}, St) ->
715715
bc_tq(L, E, Qs, St);
716716
expr({mc,L,E,Qs0}, St0) ->
717717
{Qs1,St1} = preprocess_quals(L, Qs0, St0),
718-
mc_tq(L, E, Qs1, #c_literal{anno=lineno_anno(L, St1),val=[]}, St1);
718+
mc_tq(L, wrap_list(E), Qs1, #c_literal{anno=lineno_anno(L, St1),val=[]}, St1);
719719
expr({tuple,L,Es0}, St0) ->
720720
{Es1,Eps,St1} = safe_list(Es0, St0),
721721
A = record_anno(L, St1),
@@ -967,7 +967,7 @@ expr({op,_,'++',{lc,Llc,E,Qs0},More}, St0) ->
967967
%% number variables in the environment for letrec.
968968
{Mc,Mps,St1} = safe(More, St0),
969969
{Qs,St2} = preprocess_quals(Llc, Qs0, St1),
970-
{Y,Yps,St} = lc_tq(Llc, E, Qs, Mc, St2),
970+
{Y,Yps,St} = lc_tq(Llc, wrap_list(E), Qs, Mc, St2),
971971
{Y,Mps++Yps,St};
972972
expr({op,_,'andalso',_,_}=E0, St0) ->
973973
{op,L,'andalso',E1,E2} = right_assoc(E0, 'andalso'),
@@ -1623,21 +1623,29 @@ fun_tq(Cs0, L, St0, NameInfo) ->
16231623
vars=Args,clauses=Cs1,fc=Fc,name=NameInfo},
16241624
{Fun,[],St4}.
16251625

1626-
%% lc_tq(Line, Exp, [Qualifier], Mc, State) -> {LetRec,[PreExp],State}.
1626+
wrap_list(List) when is_list(List) -> List;
1627+
wrap_list(Other) -> [Other].
1628+
1629+
%% lc_tq(Line, Exprs, [Qualifier], Mc, State) -> {LetRec,[PreExp],State}.
16271630
%% This TQ from Simon PJ pp 127-138.
16281631

1629-
lc_tq(Line, E, [#igen{}|_T] = Qs, Mc, St) ->
1630-
lc_tq1(Line, E, Qs, Mc, St);
1631-
lc_tq(Line, E, [#izip{}=Zip|Qs], Mc, St) ->
1632-
zip_tq(Line, E, Zip, Mc, St, Qs);
1633-
lc_tq(Line, E, [#ifilter{}=Filter|Qs], Mc, St) ->
1634-
filter_tq(Line, E, Filter, Mc, St, Qs, fun lc_tq/5);
1635-
lc_tq(Line, E0, [], Mc0, St0) ->
1636-
{H1,Hps,St1} = safe(E0, St0),
1632+
lc_tq(Line, Es, [#igen{}|_T] = Qs, Mc, St) ->
1633+
lc_tq1(Line, Es, Qs, Mc, St);
1634+
lc_tq(Line, Es, [#izip{}=Zip|Qs], Mc, St) ->
1635+
zip_tq(Line, Es, Zip, Mc, St, Qs);
1636+
lc_tq(Line, Es, [#ifilter{}=Filter|Qs], Mc, St) ->
1637+
filter_tq(Line, Es, Filter, Mc, St, Qs, fun lc_tq/5);
1638+
lc_tq(Line, Es0, [], Mc0, St0) ->
1639+
{Hs1,Hps,St1} = safe_list(Es0, St0),
16371640
{T1,Tps,St} = force_safe(Mc0, St1),
1638-
Anno = lineno_anno(Line, St),
1639-
E = ann_c_cons(Anno, H1, T1),
1640-
{set_anno(E, [compiler_generated|Anno]),Hps ++ Tps,St}.
1641+
Anno = lineno_anno(erl_anno:set_generated(true, Line), St),
1642+
E = ann_c_cons_all(Anno, Hs1, T1),
1643+
{E,Hps ++ Tps,St}.
1644+
1645+
ann_c_cons_all(Anno, [H | Hs], T) ->
1646+
ann_c_cons(Anno, H, ann_c_cons_all(Anno, Hs, T));
1647+
ann_c_cons_all(_Anno, [], T) ->
1648+
T.
16411649

16421650
lc_tq1(Line, E, [#igen{anno=#a{anno=GA}=GAnno,
16431651
acc_pat=AccPat,acc_guard=AccGuard,
@@ -1924,9 +1932,9 @@ bzip_tq1(Line, E, #izip{anno=#a{anno=_GA}=GAnno,
19241932
body=append(Pres) ++
19251933
[#iapply{anno=LAnno,op=F,args=Args++[Mc]}]},[],St4}.
19261934

1927-
mc_tq(Line, {map_field_assoc,Lf,K,V}, Qs, Mc, St0) ->
1928-
E = {tuple,Lf,[K,V]},
1929-
{Lc,Pre0,St1} = lc_tq(Line, E, Qs, Mc, St0),
1935+
mc_tq(Line, Es0, Qs, Mc, St0) ->
1936+
Es = map(fun({map_field_assoc,Lf,K,V}) -> {tuple,Lf,[K,V]} end, Es0),
1937+
{Lc,Pre0,St1} = lc_tq(Line, Es, Qs, Mc, St0),
19301938
{LcVar,St2} = new_var(St1),
19311939
Pre = Pre0 ++ [#iset{var=LcVar,arg=Lc}],
19321940
Call = #icall{module=#c_literal{val=maps},

lib/compiler/test/lc_SUITE.erl

+7-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
init_per_testcase/2,end_per_testcase/2,
2525
basic/1,deeply_nested/1,no_generator/1,
2626
empty_generator/1,no_export/1,shadow/1,
27-
effect/1]).
27+
effect/1,multi/1]).
2828

2929
-include_lib("common_test/include/ct.hrl").
3030

@@ -43,7 +43,8 @@ groups() ->
4343
empty_generator,
4444
no_export,
4545
shadow,
46-
effect
46+
effect,
47+
multi
4748
]}].
4849

4950
init_per_suite(Config) ->
@@ -284,6 +285,10 @@ do_effect(Lc, L) ->
284285
ok = Lc(F, L),
285286
lists:reverse(erase(?MODULE)).
286287

288+
multi(Config) when is_list(Config) ->
289+
[true, false] = [true, false || true],
290+
[1, 2, 5, 6] = [X, X + 1 || X <- [1, 5]].
291+
287292
id(I) -> I.
288293

289294
-file("bad_lc.erl", 1).

lib/compiler/test/mc_SUITE.erl

+11-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
-export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1,
2626
init_per_group/2,end_per_group/2,
2727
basic/1,duplicate_keys/1,mixed/1,
28-
shadow/1,bad_generators/1]).
28+
shadow/1,bad_generators/1,multi/1]).
2929

3030
-include_lib("common_test/include/ct.hrl").
3131

@@ -40,7 +40,8 @@ groups() ->
4040
duplicate_keys,
4141
mixed,
4242
shadow,
43-
bad_generators]}].
43+
bad_generators,
44+
multi]}].
4445

4546
init_per_suite(Config) ->
4647
test_lib:recompile(?MODULE),
@@ -298,6 +299,14 @@ bad_generators(_Config) ->
298299
end,
299300
ok.
300301

302+
multi(_Config) ->
303+
Exp = #{true => 1, false => 2},
304+
Exp = #{true => 1, false => 2 || true},
305+
Exp2 = #{1 => 1, 2 => 2, 5 => 5, 6 => 6},
306+
Exp2 = #{X => X, X + 1 => X + 1 || X <- [1, 5]},
307+
Exp3 = #{1 => 4, 5 => 8},
308+
Exp3 = #{X => X+1, X => X+3 || X <- [1, 5]}.
309+
301310
id(I) -> I.
302311

303312
-file("bad_mc.erl", 1).

lib/stdlib/src/erl_expand_records.erl

+7-2
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,11 @@ record_test_in_body(Anno, Expr, Name, St0) ->
276276
{atom,NAnno,is_record}},
277277
[Var,{atom,Anno,Name},{integer,Anno,length(Fs)+1}]}]}, St).
278278

279+
expr_or_exprs(Es, St) when is_list(Es) ->
280+
exprs(Es, St);
281+
expr_or_exprs(E, St) ->
282+
expr(E, St).
283+
279284
exprs([E0 | Es0], St0) ->
280285
{E,St1} = expr(E0, St0),
281286
{Es,St2} = exprs(Es0, St1),
@@ -302,15 +307,15 @@ expr({cons,Anno,H0,T0}, St0) ->
302307
{{cons,Anno,H,T},St2};
303308
expr({lc,Anno,E0,Qs0}, St0) ->
304309
{Qs1,St1} = lc_tq(Anno, Qs0, St0),
305-
{E1,St2} = expr(E0, St1),
310+
{E1,St2} = expr_or_exprs(E0, St1),
306311
{{lc,Anno,E1,Qs1},St2};
307312
expr({bc,Anno,E0,Qs0}, St0) ->
308313
{Qs1,St1} = lc_tq(Anno, Qs0, St0),
309314
{E1,St2} = expr(E0, St1),
310315
{{bc,Anno,E1,Qs1},St2};
311316
expr({mc,Anno,E0,Qs0}, St0) ->
312317
{Qs1,St1} = lc_tq(Anno, Qs0, St0),
313-
{E1,St2} = expr(E0, St1),
318+
{E1,St2} = expr_or_exprs(E0, St1),
314319
{{mc,Anno,E1,Qs1},St2};
315320
expr({tuple,Anno,Es0}, St0) ->
316321
{Es1,St1} = expr_list(Es0, St0),

0 commit comments

Comments
 (0)