diff options
-rw-r--r-- | lib/compiler/src/cerl.erl | 32 | ||||
-rw-r--r-- | lib/compiler/src/sys_core_fold.erl | 4 |
2 files changed, 33 insertions, 3 deletions
diff --git a/lib/compiler/src/cerl.erl b/lib/compiler/src/cerl.erl index 9024999d7f..61b47ed468 100644 --- a/lib/compiler/src/cerl.erl +++ b/lib/compiler/src/cerl.erl @@ -1588,7 +1588,7 @@ ann_c_map(As,Es) -> ann_c_map(As, #c_literal{val=#{}}, Es). ann_c_map(As,#c_literal{val=Mval}=M,Es) when is_map(Mval), map_size(Mval) =:= 0 -> - Pairs = [[K,V]||#c_map_pair{key=K,val=V}<-Es], + Pairs = [[Ck,Cv]||#c_map_pair{key=Ck,val=Cv}<-Es], IsLit = lists:foldl(fun(Pair,Res) -> Res andalso is_lit_list(Pair) end, true, Pairs), @@ -1599,8 +1599,36 @@ ann_c_map(As,#c_literal{val=Mval}=M,Es) when is_map(Mval), map_size(Mval) =:= 0 true -> #c_literal{anno=As, val=maps:from_list(lists:map(Fun, Pairs))} end; +ann_c_map(As,#c_literal{val=M},Es) when is_map(M) -> + fold_map_pairs(As,Es,M); ann_c_map(As,M,Es) -> - #c_map{var=M, es = Es, anno = As }. + #c_map{var=M, es=Es, anno=As }. + +fold_map_pairs(As,[],M) -> #c_literal{anno=As,val=M}; +%% M#{ K => V} +fold_map_pairs(As,[#c_map_pair{op=#c_literal{val=assoc},key=Ck,val=Cv}=E|Es],M) -> + case is_lit_list([Ck,Cv]) of + true -> + [K,V] = lit_list_vals([Ck,Cv]), + fold_map_pairs(As,Es,maps:put(K,V,M)); + false -> + #c_map{var=#c_literal{val=M,anno=As}, es=[E|Es], anno=As } + end; +%% M#{ K := V} +fold_map_pairs(As,[#c_map_pair{op=#c_literal{val=exact},key=Ck,val=Cv}=E|Es],M) -> + case is_lit_list([Ck,Cv]) of + true -> + [K,V] = lit_list_vals([Ck,Cv]), + case maps:is_key(K,M) of + true -> fold_map_pairs(As,Es,maps:put(K,V,M)); + false -> + #c_map{var=#c_literal{val=M,anno=As}, es=[E|Es], anno=As } + end; + false -> + #c_map{var=#c_literal{val=M,anno=As}, es=[E|Es], anno=As } + end; +fold_map_pairs(As,Es,M) -> + #c_map{var=#c_literal{val=M,anno=As}, es=Es, anno=As }. update_c_map(Old,M,Es) -> diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl index 90cc3b9051..bf1be6d773 100644 --- a/lib/compiler/src/sys_core_fold.erl +++ b/lib/compiler/src/sys_core_fold.erl @@ -72,7 +72,7 @@ -import(lists, [map/2,foldl/3,foldr/3,mapfoldl/3,all/2,any/2, reverse/1,reverse/2,member/2,nth/2,flatten/1,unzip/1]). --import(cerl, [ann_c_cons/3,ann_c_tuple/2,ann_c_map/3]). +-import(cerl, [ann_c_cons/3,ann_c_map/3,ann_c_tuple/2]). -include("core_parse.hrl"). @@ -1378,6 +1378,7 @@ eval_is_record(Call, _, _, _, _) -> Call. is_not_integer(#c_literal{val=Val}) when not is_integer(Val) -> true; is_not_integer(#c_tuple{}) -> true; is_not_integer(#c_cons{}) -> true; +is_not_integer(#c_map{}) -> true; is_not_integer(_) -> false. %% is_not_tuple(Core) -> true | false. @@ -1385,6 +1386,7 @@ is_not_integer(_) -> false. is_not_tuple(#c_literal{val=Val}) when not is_tuple(Val) -> true; is_not_tuple(#c_cons{}) -> true; +is_not_tuple(#c_map{}) -> true; is_not_tuple(_) -> false. %% eval_setelement(Call, Pos, Tuple, NewVal) -> Core. |