Skip to content

Commit

Permalink
fixup! compiler: Add zip generators for comprehensions
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorng committed Nov 6, 2024
1 parent 5d08ee6 commit 2db0029
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 42 deletions.
29 changes: 15 additions & 14 deletions lib/compiler/src/v3_core.erl
Original file line number Diff line number Diff line change
Expand Up @@ -1974,9 +1974,12 @@ preprocess_quals(Line, [{zip,Anno,Gens}|Qs], St, Acc) ->
Zip0 = #izip{anno=LAnno,
acc_guard=AccGuard},
Zip1 = preprocess_zip_generators(Gens1, Zip0),
Zip2 = Zip1#izip{skip_pats=preprocess_skip(Zip1#izip.nomatch_total,Zip1#izip.nomatch_pats,Zip1#izip.acc_pats),
tail_pats=preprocess_tail(Zip1#izip.nomatch_total,Zip1#izip.nomatch_pats,Zip1#izip.tail_pats,[]),
nomatch_total=get_nomatch_total(Zip1#izip.nomatch_total)},
Zip2 = Zip1#izip{skip_pats=preprocess_skip(Zip1#izip.nomatch_total,
Zip1#izip.nomatch_pats,
Zip1#izip.acc_pats),
tail_pats=preprocess_tail(Zip1#izip.nomatch_total,
Zip1#izip.tail_pats),
nomatch_total=get_nomatch_total(Zip1#izip.nomatch_total)},
preprocess_quals(Line, Qs, St1, [Zip2|Acc]);
preprocess_quals(Line, [Q|Qs0], St0, Acc) ->
case is_generator(Q) of
Expand Down Expand Up @@ -2041,19 +2044,17 @@ get_nomatch_total(NomatchModes) ->

preprocess_skip(NomatchModes, NomatchPats, AccPats) ->
[case NomatchMode of
skip -> NomatchPat;
_ -> AccPat
end || {NomatchMode, NomatchPat, AccPat} <:-
skip -> NomatchPat;
_ -> AccPat
end || {NomatchMode, NomatchPat, AccPat} <:-
lists:zip3(NomatchModes, NomatchPats, AccPats)].

preprocess_tail([skip|NomatchModes], [_|NomatchPats], [TailPat|TailPats], Acc) ->
preprocess_tail(NomatchModes, NomatchPats, TailPats, [TailPat|Acc]);
preprocess_tail([_|NomatchModes], [_|NomatchPats], [#ibinary{}=A|TailPats], Acc) ->
preprocess_tail(NomatchModes, NomatchPats, TailPats, [A#ibinary{segments=[]}|Acc]);
preprocess_tail([_|NomatchModes], [_|NomatchPats], [TailPat|TailPats], Acc) ->
preprocess_tail(NomatchModes, NomatchPats, TailPats, [TailPat|Acc]);
preprocess_tail([], [], [], Acc) ->
reverse(Acc).
preprocess_tail(NomatchModes, AccPats) ->
[case {NomatchMode,AccPat} of
{skip,_} -> AccPat;
{_,#ibinary{}} -> AccPat#ibinary{segments=[]};
{_,_} -> AccPat
end || {NomatchMode, AccPat} <:- lists:zip(NomatchModes, AccPats)].

is_generator({generate,_,_,_}) -> true;
is_generator({generate_strict,_,_,_}) -> true;
Expand Down
22 changes: 11 additions & 11 deletions lib/debugger/src/dbg_ieval.erl
Original file line number Diff line number Diff line change
Expand Up @@ -1135,13 +1135,13 @@ eval_lc1(E, [], Bs, Ieval) ->

%% convert values for generator vars from abstract form to flattened lists
convert_gen_values([{generator,{Generate, Line, P, L0}}|Qs], Acc, Bs0, Ieval0)
when Generate =:= generate;
when Generate =:= generate;
Generate =:= generate_strict ->
Ieval = Ieval0#ieval{line=Line},
{value,L1,_Bs1} = expr(L0, Bs0, Ieval#ieval{top=false}),
convert_gen_values(Qs, [{Generate, Line, P, L1}|Acc], Bs0, Ieval);
convert_gen_values([{generator,{Generate, Line, P, L0}}|Qs], Acc, Bs0, Ieval0)
when Generate =:= b_generate;
when Generate =:= b_generate;
Generate =:= b_generate_strict ->
Ieval = Ieval0#ieval{line=Line},
{value,L1,_Bs1} = expr(L0, Bs0, Ieval#ieval{top=false}),
Expand Down Expand Up @@ -1174,7 +1174,7 @@ bind_all_generators(Gens, Bs0, Ieval) ->

bind_all_generators1([{Generate, Anno, P, <<_/bitstring>>=Bin}|Qs],
Acc, Bs0, Ieval, continue)
when Generate =:= b_generate;
when Generate =:= b_generate;
Generate =:= b_generate_strict ->
Mfun = match_fun(Bs0),
Efun = fun(Exp, Bs) -> expr(Exp, Bs, #ieval{}) end,
Expand All @@ -1200,7 +1200,7 @@ bind_all_generators1([{Generate, Anno, P, <<_/bitstring>>=Bin}|Qs],
{[], done}
end;
bind_all_generators1([{Generate, Anno, P, <<_/bitstring>>=Bin}|Qs], Acc, Bs0, Ieval, skip)
when Generate =:= b_generate;
when Generate =:= b_generate;
Generate =:= b_generate_strict ->
Mfun = match_fun(Bs0),
Efun = fun(Exp, Bs) -> expr(Exp, Bs, #ieval{}) end,
Expand All @@ -1217,7 +1217,7 @@ bind_all_generators1([{Generate, Anno, P, <<_/bitstring>>=Bin}|Qs], Acc, Bs0, Ie
{[], skip}
end;
bind_all_generators1([{Generate, Anno, P, [H|T]}|Qs], Acc, Bs0, Ieval, continue)
when Generate =:= generate;
when Generate =:= generate;
Generate =:= generate_strict ->
case catch match1(P, H, erl_eval:new_bindings(Bs0), Bs0) of
{match,Bsn} ->
Expand Down Expand Up @@ -1250,7 +1250,7 @@ bind_all_generators1([{generate_strict, Anno, P, [H|T]}|Qs], Acc, Bs0, Ieval, co
{Acc, error}
end;
bind_all_generators1([{Generate, Anno, P, Iter0}|Qs], Acc, Bs0, Ieval, continue)
when Generate =:= m_generate;
when Generate =:= m_generate;
Generate =:= m_generate_strict ->
case maps:next(Iter0) of
{K,V,Iter} ->
Expand Down Expand Up @@ -1297,7 +1297,7 @@ bind_all_generators1([{m_generate_strict, Anno, P, Iter0}|Qs], Acc, Bs0, Ieval,
bind_all_generators1(Qs,[{m_generate_strict, Anno, P, Iter}|Acc],
Bs2, Ieval, continue)
end;
nomatch -> {Acc, error}
nomatch -> {Acc, error}
end;
none ->
{[], done}
Expand All @@ -1309,7 +1309,7 @@ bind_all_generators1([{generate_strict,_,_,[]}|_], _, _, _, _) ->
%% no more values left for a var, time to return
{[],done};
bind_all_generators1([{Generate, _Anno, _P, _Term}|_Qs], Acc, _Bs0, _Ieval,_)
when Generate =:= generate;
when Generate =:= generate;
Generate =:= generate_strict;
Generate =:= b_generate;
Generate =:= b_generate_strict ->
Expand All @@ -1321,18 +1321,18 @@ bind_all_generators1([], [_H|_T] = Acc, _Bs0, _Ieval, skip) ->
{Acc, skip}.

check_bad_generators([{Generate,_,_,V}|T], Env, Acc)
when Generate =:= generate;
when Generate =:= generate;
Generate =:= generate_strict ->
check_bad_generators(T, Env, [V|Acc]);
check_bad_generators([{Generate,_,_,Iter0}|T], Env, Acc)
when Generate =:= m_generate;
when Generate =:= m_generate;
Generate =:= m_generate_strict ->
case maps:next(Iter0) of
none -> check_bad_generators(T, Env, [#{}|Acc]);
_ -> check_bad_generators(T, Env, [#{K => V || K := V <- Iter0}|Acc])
end;
check_bad_generators([{Generate,_,P,<<_/bitstring>>=Bin}|T], Bs0, Acc)
when Generate =:= b_generate;
when Generate =:= b_generate;
Generate =:= b_generate_strict ->
Mfun = match_fun(Bs0),
Efun = fun(Exp, Bs) -> expr(Exp, Bs, #ieval{}) end,
Expand Down
2 changes: 1 addition & 1 deletion lib/debugger/test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ MODULES= \
record_SUITE \
trycatch_SUITE \
test_lib \
zlc_SUITE\
zlc_SUITE \
cleanup

ERL_FILES= $(MODULES:%=%.erl)
Expand Down
5 changes: 3 additions & 2 deletions lib/stdlib/src/erl_eval.erl
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ to be called.

-export([exprs/2,exprs/3,exprs/4,expr/2,expr/3,expr/4,expr/5,
expr_list/2,expr_list/3,expr_list/4]).
-export([new_bindings/0,new_bindings/1,bindings/1,binding/2,add_binding/3,del_binding/2]).
-export([new_bindings/0,new_bindings/1,bindings/1,binding/2,
add_binding/3,del_binding/2]).
-export([extended_parse_exprs/1, extended_parse_term/1]).
-export([is_constant_expr/1, partial_eval/1, eval_str/1]).

Expand Down Expand Up @@ -1139,7 +1140,7 @@ bind_all_generators1([{m_generate, Anno, P, Iter0}|Qs], Acc, Bs0, Lf, Ef, FUVs,
case maps:next(Iter0) of
{_K,_V,Iter} ->
bind_all_generators1(Qs, [{m_generate, Anno, P, Iter}|Acc],
Bs0, Lf, Ef, FUVs, skip);
Bs0, Lf, Ef, FUVs, skip);
none ->
{[], skip}
end;
Expand Down
2 changes: 1 addition & 1 deletion lib/syntax_tools/src/erl_syntax.erl
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ trees.
| erl_parse:form_info()
| erl_parse:af_binelement(term())
| erl_parse:af_generator()
| erl_parse:af_zip_generator()
| erl_parse:af_zip_generator()
| erl_parse:af_remote_function().

%% The representation built by the Erlang standard library parser
Expand Down
15 changes: 8 additions & 7 deletions lib/syntax_tools/src/erl_syntax_lib.erl
Original file line number Diff line number Diff line change
Expand Up @@ -648,8 +648,8 @@ vann_list_comp_body_join() ->
vann_map_generator(T,Env);
strict_map_generator ->
vann_strict_map_generator(T,Env);
zip_generator ->
vann_zip_generator(T,Env);
zip_generator ->
vann_zip_generator(T,Env);
_ ->
%% Bindings in filters are not
%% exported to the rest of the
Expand Down Expand Up @@ -694,8 +694,8 @@ vann_binary_comp_body_join() ->
vann_map_generator(T,Env);
strict_map_generator ->
vann_strict_map_generator(T,Env);
zip_generator ->
vann_zip_generator(T,Env);
zip_generator ->
vann_zip_generator(T,Env);
_ ->
%% Bindings in filters are not
%% exported to the rest of the
Expand All @@ -717,9 +717,9 @@ vann_binary_comp_body(Ts, Env) ->
vann_zip_generator_body_join() ->
fun (T, {Env, Bound, Free}) ->
{T1, Bound1, Free1} = case erl_syntax:type(T) of
binary_generator ->
vann_binary_generator(T, Env);
generator ->
binary_generator ->
vann_binary_generator(T, Env);
generator ->
vann_generator(T, Env)
end,
Env1 = ordsets:union(Env, Bound1),
Expand Down Expand Up @@ -785,6 +785,7 @@ vann_strict_map_generator(Tree, Env) ->
{E1, _, Free} = vann(E, Env),
Tree1 = rewrite(Tree, erl_syntax:strict_map_generator(P1, E1)),
{ann_bindings(Tree1, Env, Bound, Free), Bound, Free}.

vann_zip_generator(Tree, Env) ->
Es = erl_syntax:zip_generator_body(Tree),
{Es1, {Bound, Free}} = vann_zip_generator_body(Es, Env),
Expand Down
10 changes: 5 additions & 5 deletions lib/syntax_tools/test/syntax_tools_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -340,11 +340,11 @@ t_erl_parse_type(Config) when is_list(Config) ->
{"#{K => V || {K,V} <- KVs}", map_comp,false},
{"#{K => V || {K,V} <:- KVs}", map_comp,false},
{"#{K => (catch V) || {K,V} <- KVs}", map_comp,false},
{"[V+W||V <- Vs && W <- Ws]", list_comp,false},
{"[catch V+W||V <- Vs && W <- Ws]", list_comp,false},
{"<< <<B>> || <<B>> <= Bs>>", binary_comp,false},
{"<< (catch <<B>>) || <<B>> <= Bs>>", binary_comp,false},
{"<< <<B:8,C:8>> || <<B>> <= Bs && <<C>> <= Cs>>", binary_comp,false},
{"[V+W||V <- Vs && W <- Ws]", list_comp,false},
{"[catch V+W||V <- Vs && W <- Ws]", list_comp,false},
{"<< <<B>> || <<B>> <= Bs>>", binary_comp,false},
{"<< (catch <<B>>) || <<B>> <= Bs>>", binary_comp,false},
{"<< <<B:8,C:8>> || <<B>> <= Bs && <<C>> <= Cs>>", binary_comp,false},
{"<< (catch <<B:8,C:8>>) || <<B>> <= Bs && <<C>> <= Cs>>", binary_comp,false},
{"#state{ a = A, b = B}", record_expr,false},
{"#state{}", record_expr,false},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -604,4 +604,4 @@ eep73() ->
[{X,Y}||X <- [1,2,3] && Y <- [2,2,2]],
[{X,Y}||X <- [1,2,3] && <<Y>> <= <<2,2,2>>],
[{K1,K2,V1,V2}|| K1 := V1 <- #{a=>1} && K2 := V2 <- #{b=>3}],
ok.
ok.

0 comments on commit 2db0029

Please sign in to comment.