aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler
diff options
context:
space:
mode:
authorBjörn-Egil Dahlberg <[email protected]>2013-10-01 23:42:17 +0200
committerBjörn-Egil Dahlberg <[email protected]>2014-01-28 15:56:28 +0100
commit3c5067eab057391e101845b03c1ba7b76d2b3562 (patch)
treef83b915aa09ce24099c20b97d83d3c24a155b464 /lib/compiler
parent652ddd4c360cd2cc381ed033915d87d967310a49 (diff)
downloadotp-3c5067eab057391e101845b03c1ba7b76d2b3562.tar.gz
otp-3c5067eab057391e101845b03c1ba7b76d2b3562.tar.bz2
otp-3c5067eab057391e101845b03c1ba7b76d2b3562.zip
compiler: Implement support for exact Op in Maps
The syntax is handled upto v3_kernel where it is reduced to previous behaviour for construction and updates. Meaning, the ':=' operator is handled exactly as '=>' operator.
Diffstat (limited to 'lib/compiler')
-rw-r--r--lib/compiler/src/core_lib.erl4
-rw-r--r--lib/compiler/src/sys_core_dsetel.erl10
-rw-r--r--lib/compiler/src/sys_core_fold.erl22
-rw-r--r--lib/compiler/src/v3_core.erl35
-rw-r--r--lib/compiler/src/v3_kernel.erl18
5 files changed, 61 insertions, 28 deletions
diff --git a/lib/compiler/src/core_lib.erl b/lib/compiler/src/core_lib.erl
index f506901099..d6221a22bb 100644
--- a/lib/compiler/src/core_lib.erl
+++ b/lib/compiler/src/core_lib.erl
@@ -107,7 +107,9 @@ vu_expr(V, #c_tuple{es=Es}) ->
vu_expr_list(V, Es);
vu_expr(V, #c_map{es=Es}) ->
vu_expr_list(V, Es);
-vu_expr(V, #c_map_pair{key=Key,val=Val}) ->
+vu_expr(V, #c_map_pair_assoc{key=Key,val=Val}) ->
+ vu_expr_list(V, [Key,Val]);
+vu_expr(V, #c_map_pair_exact{key=Key,val=Val}) ->
vu_expr_list(V, [Key,Val]);
vu_expr(V, #c_binary{segments=Ss}) ->
vu_seg_list(V, Ss);
diff --git a/lib/compiler/src/sys_core_dsetel.erl b/lib/compiler/src/sys_core_dsetel.erl
index c7c8343c35..f921429409 100644
--- a/lib/compiler/src/sys_core_dsetel.erl
+++ b/lib/compiler/src/sys_core_dsetel.erl
@@ -105,10 +105,14 @@ visit(Env0, #c_tuple{es=Es0}=R) ->
visit(Env0, #c_map{es=Es0}=R) ->
{Es1,Env1} = visit_list(Env0, Es0),
{R#c_map{es=Es1}, Env1};
-visit(Env0, #c_map_pair{key=K0,val=V0}=R) ->
+visit(Env0, #c_map_pair_assoc{key=K0,val=V0}=R) ->
{K,Env1} = visit(Env0, K0),
{V,Env2} = visit(Env1, V0),
- {R#c_map_pair{key=K,val=V}, Env2};
+ {R#c_map_pair_assoc{key=K,val=V}, Env2};
+visit(Env0, #c_map_pair_exact{key=K0,val=V0}=R) ->
+ {K,Env1} = visit(Env0, K0),
+ {V,Env2} = visit(Env1, V0),
+ {R#c_map_pair_exact{key=K,val=V}, Env2};
visit(Env0, #c_cons{hd=H0,tl=T0}=R) ->
{H1,Env1} = visit(Env0, H0),
{T1,Env2} = visit(Env1, T0),
@@ -221,7 +225,7 @@ visit_pat(Env0, #c_tuple{es=Es}, Vs) ->
visit_pats(Es, Env0, Vs);
visit_pat(Env0, #c_map{es=Es}, Vs) ->
visit_pats(Es, Env0, Vs);
-visit_pat(Env0, #c_map_pair{key=V,val=K}, Vs0) ->
+visit_pat(Env0, #c_map_pair_exact{key=V,val=K}, Vs0) ->
{Vs1, Env1} = visit_pat(Env0, V, Vs0),
visit_pat(Env1, K, Vs1);
visit_pat(Env0, #c_cons{hd=H,tl=T}, Vs0) ->
diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl
index cdbe2d0753..2cd6ea0e53 100644
--- a/lib/compiler/src/sys_core_fold.erl
+++ b/lib/compiler/src/sys_core_fold.erl
@@ -438,18 +438,28 @@ pair_list_reversed([E|Es],Ctxt,Sub,Out,Keys) ->
%% check if key already is present in map, i.e. #{ a=>1, a=>2 }
%% where 'a' is duplicate. Update maps set with the key if not present.
-map_has_key(#c_map_pair{key=#c_literal{val=K}},Ks) ->
+map_has_key(MapPair,Ks) ->
+ K = map_get_literal_key_from_pair(MapPair),
case gb_sets:is_element(K,Ks) of
false -> {false, gb_sets:add(K,Ks)};
true -> {true, K}
end.
-pair(#c_map_pair{key=K,val=V}, effect, Sub) ->
+map_get_literal_key_from_pair(#c_map_pair_assoc{key=#c_literal{val=K}}) -> K;
+map_get_literal_key_from_pair(#c_map_pair_exact{key=#c_literal{val=K}}) -> K.
+
+pair(#c_map_pair_assoc{key=K,val=V}, effect, Sub) ->
+ make_effect_seq([K,V], Sub);
+pair(#c_map_pair_exact{key=K,val=V}, effect, Sub) ->
make_effect_seq([K,V], Sub);
-pair(#c_map_pair{key=K0,val=V0}=Pair, value=Ctxt, Sub) ->
+pair(#c_map_pair_assoc{key=K0,val=V0}=Pair, value=Ctxt, Sub) ->
+ K = expr(K0, Ctxt, Sub),
+ V = expr(V0, Ctxt, Sub),
+ Pair#c_map_pair_assoc{key=K,val=V};
+pair(#c_map_pair_exact{key=K0,val=V0}=Pair, value=Ctxt, Sub) ->
K = expr(K0, Ctxt, Sub),
V = expr(V0, Ctxt, Sub),
- Pair#c_map_pair{key=K,val=V}.
+ Pair#c_map_pair_exact{key=K,val=V}.
bitstr_list(Es, Sub) ->
[bitstr(E, Sub) || E <- Es].
@@ -1559,10 +1569,10 @@ map_pair_pattern_list(Ps0, Isub, Osub0) ->
{Ps,{_,Osub}} = mapfoldl(fun map_pair_pattern/2, {Isub,Osub0}, Ps0),
{Ps,Osub}.
-map_pair_pattern(#c_map_pair{key=K0,val=V0}=Pair, {Isub,Osub0}) ->
+map_pair_pattern(#c_map_pair_exact{key=K0,val=V0}=Pair, {Isub,Osub0}) ->
{K,Osub1} = pattern(K0, Isub, Osub0),
{V,Osub} = pattern(V0, Isub, Osub1),
- {Pair#c_map_pair{key=K,val=V},{Isub,Osub}}.
+ {Pair#c_map_pair_exact{key=K,val=V},{Isub,Osub}}.
bin_pattern_list(Ps0, Isub, Osub0) ->
{Ps,{_,Osub}} = mapfoldl(fun bin_pattern/2, {Isub,Osub0}, Ps0),
diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl
index 32b65333a4..b33799275b 100644
--- a/lib/compiler/src/v3_core.erl
+++ b/lib/compiler/src/v3_core.erl
@@ -488,6 +488,8 @@ expr({tuple,L,Es0}, St0) ->
A = lineno_anno(L, St1),
{ann_c_tuple(A, Es1),Eps,St1};
expr({map,L,Es0}, St0) ->
+ % erl_lint should make sure only #{ K => V } are allowed
+ % in map construction.
{Es1,Eps,St1} = map_pair_list(Es0, St0),
A = lineno_anno(L, St1),
{#c_map{anno=A,es=Es1},Eps,St1};
@@ -705,13 +707,20 @@ make_bool_switch_guard(L, E, V, T, F) ->
]}.
map_pair_list(Es, St) ->
- foldr(fun ({map_field,L,K0,V0}, {Ces,Esp,St0}) ->
- {K,Ep0,St1} = safe(K0, St0),
- {V,Ep1,St2} = safe(V0, St1),
- A = lineno_anno(L, St2),
- Pair = #c_map_pair{anno=A,key=K,val=V},
- {[Pair|Ces],Ep0 ++ Ep1 ++ Esp,St2}
- end, {[],[],St}, Es).
+ foldr(fun
+ ({map_field_assoc,L,K0,V0}, {Ces,Esp,St0}) ->
+ {K,Ep0,St1} = safe(K0, St0),
+ {V,Ep1,St2} = safe(V0, St1),
+ A = lineno_anno(L, St2),
+ Pair = #c_map_pair_assoc{anno=A,key=K,val=V},
+ {[Pair|Ces],Ep0 ++ Ep1 ++ Esp,St2};
+ ({map_field_exact,L,K0,V0}, {Ces,Esp,St0}) ->
+ {K,Ep0,St1} = safe(K0, St0),
+ {V,Ep1,St2} = safe(V0, St1),
+ A = lineno_anno(L, St2),
+ Pair = #c_map_pair_exact{anno=A,key=K,val=V},
+ {[Pair|Ces],Ep0 ++ Ep1 ++ Esp,St2}
+ end, {[],[],St}, Es).
%% try_exception([ExcpClause], St) -> {[ExcpVar],Handler,St}.
@@ -1497,7 +1506,7 @@ pattern({tuple,L,Ps}, St) ->
ann_c_tuple(lineno_anno(L, St), pattern_list(Ps, St));
pattern({map,L,Ps}, St) ->
#c_map{anno=lineno_anno(L, St),es=sort(pattern_list(Ps, St))};
-pattern({map_field,L,K,V}, St) ->
+pattern({map_field_exact,L,K,V}, St) ->
%% FIXME: Better way to construct literals? or missing case
%% {Key,_,_} = expr(K, St),
Key = case K of
@@ -1511,7 +1520,7 @@ pattern({map_field,L,K,V}, St) ->
_ ->
pattern(K,St)
end,
- #c_map_pair{anno=lineno_anno(L, St),
+ #c_map_pair_exact{anno=lineno_anno(L, St),
key=Key,
val=pattern(V, St)};
pattern({bin,L,Ps}, St) ->
@@ -1862,9 +1871,9 @@ upattern(#c_tuple{es=Es0}=Tuple, Ks, St0) ->
upattern(#c_map{es=Es0}=Map, Ks, St0) ->
{Es1,Esg,Esv,Eus,St1} = upattern_list(Es0, Ks, St0),
{Map#c_map{es=Es1},Esg,Esv,Eus,St1};
-upattern(#c_map_pair{val=V0}=MapPair, Ks, St0) ->
+upattern(#c_map_pair_exact{val=V0}=MapPair, Ks, St0) ->
{V,Vg,Vv,Vu,St1} = upattern(V0, Ks, St0),
- {MapPair#c_map_pair{val=V},Vg,Vv,Vu,St1};
+ {MapPair#c_map_pair_exact{val=V},Vg,Vv,Vu,St1};
upattern(#c_binary{segments=Es0}=Bin, Ks, St0) ->
{Es1,Esg,Esv,Eus,St1} = upat_bin(Es0, Ks, St0),
{Bin#c_binary{segments=Es1},Esg,Esv,Eus,St1};
@@ -2195,7 +2204,9 @@ is_simple(#c_cons{hd=H,tl=T}) ->
is_simple(H) andalso is_simple(T);
is_simple(#c_tuple{es=Es}) -> is_simple_list(Es);
is_simple(#c_map{es=Es}) -> is_simple_list(Es);
-is_simple(#c_map_pair{key=K,val=V}) ->
+is_simple(#c_map_pair_assoc{key=K,val=V}) ->
+ is_simple(K) andalso is_simple(V);
+is_simple(#c_map_pair_exact{key=K,val=V}) ->
is_simple(K) andalso is_simple(V);
is_simple(_) -> false.
diff --git a/lib/compiler/src/v3_kernel.erl b/lib/compiler/src/v3_kernel.erl
index f4ba60e529..44f853ec2b 100644
--- a/lib/compiler/src/v3_kernel.erl
+++ b/lib/compiler/src/v3_kernel.erl
@@ -497,12 +497,18 @@ translate_match_fail_1(Anno, As, Sub, #kern{ff=FF}) ->
translate_fc(Args) ->
[#c_literal{val=function_clause},make_list(Args)].
+%% FIXME: Not completed
map_pairs(Es, Sub, St) ->
- foldr(fun(#c_map_pair{key=K0,val=V0}, {Kes,Esp,St0}) ->
- {K,[],St1} = expr(K0, Sub, St0),
- {V,Ep,St2} = atomic(V0, Sub, St1),
- {[#k_map_pair{key=K,val=V}|Kes],Ep ++ Esp,St2}
- end, {[],[],St}, Es).
+ foldr(fun
+ (#c_map_pair_assoc{key=K0,val=V0}, {Kes,Esp,St0}) ->
+ {K,[],St1} = expr(K0, Sub, St0),
+ {V,Ep,St2} = atomic(V0, Sub, St1),
+ {[#k_map_pair{key=K,val=V}|Kes],Ep ++ Esp,St2};
+ (#c_map_pair_exact{key=K0,val=V0}, {Kes,Esp,St0}) ->
+ {K,[],St1} = expr(K0, Sub, St0),
+ {V,Ep,St2} = atomic(V0, Sub, St1),
+ {[#k_map_pair{key=K,val=V}|Kes],Ep ++ Esp,St2}
+ end, {[],[],St}, Es).
%% call_type(Module, Function, Arity) -> call | bif | apply | error.
%% Classify the call.
@@ -662,7 +668,7 @@ pattern(#c_tuple{anno=A,es=Ces}, Isub, Osub0, St0) ->
pattern(#c_map{anno=A,es=Ces}, Isub, Osub0, St0) ->
{Kes,Osub1,St1} = pattern_list(Ces, Isub, Osub0, St0),
{#k_map{anno=A,es=Kes},Osub1,St1};
-pattern(#c_map_pair{anno=A,key=Ck,val=Cv},Isub, Osub0, St0) ->
+pattern(#c_map_pair_exact{anno=A,key=Ck,val=Cv},Isub, Osub0, St0) ->
{Kk,Osub1,St1} = pattern(Ck, Isub, Osub0, St0),
{Kv,Osub2,St2} = pattern(Cv, Isub, Osub1, St1),
{#k_map_pair{anno=A,key=Kk,val=Kv},Osub2,St2};