aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/compiler/src/cerl.erl106
-rw-r--r--lib/compiler/src/cerl_inline.erl46
-rw-r--r--lib/compiler/src/cerl_trees.erl65
-rw-r--r--lib/compiler/src/core_lib.erl4
-rw-r--r--lib/compiler/src/core_lint.erl10
-rw-r--r--lib/compiler/src/core_parse.hrl8
-rw-r--r--lib/compiler/src/core_parse.yrl6
-rw-r--r--lib/compiler/src/core_pp.erl4
-rw-r--r--lib/compiler/src/sys_core_dsetel.erl10
-rw-r--r--lib/compiler/src/sys_core_fold.erl16
-rw-r--r--lib/compiler/src/v3_core.erl15
-rw-r--r--lib/compiler/src/v3_kernel.erl11
12 files changed, 134 insertions, 167 deletions
diff --git a/lib/compiler/src/cerl.erl b/lib/compiler/src/cerl.erl
index c6bf046c4d..60a8559950 100644
--- a/lib/compiler/src/cerl.erl
+++ b/lib/compiler/src/cerl.erl
@@ -124,11 +124,11 @@
%% keep map exports here for now
map_es/1,
- update_c_map_skel/2,
- update_c_map_pair_assoc_skel/2, update_c_map_pair_exact_skel/2,
- ann_c_map_skel/2,
- ann_c_map_pair_assoc_skel/2, ann_c_map_pair_exact_skel/2,
- map_pair_es/1, map_pair_assoc_es/1, map_pair_exact_es/1
+ update_c_map/2,
+ ann_c_map/2,
+ map_pair_op/1,map_pair_key/1,map_pair_val/1,
+ update_c_map_pair/4,
+ ann_c_map_pair/4
]).
-export_type([c_binary/0, c_call/0, c_clause/0, c_cons/0, c_fun/0, c_literal/0,
@@ -155,8 +155,7 @@
-type c_letrec() :: #c_letrec{}.
-type c_literal() :: #c_literal{}.
-type c_map() :: #c_map{}.
--type c_map_pair_assoc() :: #c_map_pair_assoc{}.
--type c_map_pair_exact() :: #c_map_pair_exact{}.
+-type c_map_pair() :: #c_map_pair{}.
-type c_module() :: #c_module{}.
-type c_primop() :: #c_primop{}.
-type c_receive() :: #c_receive{}.
@@ -169,7 +168,7 @@
-type cerl() :: c_alias() | c_apply() | c_binary() | c_bitstr()
| c_call() | c_case() | c_catch() | c_clause() | c_cons()
| c_fun() | c_let() | c_letrec() | c_literal()
- | c_map() | c_map_pair_assoc() | c_map_pair_exact()
+ | c_map() | c_map_pair()
| c_module() | c_primop() | c_receive() | c_seq()
| c_try() | c_tuple() | c_values() | c_var().
@@ -282,8 +281,7 @@ type(#c_let{}) -> 'let';
type(#c_letrec{}) -> letrec;
type(#c_literal{}) -> literal;
type(#c_map{}) -> map;
-type(#c_map_pair_assoc{}) -> map_pair_assoc;
-type(#c_map_pair_exact{}) -> map_pair_exact;
+type(#c_map_pair{}) -> map_pair;
type(#c_module{}) -> module;
type(#c_primop{}) -> primop;
type(#c_receive{}) -> 'receive';
@@ -1581,50 +1579,24 @@ ann_make_list(_, [], Node) ->
map_es(#c_map{es = Es}) ->
Es.
-map_pair_assoc_es(#c_map_pair_assoc{key=K,val=V}) -> [K,V].
-map_pair_exact_es(#c_map_pair_exact{key=K,val=V}) -> [K,V].
-map_pair_es(#c_map_pair_assoc{key=K,val=V}) -> [K,V];
-map_pair_es(#c_map_pair_exact{key=K,val=V}) -> [K,V].
-
-update_c_map_pair_assoc_skel(Old, [K,V]) ->
- #c_map_pair_assoc{key=K, val=V, anno = get_ann(Old)}.
-
-update_c_map_pair_exact_skel(Old, [K,V]) ->
- #c_map_pair_exact{key=K, val=V, anno = get_ann(Old)}.
-
-ann_c_map_pair_assoc_skel(As, [K,V]) ->
- #c_map_pair_assoc{key = K, val=V, anno = As}.
-
-ann_c_map_pair_exact_skel(As, [K,V]) ->
- #c_map_pair_exact{key = K, val=V, anno = As}.
-
-%c_map_skel(Es) ->
-% #c_map{es = Es}.
-%
-
ann_c_map(As, Es) ->
#c_map{es = Es, anno = As }.
-%% TODO: when we have map literals use a variant of
-%% case is_lit_list(Es) of
-%% false ->
-%% #c_map{es = Es, anno = As};
-%% true ->
-%% #c_literal{val = maps:from_list(lit_list_vals(Es)), anno = As}
-%% end.
-
-ann_c_map_pair_assoc(As, [K,V]) ->
- #c_map_pair_assoc{key = K, val=V, anno = As}.
+update_c_map(Old, Es) ->
+ #c_map{es = Es, anno = get_ann(Old)}.
-ann_c_map_pair_exact(As, [K,V]) ->
- #c_map_pair_exact{key = K, val=V, anno = As}.
+map_pair_key(#c_map_pair{key=K}) -> K.
+map_pair_val(#c_map_pair{val=V}) -> V.
+map_pair_op(#c_map_pair{op=Op}) -> Op.
+-spec ann_c_map_pair([term()], cerl(), cerl(), cerl()) ->
+ c_map_pair().
-ann_c_map_skel(As, Es) ->
- #c_map{es = Es, anno = As}.
+ann_c_map_pair(As,Op,K,V) ->
+ #c_map_pair{op=Op, key = K, val=V, anno = As}.
-update_c_map_skel(Old, Es) ->
- #c_map{es = Es, anno = get_ann(Old)}.
+update_c_map_pair(Old,Op,K,V) ->
+ #c_map_pair{op=Op, key=K, val=V, anno = get_ann(Old)}.
%% ---------------------------------------------------------------------
@@ -3017,8 +2989,8 @@ pat_vars(Node, Vs) ->
pat_list_vars(tuple_es(Node), Vs);
map ->
pat_list_vars(map_es(Node), Vs);
- map_pair_exact ->
- pat_list_vars(map_pair_exact_es(Node), Vs);
+ map_pair ->
+ pat_list_vars([map_pair_op(Node),map_pair_key(Node),map_pair_val(Node)],Vs);
binary ->
pat_list_vars(binary_segments(Node), Vs);
bitstr ->
@@ -3830,12 +3802,6 @@ is_data(#c_cons{}) ->
true;
is_data(#c_tuple{}) ->
true;
-is_data(#c_map{}) ->
- true;
-is_data(#c_map_pair_assoc{}) ->
- true;
-is_data(#c_map_pair_exact{}) ->
- true;
is_data(_) ->
false.
@@ -3881,14 +3847,7 @@ data_type(#c_literal{val = V}) ->
data_type(#c_cons{}) ->
cons;
data_type(#c_tuple{}) ->
- tuple;
-data_type(#c_map{}) ->
- map;
-data_type(#c_map_pair_assoc{}) ->
- map_pair_assoc;
-data_type(#c_map_pair_exact{}) ->
- map_pair_exact.
-
+ tuple.
%% @spec data_es(Node::cerl()) -> [cerl()]
%%
@@ -3919,14 +3878,7 @@ data_es(#c_literal{val = V}) ->
data_es(#c_cons{hd = H, tl = T}) ->
[H, T];
data_es(#c_tuple{es = Es}) ->
- Es;
-data_es(#c_map{es=Es}) ->
- Es;
-data_es(#c_map_pair_assoc{key=K,val=V}) ->
- [K,V];
-data_es(#c_map_pair_exact{key=K,val=V}) ->
- [K,V].
-
+ Es.
%% @spec data_arity(Node::cerl()) -> integer()
%%
@@ -3982,11 +3934,7 @@ make_data(CType, Es) ->
ann_make_data(As, {atomic, V}, []) -> #c_literal{val = V, anno = As};
ann_make_data(As, cons, [H, T]) -> ann_c_cons(As, H, T);
-ann_make_data(As, tuple, Es) -> ann_c_tuple(As, Es);
-ann_make_data(As, map, Es) -> ann_c_map(As, Es);
-ann_make_data(As, map_pair_assoc, Es) -> ann_c_map_pair_assoc(As, Es);
-ann_make_data(As, map_pair_exact, Es) -> ann_c_map_pair_exact(As, Es).
-
+ann_make_data(As, tuple, Es) -> ann_c_tuple(As, Es).
%% @spec update_data(Old::cerl(), Type::dtype(),
%% Elements::[cerl()]) -> cerl()
@@ -4119,10 +4067,8 @@ subtrees(T) ->
[tuple_es(T)];
map ->
[map_es(T)];
- map_pair_assoc ->
- [map_pair_assoc_es(T)];
- map_pair_exact ->
- [map_pair_exact_es(T)];
+ map_pair ->
+ [[map_pair_op(T)],[map_pair_key(T)],[map_pair_val(T)]];
'let' ->
[let_vars(T), [let_arg(T)], [let_body(T)]];
seq ->
diff --git a/lib/compiler/src/cerl_inline.erl b/lib/compiler/src/cerl_inline.erl
index c6de63c69f..3837b57750 100644
--- a/lib/compiler/src/cerl_inline.erl
+++ b/lib/compiler/src/cerl_inline.erl
@@ -63,7 +63,11 @@
receive_clauses/1, receive_timeout/1, seq_arg/1,
seq_body/1, set_ann/2, try_arg/1, try_body/1, try_vars/1,
try_evars/1, try_handler/1, tuple_es/1, tuple_arity/1,
- type/1, values_es/1, var_name/1]).
+ type/1, values_es/1, var_name/1,
+ map_es/1, update_c_map/2,
+ update_c_map_pair/4,
+ map_pair_op/1, map_pair_key/1, map_pair_val/1
+ ]).
-import(lists, [foldl/3, foldr/3, mapfoldl/3, reverse/1]).
@@ -128,6 +132,8 @@ weight(call) -> 3; % Assume remote-calls as efficient as `apply'.
weight(primop) -> 2; % Assume more efficient than `apply'.
weight(binary) -> 4; % Initialisation base cost.
weight(bitstr) -> 3; % Coding/decoding a value; like a primop.
+weight(map) -> 4; % Initialisation base cost.
+weight(map_pair) -> 3; % Coding/decoding a value; like a primop.
weight(module) -> 1. % Like a letrec with a constant body
%% These "reference" structures are used for variables and function
@@ -333,6 +339,8 @@ i(E, Ctxt, Ren, Env, S0) ->
i_catch(E, Ctxt, Ren, Env, S);
binary ->
i_binary(E, Ren, Env, S);
+ map ->
+ i_map(E, Ctxt, Ren, Env, S);
module ->
i_module(E, Ctxt, Ren, Env, S)
end
@@ -1324,6 +1332,25 @@ i_bitstr(E, Ren, Env, S) ->
S3 = count_size(weight(bitstr), S2),
{update_c_bitstr(E, Val, Size, Unit, Type, Flags), S3}.
+i_map(E, Ctx, Ren, Env, S) ->
+ %% Visit the segments for value.
+ {Es, S1} = mapfoldl(fun (E, S) ->
+ i_map_pair(E, Ctx, Ren, Env, S)
+ end,
+ S, map_es(E)),
+ S2 = count_size(weight(map), S1),
+ {update_c_map(E, Es), S2}.
+
+i_map_pair(E, Ctx, Ren, Env, S) ->
+ %% It is not necessary to visit the Op and Key fields,
+ %% since these are always literals.
+ {Val, S1} = i(map_pair_val(E), Ctx, Ren, Env, S),
+ Op = map_pair_op(E),
+ Key = map_pair_key(E),
+ S2 = count_size(weight(map_pair), S1),
+ {update_c_map_pair(E, Op, Key, Val), S2}.
+
+
%% This is a simplified version of `i_pattern', for lists of parameter
%% variables only. It does not modify the state.
@@ -1383,6 +1410,14 @@ i_pattern(E, Ren, Env, Ren0, Env0, S) ->
S, binary_segments(E)),
S2 = count_size(weight(binary), S1),
{update_c_binary(E, Es), S2};
+ map ->
+ {Es, S1} = mapfoldl(fun (E, S) ->
+ i_map_pair_pattern(E, Ren, Env,
+ Ren0, Env0, S)
+ end,
+ S, map_es(E)),
+ S2 = count_size(weight(map), S1),
+ {update_c_map(E, Es), S2};
_ ->
case is_literal(E) of
true ->
@@ -1416,6 +1451,15 @@ i_bitstr_pattern(E, Ren, Env, Ren0, Env0, S) ->
S3 = count_size(weight(bitstr), S2),
{update_c_bitstr(E, Val, Size, Unit, Type, Flags), S3}.
+i_map_pair_pattern(E, Ren, Env, Ren0, Env0, S) ->
+ %% It is not necessary to visit the Op it is always a literal.
+ %% Same goes for Key
+ {Val, S1} = i_pattern(map_pair_val(E), Ren, Env, Ren0, Env0, S),
+ Op = map_pair_op(E), %% should be 'exact' literal
+ Key = map_pair_key(E),
+ S2 = count_size(weight(map_pair), S1),
+ {update_c_map_pair(E, Op, Key, Val), S2}.
+
%% ---------------------------------------------------------------------
%% Other central inlining functions
diff --git a/lib/compiler/src/cerl_trees.erl b/lib/compiler/src/cerl_trees.erl
index dc1cc606b3..2542841eef 100644
--- a/lib/compiler/src/cerl_trees.erl
+++ b/lib/compiler/src/cerl_trees.erl
@@ -58,11 +58,11 @@
update_c_values/2, values_es/1, var_name/1,
map_es/1,
- update_c_map_skel/2,
- update_c_map_pair_assoc_skel/2, update_c_map_pair_exact_skel/2,
- ann_c_map_skel/2,
- ann_c_map_pair_assoc_skel/2, ann_c_map_pair_exact_skel/2,
- map_pair_assoc_es/1, map_pair_exact_es/1
+ ann_c_map/2,
+ update_c_map/2,
+ map_pair_key/1,map_pair_val/1,map_pair_op/1,
+ ann_c_map_pair/4,
+ update_c_map_pair/4
]).
@@ -138,11 +138,11 @@ map_1(F, T) ->
tuple ->
update_c_tuple_skel(T, map_list(F, tuple_es(T)));
map ->
- update_c_map_skel(T, map_list(F, map_es(T)));
- map_pair_assoc ->
- update_c_map_pair_assoc_skel(T, map_list(F, map_pair_assoc_es(T)));
- map_pair_exact ->
- update_c_map_pair_exact_skel(T, map_list(F, map_pair_exact_es(T)));
+ update_c_map(T, map_list(F, map_es(T)));
+ map_pair ->
+ update_c_map_pair(T, map(F, map_pair_op(T)),
+ map(F, map_pair_key(T)),
+ map(F, map_pair_val(T)));
'let' ->
update_c_let(T, map_list(F, let_vars(T)),
map(F, let_arg(T)),
@@ -251,10 +251,12 @@ fold_1(F, S, T) ->
fold_list(F, S, tuple_es(T));
map ->
fold_list(F, S, map_es(T));
- map_pair_assoc ->
- fold_list(F, S, map_pair_assoc_es(T));
- map_pair_exact ->
- fold_list(F, S, map_pair_exact_es(T));
+ map_pair ->
+ fold(F,
+ fold(F,
+ fold(F, S, map_pair_op(T)),
+ map_pair_key(T)),
+ map_pair_val(T));
'let' ->
fold(F, fold(F, fold_list(F, S, let_vars(T)),
let_arg(T)),
@@ -371,13 +373,12 @@ mapfold(F, S0, T) ->
F(update_c_tuple_skel(T, Ts), S1);
map ->
{Ts, S1} = mapfold_list(F, S0, map_es(T)),
- F(update_c_map_skel(T, Ts), S1);
- map_pair_assoc ->
- {Ts, S1} = mapfold_list(F, S0, map_pair_assoc_es(T)),
- F(update_c_map_pair_assoc_skel(T,Ts), S1);
- map_pair_exact ->
- {Ts, S1} = mapfold_list(F, S0, map_pair_exact_es(T)),
- F(update_c_map_pair_exact_skel(T,Ts), S1);
+ F(update_c_map(T, Ts), S1);
+ map_pair ->
+ {Op, S1} = mapfold(F, S0, map_pair_op(T)),
+ {Key, S2} = mapfold(F, S1, map_pair_key(T)),
+ {Val, S3} = mapfold(F, S2, map_pair_val(T)),
+ F(update_c_map_pair(T,Op,Key,Val), S3);
'let' ->
{Vs, S1} = mapfold_list(F, S0, let_vars(T)),
{A, S2} = mapfold(F, S1, let_arg(T)),
@@ -519,10 +520,8 @@ variables(T, S) ->
vars_in_list(tuple_es(T), S);
map ->
vars_in_list(map_es(T), S);
- map_pair_assoc ->
- vars_in_list(map_pair_assoc_es(T), S);
- map_pair_exact ->
- vars_in_list(map_pair_exact_es(T), S);
+ map_pair ->
+ vars_in_list([map_pair_op(T),map_pair_key(T), map_pair_val(T)], S);
'let' ->
Vs = variables(let_body(T), S),
Vs1 = var_list_names(let_vars(T)),
@@ -726,15 +725,13 @@ label(T, N, Env) ->
map ->
{Ts, N1} = label_list(map_es(T), N, Env),
{As, N2} = label_ann(T, N1),
- {ann_c_map_skel(As, Ts), N2};
- map_pair_assoc ->
- {Ts, N1} = label_list(map_pair_assoc_es(T), N, Env),
- {As, N2} = label_ann(T, N1),
- {ann_c_map_pair_assoc_skel(As, Ts), N2};
- map_pair_exact ->
- {Ts, N1} = label_list(map_pair_exact_es(T), N, Env),
- {As, N2} = label_ann(T, N1),
- {ann_c_map_pair_exact_skel(As, Ts), N2};
+ {ann_c_map(As, Ts), N2};
+ map_pair ->
+ {Op, N1} = label(map_pair_op(T), N, Env),
+ {Val, N2} = label(map_pair_key(T), N1, Env),
+ {Key, N3} = label(map_pair_val(T), N2, Env),
+ {As, N4} = label_ann(T, N3),
+ {ann_c_map_pair(As,Op,Key,Val), N4};
'let' ->
{A, N1} = label(let_arg(T), N, Env),
{Vs, N2, Env1} = label_vars(let_vars(T), N1, Env),
diff --git a/lib/compiler/src/core_lib.erl b/lib/compiler/src/core_lib.erl
index d6221a22bb..f506901099 100644
--- a/lib/compiler/src/core_lib.erl
+++ b/lib/compiler/src/core_lib.erl
@@ -107,9 +107,7 @@ 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_assoc{key=Key,val=Val}) ->
- vu_expr_list(V, [Key,Val]);
-vu_expr(V, #c_map_pair_exact{key=Key,val=Val}) ->
+vu_expr(V, #c_map_pair{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/core_lint.erl b/lib/compiler/src/core_lint.erl
index 185193e45d..36165245a6 100644
--- a/lib/compiler/src/core_lint.erl
+++ b/lib/compiler/src/core_lint.erl
@@ -256,9 +256,7 @@ gexpr(#c_tuple{es=Es}, Def, _Rt, St) ->
gexpr_list(Es, Def, St);
gexpr(#c_map{es=Es}, Def, _Rt, St) ->
gexpr_list(Es, Def, St);
-gexpr(#c_map_pair_assoc{key=K,val=V}, Def, _Rt, St) ->
- gexpr_list([K,V], Def, St);
-gexpr(#c_map_pair_exact{key=K,val=V}, Def, _Rt, St) ->
+gexpr(#c_map_pair{key=K,val=V}, Def, _Rt, St) ->
gexpr_list([K,V], Def, St);
gexpr(#c_binary{segments=Ss}, Def, _Rt, St) ->
gbitstr_list(Ss, Def, St);
@@ -312,9 +310,7 @@ expr(#c_tuple{es=Es}, Def, _Rt, St) ->
expr_list(Es, Def, St);
expr(#c_map{es=Es}, Def, _Rt, St) ->
expr_list(Es, Def, St);
-expr(#c_map_pair_assoc{key=K,val=V},Def,_Rt,St) ->
- expr_list([K,V],Def,St);
-expr(#c_map_pair_exact{key=K,val=V},Def,_Rt,St) ->
+expr(#c_map_pair{key=K,val=V},Def,_Rt,St) ->
expr_list([K,V],Def,St);
expr(#c_binary{segments=Ss}, Def, _Rt, St) ->
bitstr_list(Ss, Def, St);
@@ -469,7 +465,7 @@ pattern(#c_tuple{es=Es}, Def, Ps, St) ->
pattern_list(Es, Def, Ps, St);
pattern(#c_map{es=Es}, Def, Ps, St) ->
pattern_list(Es, Def, Ps, St);
-pattern(#c_map_pair_exact{key=K,val=V},Def,Ps,St) ->
+pattern(#c_map_pair{op=#c_literal{val=exact},key=K,val=V},Def,Ps,St) ->
pattern_list([K,V],Def,Ps,St);
pattern(#c_binary{segments=Ss}, Def, Ps, St0) ->
St = pat_bin_tail_check(Ss, St0),
diff --git a/lib/compiler/src/core_parse.hrl b/lib/compiler/src/core_parse.hrl
index 40c3ae4582..067a1ae895 100644
--- a/lib/compiler/src/core_parse.hrl
+++ b/lib/compiler/src/core_parse.hrl
@@ -97,10 +97,10 @@
-record(c_var, {anno=[], name :: cerl:var_name()}).
--record(c_map_pair_assoc, {anno=[], key, val}).
-
--record(c_map_pair_exact, {anno=[], key, val}).
+-record(c_map_pair, {anno=[],
+ op :: 'assoc' | 'exact',
+ key, val}).
-record(c_map, {anno=[],
var=#c_literal{val=[]} :: #c_var{} | #c_literal{},
- es :: [#c_map_pair_assoc{}|#c_map_pair_exact{}]}).
+ es :: [#c_map_pair{}]}).
diff --git a/lib/compiler/src/core_parse.yrl b/lib/compiler/src/core_parse.yrl
index 82ba11b0fc..67acb0856c 100644
--- a/lib/compiler/src/core_parse.yrl
+++ b/lib/compiler/src/core_parse.yrl
@@ -190,7 +190,7 @@ map_pair_patterns -> map_pair_pattern : ['$1'].
map_pair_patterns -> map_pair_pattern ',' map_pair_patterns : ['$1' | '$3'].
map_pair_pattern -> '~' '<' anno_pattern ',' anno_pattern '>' :
- #c_map_pair_exact{key='$3',val='$5'}.
+ #c_map_pair{op=exact,key='$3',val='$5'}.
cons_pattern -> '[' anno_pattern tail_pattern :
#c_cons{hd='$2',tl='$3'}.
@@ -296,9 +296,9 @@ map_pair -> map_pair_assoc : '$1'.
map_pair -> map_pair_exact : '$1'.
map_pair_assoc -> '::' '<' anno_expression ',' anno_expression'>' :
- #c_map_pair_assoc{key='$3',val='$5'}.
+ #c_map_pair{op=#c_literal{val=assoc},key='$3',val='$5'}.
map_pair_exact -> '~' '<' anno_expression ',' anno_expression'>' :
- #c_map_pair_exact{key='$3',val='$5'}.
+ #c_map_pair{op=#c_literal{val=exact},key='$3',val='$5'}.
cons -> '[' anno_expression tail : c_cons('$2', '$3').
diff --git a/lib/compiler/src/core_pp.erl b/lib/compiler/src/core_pp.erl
index f775d87507..faa26ec6df 100644
--- a/lib/compiler/src/core_pp.erl
+++ b/lib/compiler/src/core_pp.erl
@@ -172,12 +172,12 @@ format_1(#c_map{es=Es}, Ctxt) ->
format_hseq(Es, ",", add_indent(Ctxt, 1), fun format/2),
"}~"
];
-format_1(#c_map_pair_assoc{key=K,val=V}, Ctxt) ->
+format_1(#c_map_pair{op=#c_literal{val=assoc},key=K,val=V}, Ctxt) ->
["::<",
format_hseq([K,V], ",", add_indent(Ctxt, 1), fun format/2),
">"
];
-format_1(#c_map_pair_exact{key=K,val=V}, Ctxt) ->
+format_1(#c_map_pair{op=#c_literal{val=exact},key=K,val=V}, Ctxt) ->
["~<",
format_hseq([K,V], ",", add_indent(Ctxt, 1), fun format/2),
">"
diff --git a/lib/compiler/src/sys_core_dsetel.erl b/lib/compiler/src/sys_core_dsetel.erl
index f921429409..60d83763f8 100644
--- a/lib/compiler/src/sys_core_dsetel.erl
+++ b/lib/compiler/src/sys_core_dsetel.erl
@@ -105,14 +105,10 @@ 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_assoc{key=K0,val=V0}=R) ->
+visit(Env0, #c_map_pair{key=K0,val=V0}=R) ->
{K,Env1} = visit(Env0, K0),
{V,Env2} = visit(Env1, V0),
- {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};
+ {R#c_map_pair{key=K,val=V}, Env2};
visit(Env0, #c_cons{hd=H0,tl=T0}=R) ->
{H1,Env1} = visit(Env0, H0),
{T1,Env2} = visit(Env1, T0),
@@ -225,7 +221,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_exact{key=V,val=K}, Vs0) ->
+visit_pat(Env0, #c_map_pair{op=#c_literal{val=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 6792e2c894..1cdbac5693 100644
--- a/lib/compiler/src/sys_core_fold.erl
+++ b/lib/compiler/src/sys_core_fold.erl
@@ -421,18 +421,12 @@ expr_list(Es, Ctxt, Sub) ->
pair_list(Es, Ctxt, Sub) ->
[pair(E, Ctxt, Sub) || E <- Es].
-pair(#c_map_pair_assoc{key=K,val=V}, effect, Sub) ->
+pair(#c_map_pair{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_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) ->
+pair(#c_map_pair{key=K0,val=V0}=Pair, value=Ctxt, Sub) ->
K = expr(K0, Ctxt, Sub),
V = expr(V0, Ctxt, Sub),
- Pair#c_map_pair_exact{key=K,val=V}.
+ Pair#c_map_pair{key=K,val=V}.
bitstr_list(Es, Sub) ->
[bitstr(E, Sub) || E <- Es].
@@ -1542,10 +1536,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_exact{key=K0,val=V0}=Pair, {Isub,Osub0}) ->
+map_pair_pattern(#c_map_pair{op=#c_literal{val=exact},key=K0,val=V0}=Pair, {Isub,Osub0}) ->
{K,Osub1} = pattern(K0, Isub, Osub0),
{V,Osub} = pattern(V0, Isub, Osub1),
- {Pair#c_map_pair_exact{key=K,val=V},{Isub,Osub}}.
+ {Pair#c_map_pair{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 b5fb65ff08..e30bfa729c 100644
--- a/lib/compiler/src/v3_core.erl
+++ b/lib/compiler/src/v3_core.erl
@@ -712,13 +712,13 @@ map_pair_list(Es, St) ->
{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 = #c_map_pair{op=#c_literal{val=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 = #c_map_pair{op=#c_literal{val=exact},anno=A,key=K,val=V},
{[Pair|Ces],Ep0 ++ Ep1 ++ Esp,St2}
end, {[],[],St}, Es).
@@ -1520,7 +1520,8 @@ pattern({map_field_exact,L,K,V}, St) ->
_ ->
pattern(K,St)
end,
- #c_map_pair_exact{anno=lineno_anno(L, St),
+ #c_map_pair{anno=lineno_anno(L, St),
+ op=#c_literal{val=exact},
key=Key,
val=pattern(V, St)};
pattern({bin,L,Ps}, St) ->
@@ -1871,9 +1872,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_exact{val=V0}=MapPair, Ks, St0) ->
+upattern(#c_map_pair{op=#c_literal{val=exact},val=V0}=MapPair, Ks, St0) ->
{V,Vg,Vv,Vu,St1} = upattern(V0, Ks, St0),
- {MapPair#c_map_pair_exact{val=V},Vg,Vv,Vu,St1};
+ {MapPair#c_map_pair{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};
@@ -2204,9 +2205,7 @@ 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_assoc{key=K,val=V}) ->
- is_simple(K) andalso is_simple(V);
-is_simple(#c_map_pair_exact{key=K,val=V}) ->
+is_simple(#c_map_pair{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 1d7d168214..9a2b1605ad 100644
--- a/lib/compiler/src/v3_kernel.erl
+++ b/lib/compiler/src/v3_kernel.erl
@@ -500,14 +500,11 @@ translate_fc(Args) ->
%% FIXME: Not completed
map_pairs(Es, Sub, St) ->
foldr(fun
- (#c_map_pair_assoc{key=K0,val=V0}, {Kes,Esp,St0}) ->
+ (#c_map_pair{op=#c_literal{val=Op},key=K0,val=V0}, {Kes,Esp,St0}) when
+ Op =:= assoc; Op =:= exact -> %% assert Op
{K,[],St1} = expr(K0, Sub, St0),
{V,Ep,St2} = atomic(V0, Sub, St1),
- {[#k_map_pair{op=assoc,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{op=exact,key=K,val=V}|Kes],Ep ++ Esp,St2}
+ {[#k_map_pair{op=Op,key=K,val=V}|Kes],Ep ++ Esp,St2}
end, {[],[],St}, Es).
%% call_type(Module, Function, Arity) -> call | bif | apply | error.
@@ -668,7 +665,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_exact{anno=A,key=Ck,val=Cv},Isub, Osub0, St0) ->
+pattern(#c_map_pair{op=#c_literal{val=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,op=exact,key=Kk,val=Kv},Osub2,St2};