aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stdlib/src/erl_eval.erl
diff options
context:
space:
mode:
authorBjörn-Egil Dahlberg <[email protected]>2012-06-04 00:36:11 +0200
committerBjörn-Egil Dahlberg <[email protected]>2014-01-28 15:56:27 +0100
commit542c79e9685adbdab398856af99aaf9137966ec9 (patch)
tree2e6e1b4c4dfa29436d33352e0aab1e2ea397c247 /lib/stdlib/src/erl_eval.erl
parentd6b62db709a9e8e80689416bd7a5e5444ac3d3bf (diff)
downloadotp-542c79e9685adbdab398856af99aaf9137966ec9.tar.gz
otp-542c79e9685adbdab398856af99aaf9137966ec9.tar.bz2
otp-542c79e9685adbdab398856af99aaf9137966ec9.zip
erl_eval: Add functions to interpreter for maps
Diffstat (limited to 'lib/stdlib/src/erl_eval.erl')
-rw-r--r--lib/stdlib/src/erl_eval.erl28
1 files changed, 28 insertions, 0 deletions
diff --git a/lib/stdlib/src/erl_eval.erl b/lib/stdlib/src/erl_eval.erl
index 18d8148b15..335134d1f0 100644
--- a/lib/stdlib/src/erl_eval.erl
+++ b/lib/stdlib/src/erl_eval.erl
@@ -239,6 +239,21 @@ expr({record,_,Name,_}, _Bs, _Lf, _Ef, _RBs) ->
erlang:raise(error, {undef_record,Name}, stacktrace());
expr({record,_,_,Name,_}, _Bs, _Lf, _Ef, _RBs) ->
erlang:raise(error, {undef_record,Name}, stacktrace());
+
+%% map
+expr({map_field,_,EK, EV}, Bs0, Lf, Ef, RBs) ->
+ {value,K,Bs1} = expr(EK, Bs0, Lf, Ef, none),
+ {value,V,Bs2} = expr(EV, Bs0, Lf, Ef, none),
+ ret_expr({K,V}, merge_bindings(Bs1,Bs2), RBs);
+expr({map,_, Binding,Es}, Bs0, Lf, Ef, RBs) ->
+ {value, Map0, Bs1} = expr(Binding, Bs0, Lf, Ef, RBs),
+ {Vs,Bs} = expr_list(Es, Bs1, Lf, Ef),
+ ret_expr(lists:foldl(fun({K,V}, Mi) -> map:put(K,V,Mi) end, Map0, Vs), Bs, RBs);
+expr({map,_,Es}, Bs0, Lf, Ef, RBs) ->
+ {Vs,Bs} = expr_list(Es, Bs0, Lf, Ef),
+ ret_expr(lists:foldl(fun({K,V}, Mi) -> map:put(K,V,Mi) end, map:new(), Vs), Bs, RBs);
+
+
expr({block,_,Es}, Bs, Lf, Ef, RBs) ->
exprs(Es, Bs, Lf, Ef, RBs);
expr({'if',_,Cs}, Bs, Lf, Ef, RBs) ->
@@ -994,6 +1009,7 @@ type_test(port) -> is_port;
type_test(function) -> is_function;
type_test(binary) -> is_binary;
type_test(record) -> is_record;
+type_test(map) -> is_map;
type_test(Test) -> Test.
@@ -1075,6 +1091,9 @@ match1({tuple,_,Elts}, Tuple, Bs, BBs)
match_tuple(Elts, Tuple, 1, Bs, BBs);
match1({tuple,_,_}, _, _Bs, _BBs) ->
throw(nomatch);
+match1({map,_,Fs}, Map, Bs, BBs) ->
+ match_map(Fs, Map, Bs, BBs);
+
match1({bin, _, Fs}, <<_/bitstring>>=B, Bs0, BBs) ->
eval_bits:match_bits(Fs, B, Bs0, BBs,
match_fun(BBs),
@@ -1118,6 +1137,15 @@ match_tuple([E|Es], Tuple, I, Bs0, BBs) ->
match_tuple([], _, _, Bs, _BBs) ->
{match,Bs}.
+match_map([{map_field, _, K, V}|Fs], Map, Bs0, BBs) ->
+ Vm = try map:get(element(3,K),Map)
+ catch error:_ -> throw(nomatch)
+ end,
+ {match, Bs} = match1(V, Vm, Bs0, BBs),
+ match_map(Fs, Map, Bs, BBs);
+match_map([], _, Bs, _) ->
+ {match, Bs}.
+
%% match_list(PatternList, TermList, Bindings) ->
%% {match,NewBindings} | nomatch
%% Try to match a list of patterns against a list of terms with the