aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/v3_core.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2012-05-16 10:50:30 +0200
committerBjörn-Egil Dahlberg <[email protected]>2014-01-28 15:56:25 +0100
commit64ee859fc4c17259ab95192abf7493fed8f2b0ac (patch)
tree8506892a03635fa44f523f4daf470c4845e63e77 /lib/compiler/src/v3_core.erl
parentd3ece60d52880fb273da3c4aa07655a0eeddeafb (diff)
downloadotp-64ee859fc4c17259ab95192abf7493fed8f2b0ac.tar.gz
otp-64ee859fc4c17259ab95192abf7493fed8f2b0ac.tar.bz2
otp-64ee859fc4c17259ab95192abf7493fed8f2b0ac.zip
Implement support for maps in the compiler
To make it possible to build the entire OTP system, also define dummys for the instructions in ops.tab.
Diffstat (limited to 'lib/compiler/src/v3_core.erl')
-rw-r--r--lib/compiler/src/v3_core.erl32
1 files changed, 32 insertions, 0 deletions
diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl
index a5f31f3844..1ef710a260 100644
--- a/lib/compiler/src/v3_core.erl
+++ b/lib/compiler/src/v3_core.erl
@@ -487,6 +487,15 @@ expr({tuple,L,Es0}, St0) ->
{Es1,Eps,St1} = safe_list(Es0, St0),
A = lineno_anno(L, St1),
{ann_c_tuple(A, Es1),Eps,St1};
+expr({map,L,Es0}, St0) ->
+ {Es1,Eps,St1} = map_pair_list(Es0, St0),
+ A = lineno_anno(L, St1),
+ {#c_map{anno=A,es=Es1},Eps,St1};
+expr({map,L,{var,Vl,Map},Es0}, St0) ->
+ {Es1,Eps,St1} = map_pair_list(Es0, St0),
+ A = lineno_anno(L, St1),
+ Av = lineno_anno(Vl, St1),
+ {#c_map{anno=A,var=#c_var{anno=Av,name=Map},es=Es1},Eps,St1};
expr({bin,L,Es0}, St0) ->
try expr_bin(Es0, lineno_anno(L, St0), St0) of
{_,_,_}=Res -> Res
@@ -695,6 +704,14 @@ make_bool_switch_guard(L, E, V, T, F) ->
{clause,NegL,[V],[],[V]}
]}.
+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).
%% try_exception([ExcpClause], St) -> {[ExcpVar],Handler,St}.
@@ -1478,6 +1495,12 @@ pattern({cons,L,H,T}, St) ->
ann_c_cons(lineno_anno(L, St), pattern(H, St), pattern(T, St));
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) ->
+ #c_map_pair{anno=lineno_anno(L, St),
+ key=pattern(K, St),
+ val=pattern(V, St)};
pattern({bin,L,Ps}, St) ->
%% We don't create a #ibinary record here, since there is
%% no need to hold any used/new annotations in a pattern.
@@ -1823,6 +1846,12 @@ upattern(#c_cons{hd=H0,tl=T0}=Cons, Ks, St0) ->
upattern(#c_tuple{es=Es0}=Tuple, Ks, St0) ->
{Es1,Esg,Esv,Eus,St1} = upattern_list(Es0, Ks, St0),
{Tuple#c_tuple{es=Es1},Esg,Esv,Eus,St1};
+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) ->
+ {V,Vg,Vv,Vu,St1} = upattern(V0, Ks, St0),
+ {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};
@@ -2152,6 +2181,9 @@ is_simple(#c_literal{}) -> true;
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(K) andalso is_simple(V);
is_simple(_) -> false.
-spec is_simple_list([cerl:cerl()]) -> boolean().