From 2db0029552f2b3619355cb23fa2047eaa8975eb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Wed, 6 Nov 2024 06:11:23 +0100 Subject: [PATCH] fixup! compiler: Add zip generators for comprehensions --- lib/compiler/src/v3_core.erl | 29 ++++++++++--------- lib/debugger/src/dbg_ieval.erl | 22 +++++++------- lib/debugger/test/Makefile | 2 +- lib/stdlib/src/erl_eval.erl | 5 ++-- lib/syntax_tools/src/erl_syntax.erl | 2 +- lib/syntax_tools/src/erl_syntax_lib.erl | 15 +++++----- lib/syntax_tools/test/syntax_tools_SUITE.erl | 10 +++---- .../syntax_tools_SUITE_test_module.erl | 2 +- 8 files changed, 45 insertions(+), 42 deletions(-) diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl index 586a20324fad..a0ae53bb50d6 100644 --- a/lib/compiler/src/v3_core.erl +++ b/lib/compiler/src/v3_core.erl @@ -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 @@ -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; diff --git a/lib/debugger/src/dbg_ieval.erl b/lib/debugger/src/dbg_ieval.erl index 8cc8700b989c..3681edcc66d9 100644 --- a/lib/debugger/src/dbg_ieval.erl +++ b/lib/debugger/src/dbg_ieval.erl @@ -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}), @@ -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, @@ -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, @@ -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} -> @@ -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} -> @@ -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} @@ -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 -> @@ -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, diff --git a/lib/debugger/test/Makefile b/lib/debugger/test/Makefile index 2e68d2971678..4ecb3652ed36 100644 --- a/lib/debugger/test/Makefile +++ b/lib/debugger/test/Makefile @@ -53,7 +53,7 @@ MODULES= \ record_SUITE \ trycatch_SUITE \ test_lib \ - zlc_SUITE\ + zlc_SUITE \ cleanup ERL_FILES= $(MODULES:%=%.erl) diff --git a/lib/stdlib/src/erl_eval.erl b/lib/stdlib/src/erl_eval.erl index 54f144f427d1..9e362190ef08 100644 --- a/lib/stdlib/src/erl_eval.erl +++ b/lib/stdlib/src/erl_eval.erl @@ -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]). @@ -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; diff --git a/lib/syntax_tools/src/erl_syntax.erl b/lib/syntax_tools/src/erl_syntax.erl index 529f899f9df6..e1ec49ab82b2 100644 --- a/lib/syntax_tools/src/erl_syntax.erl +++ b/lib/syntax_tools/src/erl_syntax.erl @@ -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 diff --git a/lib/syntax_tools/src/erl_syntax_lib.erl b/lib/syntax_tools/src/erl_syntax_lib.erl index bd34708c9f64..ea0e67ec7aba 100644 --- a/lib/syntax_tools/src/erl_syntax_lib.erl +++ b/lib/syntax_tools/src/erl_syntax_lib.erl @@ -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 @@ -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 @@ -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), @@ -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), diff --git a/lib/syntax_tools/test/syntax_tools_SUITE.erl b/lib/syntax_tools/test/syntax_tools_SUITE.erl index 0ee08aefea58..0ddbbb2ebde6 100644 --- a/lib/syntax_tools/test/syntax_tools_SUITE.erl +++ b/lib/syntax_tools/test/syntax_tools_SUITE.erl @@ -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}, - {"<< <> || <> <= Bs>>", binary_comp,false}, - {"<< (catch <>) || <> <= Bs>>", binary_comp,false}, - {"<< <> || <> <= Bs && <> <= Cs>>", binary_comp,false}, + {"[V+W||V <- Vs && W <- Ws]", list_comp,false}, + {"[catch V+W||V <- Vs && W <- Ws]", list_comp,false}, + {"<< <> || <> <= Bs>>", binary_comp,false}, + {"<< (catch <>) || <> <= Bs>>", binary_comp,false}, + {"<< <> || <> <= Bs && <> <= Cs>>", binary_comp,false}, {"<< (catch <>) || <> <= Bs && <> <= Cs>>", binary_comp,false}, {"#state{ a = A, b = B}", record_expr,false}, {"#state{}", record_expr,false}, diff --git a/lib/syntax_tools/test/syntax_tools_SUITE_data/syntax_tools_SUITE_test_module.erl b/lib/syntax_tools/test/syntax_tools_SUITE_data/syntax_tools_SUITE_test_module.erl index 9c2b6c4a823f..ddf06a7597bc 100644 --- a/lib/syntax_tools/test/syntax_tools_SUITE_data/syntax_tools_SUITE_test_module.erl +++ b/lib/syntax_tools/test/syntax_tools_SUITE_data/syntax_tools_SUITE_test_module.erl @@ -604,4 +604,4 @@ eep73() -> [{X,Y}||X <- [1,2,3] && Y <- [2,2,2]], [{X,Y}||X <- [1,2,3] && <> <= <<2,2,2>>], [{K1,K2,V1,V2}|| K1 := V1 <- #{a=>1} && K2 := V2 <- #{b=>3}], - ok. \ No newline at end of file + ok.