aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorBjörn-Egil Dahlberg <[email protected]>2013-09-17 16:50:05 +0200
committerBjörn-Egil Dahlberg <[email protected]>2014-01-28 15:56:25 +0100
commit08a9a9a7113d310de2e6511d898a06cb8a559ce8 (patch)
tree6260885fdc38c40273564ef8b006a9b6e12f2776 /lib
parent2a943f14a44903eb8e67549978de5dbf7275ad57 (diff)
downloadotp-08a9a9a7113d310de2e6511d898a06cb8a559ce8.tar.gz
otp-08a9a9a7113d310de2e6511d898a06cb8a559ce8.tar.bz2
otp-08a9a9a7113d310de2e6511d898a06cb8a559ce8.zip
compiler: Handle literals, not just atoms, as keys in maps
Diffstat (limited to 'lib')
-rw-r--r--lib/compiler/src/sys_pre_expand.erl7
-rw-r--r--lib/compiler/src/v3_core.erl15
-rw-r--r--lib/compiler/src/v3_kernel.erl19
3 files changed, 26 insertions, 15 deletions
diff --git a/lib/compiler/src/sys_pre_expand.erl b/lib/compiler/src/sys_pre_expand.erl
index 969e95e8dc..04084d22ff 100644
--- a/lib/compiler/src/sys_pre_expand.erl
+++ b/lib/compiler/src/sys_pre_expand.erl
@@ -231,9 +231,10 @@ pattern({tuple,Line,Ps}, St0) ->
pattern({map,Line,Ps}, St0) ->
{TPs,St1} = pattern_list(Ps, St0),
{{map,Line,TPs},St1};
-pattern({map_field,Line,Key,V0}, St0) ->
- {V,St1} = pattern(V0, St0),
- {{map_field,Line,Key,V},St1};
+pattern({map_field,Line,K0,V0}, St0) ->
+ {K,St1} = pattern(K0, St0),
+ {V,St2} = pattern(V0, St1),
+ {{map_field,Line,K,V},St2};
%%pattern({struct,Line,Tag,Ps}, St0) ->
%% {TPs,TPsvs,St1} = pattern_list(Ps, St0),
%% {{tuple,Line,[{atom,Line,Tag}|TPs]},TPsvs,St1};
diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl
index 1ef710a260..32b65333a4 100644
--- a/lib/compiler/src/v3_core.erl
+++ b/lib/compiler/src/v3_core.erl
@@ -1498,8 +1498,21 @@ pattern({tuple,L,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) ->
+ %% FIXME: Better way to construct literals? or missing case
+ %% {Key,_,_} = expr(K, St),
+ Key = case K of
+ {bin,L,Es0} ->
+ case constant_bin(Es0) of
+ error ->
+ throw(badmatch);
+ Bin ->
+ #c_literal{anno=lineno_anno(L,St),val=Bin}
+ end;
+ _ ->
+ pattern(K,St)
+ end,
#c_map_pair{anno=lineno_anno(L, St),
- key=pattern(K, St),
+ key=Key,
val=pattern(V, St)};
pattern({bin,L,Ps}, St) ->
%% We don't create a #ibinary record here, since there is
diff --git a/lib/compiler/src/v3_kernel.erl b/lib/compiler/src/v3_kernel.erl
index 84b3a4e37f..3d2dbf2088 100644
--- a/lib/compiler/src/v3_kernel.erl
+++ b/lib/compiler/src/v3_kernel.erl
@@ -662,10 +662,10 @@ 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=Kk0,val=Cv},Isub, Osub0, St0) ->
- Kk = #k_atom{val=Kk0#c_literal.val},
- {Kv,Osub1,St1} = pattern(Cv, Isub, Osub0, St0),
- {#k_map_pair{anno=A,key=Kk,val=Kv},Osub1,St1};
+pattern(#c_map_pair{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};
pattern(#c_binary{anno=A,segments=Cv}, Isub, Osub0, St0) ->
{Kv,Osub1,St1} = pattern_bin(Cv, Isub, Osub0, St0),
{#k_binary{anno=A,segs=Kv},Osub1,St1};
@@ -1270,12 +1270,9 @@ group_value(k_cons, Cs) -> [Cs]; %These are single valued
group_value(k_nil, Cs) -> [Cs];
group_value(k_binary, Cs) -> [Cs];
group_value(k_bin_end, Cs) -> [Cs];
-group_value(k_bin_seg, Cs) ->
- group_bin_seg(Cs);
-group_value(k_bin_int, Cs) ->
- [Cs];
-group_value(k_map, Cs) ->
- group_map(Cs);
+group_value(k_bin_seg, Cs) -> group_bin_seg(Cs);
+group_value(k_bin_int, Cs) -> [Cs];
+group_value(k_map, Cs) -> group_map(Cs);
group_value(_, Cs) ->
%% group_value(Cs).
Cd = foldl(fun (C, Gcs0) -> dict:append(clause_val(C), C, Gcs0) end,
@@ -1467,7 +1464,7 @@ arg_val(Arg, C) ->
end;
#k_map{es=Es} ->
Keys = [begin
- #k_map_pair{key=#k_atom{val=Key}} = Pair,
+ #k_map_pair{key=#k_literal{val=Key}} = Pair,
Key
end || Pair <- Es],
ordsets:from_list(Keys)