From 9a0a5e28ac9fea2111fb840f6f98d2fb0d8760ac Mon Sep 17 00:00:00 2001 From: lucioleKi Date: Mon, 4 Nov 2024 14:10:11 +0100 Subject: [PATCH] debugger done --- lib/debugger/src/dbg_ieval.erl | 87 +++++++++++++++++++++++++++------ lib/debugger/src/dbg_iload.erl | 8 ++- lib/debugger/test/zlc_SUITE.erl | 14 +++--- lib/stdlib/src/erl_eval.erl | 12 ++--- 4 files changed, 90 insertions(+), 31 deletions(-) diff --git a/lib/debugger/src/dbg_ieval.erl b/lib/debugger/src/dbg_ieval.erl index ea8ab44d143d..3d9772fe10b5 100644 --- a/lib/debugger/src/dbg_ieval.erl +++ b/lib/debugger/src/dbg_ieval.erl @@ -1176,62 +1176,96 @@ bind_all_generators1([{Generate, Anno, P, <<_/bitstring>>=Bin}|Qs], {match, Rest, Bs1} -> Bs2 = zip_add_bindings(Bs1, Bs0), case Bs2 of - nomatch -> + nomatch when Generate =:= b_generate -> bind_all_generators1(Qs, [{b_generate, Anno, P, Rest}|Acc], Bs0, Ieval, skip); + nomatch -> {Acc, error}; _ -> bind_all_generators1(Qs, [{b_generate, Anno, P, Rest}|Acc], Bs2, Ieval, continue) end; - {nomatch, Rest} -> + {nomatch, Rest} when Generate =:= b_generate -> bind_all_generators1(Qs, [{b_generate, Anno, P, Rest}|Acc], Bs0, Ieval, skip); + {nomatch, _Rest} -> + {Acc, error}; + done when Generate =:= b_generate_strict, Bin =/= <<>> -> + {Acc, error}; done -> {[], done} end; -bind_all_generators1([{b_generate, Anno, P, <<_/bitstring>>=Bin}|Qs], Acc, Bs0, Ieval, skip) -> +bind_all_generators1([{Generate, Anno, P, <<_/bitstring>>=Bin}|Qs], Acc, Bs0, Ieval, skip) + when Generate =:= b_generate; + Generate =:= b_generate_strict -> Mfun = match_fun(Bs0), Efun = fun(Exp, Bs) -> expr(Exp, Bs, #ieval{}) end, case eval_bits:bin_gen(P, Bin, erl_eval:new_bindings(Bs0), Bs0, Mfun, Efun) of {match, Rest, _} -> bind_all_generators1(Qs, [{b_generate, Anno, P, Rest}|Acc], Bs0, Ieval, skip); - {nomatch, Rest} -> + {nomatch, Rest} when Generate =:= b_generate -> bind_all_generators1(Qs, [{b_generate, Anno, P, Rest}|Acc], Bs0, Ieval, skip); + {nomatch, _Rest} -> + {Acc, error}; + done when Generate =:= b_generate_strict, Bin =/= <<>> -> + {Acc, error}; done -> {[], skip} end; -bind_all_generators1([{generate, Anno, P, [H|T]}|Qs], Acc, Bs0, Ieval, continue) -> +bind_all_generators1([{Generate, Anno, P, [H|T]}|Qs], Acc, Bs0, Ieval, continue) + when Generate =:= generate; + Generate =:= generate_strict -> case catch match1(P, H, erl_eval:new_bindings(Bs0), Bs0) of {match,Bsn} -> Bs2 = zip_add_bindings(Bsn, Bs0), case Bs2 of - nomatch -> + nomatch when Generate =:= generate -> bind_all_generators1(Qs,[{generate, Anno, P, T}|Acc], Bs0, Ieval, skip); + nomatch -> {Acc, error}; _ -> bind_all_generators1(Qs,[{generate, Anno, P, T}|Acc], Bs2, Ieval, continue) end; - nomatch -> + nomatch when Generate =:= generate -> %% match/6 returns nomatch. Skip this value - bind_all_generators1(Qs,[{generate, Anno, P, T}|Acc], Bs0, Ieval, skip) + bind_all_generators1(Qs,[{generate, Anno, P, T}|Acc], Bs0, Ieval, skip); + nomatch -> + {Acc, error} end; bind_all_generators1([{generate, Anno, P, [_H|T]}|Qs], Acc, Bs0, Ieval, skip) -> bind_all_generators1(Qs,[{generate, Anno, P, T}|Acc], Bs0, Ieval, skip); -bind_all_generators1([{m_generate, Anno, P, Iter0}|Qs], Acc, Bs0, Ieval, continue) -> +bind_all_generators1([{generate_strict, Anno, P, [H|T]}|Qs], Acc, Bs0, Ieval, continue) -> + case catch match1(P, H, erl_eval:new_bindings(Bs0), Bs0) of + {match,Bsn} -> + Bs2 = zip_add_bindings(Bsn, Bs0), + case Bs2 of + nomatch -> {Acc, error}; + _ -> + bind_all_generators1(Qs,[{generate, Anno, P, T}|Acc], Bs2, Ieval, continue) + end; + nomatch -> + {Acc, error} + end; +bind_all_generators1([{Generate, Anno, P, Iter0}|Qs], Acc, Bs0, Ieval, continue) + when Generate =:= m_generate; + Generate =:= m_generate_strict -> case maps:next(Iter0) of {K,V,Iter} -> case catch match1(P, {K,V}, erl_eval:new_bindings(Bs0), Bs0) of {match,Bsn} -> Bs2 = zip_add_bindings(Bsn, Bs0), case Bs2 of - nomatch -> + nomatch when Generate =:= m_generate -> bind_all_generators1(Qs,[{m_generate, Anno, P, Iter}|Acc], Bs0, Ieval, skip); + nomatch -> + {Acc, error}; _ -> bind_all_generators1(Qs,[{m_generate, Anno, P, Iter}|Acc], Bs2, Ieval, continue) end; - nomatch -> + nomatch when Generate =:= m_generate -> bind_all_generators1(Qs, [{m_generate, Anno, P, Iter}|Acc], - Bs0, Ieval, skip) + Bs0, Ieval, skip); + nomatch -> + {Acc, error} end; none -> {[], done} @@ -1244,12 +1278,35 @@ bind_all_generators1([{m_generate, Anno, P, Iter0}|Qs], Acc, Bs0, Ieval, skip) - none -> {[], skip} end; +bind_all_generators1([{m_generate_strict, Anno, P, Iter0}|Qs], Acc, Bs0, Ieval, continue) -> + case maps:next(Iter0) of + {K,V,Iter} -> + case catch match1(P, {K,V}, erl_eval:new_bindings(Bs0), Bs0) of + {match,Bsn} -> + Bs2 = zip_add_bindings(Bsn, Bs0), + case Bs2 of + nomatch -> + {Acc, error}; + _ -> + bind_all_generators1(Qs,[{m_generate, Anno, P, Iter}|Acc], + Bs2, Ieval, continue) + end; + nomatch -> {Acc, error} + end; + none -> + {[], done} + end; bind_all_generators1([{generate,_,_,[]}|_], _, _, _, _) -> %% no more values left for a var, time to return {[],done}; -bind_all_generators1([{b_generate, _Anno, _P, _Term}|_Qs], Acc, _Bs0, _Ieval,_) -> - {Acc, error}; -bind_all_generators1([{generate, _Anno, _P, _Term}|_Qs], Acc, _Bs0, _Ieval,_) -> +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; + Generate =:= generate_strict; + Generate =:= b_generate; + Generate =:= b_generate_strict -> {Acc, error}; bind_all_generators1([], [_H|_T] = Acc, Bs0, _Ieval, continue) -> %% all vars are bind for this round diff --git a/lib/debugger/src/dbg_iload.erl b/lib/debugger/src/dbg_iload.erl index f5969b203117..accb744bf78c 100644 --- a/lib/debugger/src/dbg_iload.erl +++ b/lib/debugger/src/dbg_iload.erl @@ -717,10 +717,16 @@ expr_comprehension({zip,Anno,Gens}, St) -> Gs = [case G of ({generate,L,P0,Qs}) -> {generator,{generate,L,pattern(P0, St),expr(Qs, false, St)}}; + ({generate_strict,L,P0,Qs}) -> + {generator,{generate_strict,L,pattern(P0, St),expr(Qs, false, St)}}; ({b_generate,L,P0,Qs}) -> %R12. {generator,{b_generate,L,pattern(P0, St),expr(Qs, false, St)}}; + ({b_generate_strict,L,P0,Qs}) -> %R12. + {generator,{b_generate_strict,L,pattern(P0, St),expr(Qs, false, St)}}; ({m_generate,L,P0,Qs}) -> %OTP 26 - {generator,{m_generate,L,mc_pattern(P0, St),expr(Qs, false, St)}} + {generator,{m_generate,L,mc_pattern(P0, St),expr(Qs, false, St)}}; + ({m_generate_strict,L,P0,Qs}) -> %OTP 26 + {generator,{m_generate_strict,L,mc_pattern(P0, St),expr(Qs, false, St)}} end || G <- Gens], {zip,ln(Anno),Gs}. diff --git a/lib/debugger/test/zlc_SUITE.erl b/lib/debugger/test/zlc_SUITE.erl index c799e4721da8..a34b7ad6e6d2 100644 --- a/lib/debugger/test/zlc_SUITE.erl +++ b/lib/debugger/test/zlc_SUITE.erl @@ -206,7 +206,7 @@ strict_list(Config) when is_list(Config) -> [] = strict_list_mixed_1([], []), [11,22] = strict_list_mixed_1([{i,1},{i,2}], [{i,10},{i,20}]), [13,25] = strict_list_mixed_1([{i,3},{i,4},{i,5}], [{i,10},bad,{i,20}]), - {'EXIT',{{badmatches,{bad,{i,15}}},_}} = + {'EXIT',{{bad_generators,{[bad,{i,5}],[{i,15},{i,20}]}},_}} = catch strict_list_mixed_1([{i,3},bad,{i,5}], [{i,10},{i,15},{i,20}]), {'EXIT',{{bad_generators,{[{i,5}],[]}},_}} = catch strict_list_mixed_1([{i,3},{i,5}], [bad]), @@ -219,26 +219,26 @@ strict_list(Config) when is_list(Config) -> %% How should a bad match of map generator be presented? %% Maybe like this: {badmatches,{{a,3},{{k,1},{v,2}}}} - {'EXIT',{{badmatches,{{a,3},{k,1},{v,2}}},_}} = + {'EXIT',{{bad_generators,{[{a,3}],{{k,1},{v,2},none}}},_}} = catch strict_list_mixed_2([{a,3}], SimpleMap), - {'EXIT',{{bad_generators,{[],SimpleMap}},_}} = + {'EXIT',{{bad_generators,{[],{{k,1},{v,2},none}}},_}} = catch strict_list_mixed_2([], SimpleMap), [] = strict_list_strict_1([], []), [11,22] = strict_list_strict_1([{i,1},{i,2}], [{i,10},{i,20}]), - {'EXIT',{{badmatches,{bad,{i,15}}},_}} = + {'EXIT',{{bad_generators,{[bad,{i,5}],[{i,15},{i,20}]}},_}} = catch strict_list_strict_1([{i,3},bad,{i,5}], [{i,10},{i,15},{i,20}]), - {'EXIT',{{badmatches,{{i,4},{wrong_tag,7}}},_}} = + {'EXIT',{{bad_generators,{[{i,4},{i,5}],[{wrong_tag,7},{i,20}]}},_}} = catch strict_list_strict_1([{i,3},{i,4},{i,5}], [{i,10},{wrong_tag,7},{i,20}]), - {'EXIT',{{badmatches,{{a,b,c},{wrong_tag,7}}},_}} = + {'EXIT',{{bad_generators,{[{a,b,c},{i,5}],[{wrong_tag,7},{i,20}]}},_}} = catch strict_list_strict_1([{i,3},{a,b,c},{i,5}], [{i,10},{wrong_tag,7},{i,20}]), {'EXIT',{{bad_generators,{[{i,5}],[]}},_}} = catch strict_list_strict_1([{i,3},{i,5}], [{i,7}]), [] = strict_list_strict_2([], [], <<>>), [5,23] = strict_list_strict_2([{i,1},{i,2}], [{i,2},{i,7}], <<3,9>>), - {'EXIT',{{badmatches,{{i,2},{i,7},<<9:7>>}},_}} = + {'EXIT',{{bad_generators,{[{i,2}],[{i,7}],<<9:7>>}},_}} = catch strict_list_strict_2([{i,1},{i,2}], [{i,2},{i,7}], <<3,9:7>>), {'EXIT',{{bad_generators,{[],[],[]}},_}} = catch strict_list_strict_2([], [], []), {'EXIT',{{bad_generators,{[{i,0}],[],<<>>}},_}} = diff --git a/lib/stdlib/src/erl_eval.erl b/lib/stdlib/src/erl_eval.erl index e7fffc6111e7..e12813c4f664 100644 --- a/lib/stdlib/src/erl_eval.erl +++ b/lib/stdlib/src/erl_eval.erl @@ -993,8 +993,7 @@ bind_all_generators1([{Generate, Anno, P, <<_/bitstring>>=Bin}|Qs], nomatch when Generate =:= b_generate -> bind_all_generators1(Qs,[{b_generate, Anno, P, Rest}|Acc], Bs0, Lf, Ef, FUVs, skip); - nomatch -> - {Acc, error}; + nomatch -> {Acc, error}; _ -> bind_all_generators1(Qs,[{b_generate, Anno, P, Rest}|Acc], Bs2, Lf, Ef, FUVs, continue) @@ -1040,8 +1039,7 @@ bind_all_generators1([{Generate, Anno, P, [H|T]}|Qs], Acc, Bs0, Lf, Ef, FUVs, co nomatch when Generate =:= generate -> bind_all_generators1(Qs,[{Generate, Anno, P, T}|Acc], Bs0, Lf, Ef, FUVs, skip); - nomatch -> - {Acc, error}; + nomatch -> {Acc, error}; _ -> bind_all_generators1(Qs,[{Generate, Anno, P, T}|Acc], Bs2, Lf, Ef, FUVs, continue) end; @@ -1078,8 +1076,7 @@ bind_all_generators1([{Generate, Anno, P, Iter0}|Qs], Acc, Bs0, Lf, Ef, FUVs, co nomatch when Generate =:= m_generate -> bind_all_generators1(Qs,[{m_generate, Anno, P, Iter}|Acc], Bs0, Lf, Ef, FUVs, skip); - nomatch -> - {Acc, error}; + nomatch -> {Acc, error}; _ -> bind_all_generators1(Qs,[{Generate, Anno, P, Iter}|Acc], Bs2, Lf, Ef, FUVs, continue) end; @@ -1111,8 +1108,7 @@ bind_all_generators1([{m_generate_strict, Anno, P, Iter0}|Qs], Acc, Bs0, Lf, Ef, _ -> bind_all_generators1(Qs,[{m_generate_strict, Anno, P, Iter}|Acc], Bs2, Lf, Ef, FUVs, continue) end; - nomatch -> - {Acc, error} + nomatch -> {Acc, error} end; none -> {[], done}