From d3ece60d52880fb273da3c4aa07655a0eeddeafb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Wed, 16 May 2012 10:49:36 +0200 Subject: Introduce a representation for maps in Core Erlang --- lib/compiler/src/core_parse.hrl | 6 ++++++ lib/compiler/src/core_parse.yrl | 30 +++++++++++++++++++++++++++++- lib/compiler/src/core_pp.erl | 16 ++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/lib/compiler/src/core_parse.hrl b/lib/compiler/src/core_parse.hrl index 0b8f4d8895..c134747991 100644 --- a/lib/compiler/src/core_parse.hrl +++ b/lib/compiler/src/core_parse.hrl @@ -96,3 +96,9 @@ -record(c_values, {anno=[], es}). % es :: [Tree] -record(c_var, {anno=[], name :: cerl:var_name()}). + +-record(c_map_pair, {anno=[], key, val}). + +-record(c_map, {anno=[], + var=#c_literal{val=[]} :: #c_var{} | #c_literal{}, + es :: [#c_map_pair{}]}). diff --git a/lib/compiler/src/core_parse.yrl b/lib/compiler/src/core_parse.yrl index 4e98a8c2da..b072950eeb 100644 --- a/lib/compiler/src/core_parse.yrl +++ b/lib/compiler/src/core_parse.yrl @@ -21,6 +21,8 @@ %% Have explicit productions for annotated phrases named anno_XXX. %% This just does an XXX and adds the annotation. +Expect 1. + Nonterminals module_definition module_export module_attribute module_defs @@ -44,6 +46,9 @@ receive_expr timeout try_expr sequence catch_expr variable clause clause_pattern +map_expr map_pairs map_pair +map_pattern map_pair_patterns map_pair_pattern + annotation anno_fun anno_expression anno_expressions anno_variable anno_variables anno_pattern anno_patterns anno_function_name @@ -53,7 +58,7 @@ Terminals %% Separators -'(' ')' '{' '}' '[' ']' '|' ',' '->' '=' '/' '<' '>' ':' '-|' '#' +'(' ')' '{' '}' '[' ']' '|' ',' '->' '=' '/' '<' '>' ':' '-|' '#' '~' %% Keywords (atoms are assumed to always be single-quoted). @@ -166,6 +171,7 @@ anno_patterns -> anno_pattern : ['$1']. other_pattern -> atomic_pattern : '$1'. other_pattern -> tuple_pattern : '$1'. +other_pattern -> map_pattern : '$1'. other_pattern -> cons_pattern : '$1'. other_pattern -> binary_pattern : '$1'. other_pattern -> anno_variable '=' anno_pattern : @@ -176,6 +182,16 @@ atomic_pattern -> atomic_literal : '$1'. tuple_pattern -> '{' '}' : c_tuple([]). tuple_pattern -> '{' anno_patterns '}' : c_tuple('$2'). +map_pattern -> '~' '{' '}' '~' : #c_map{es=[]}. +map_pattern -> '~' '{' map_pair_patterns '}' '~' : + #c_map{es=lists:sort('$3')}. + +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{key='$3',val='$5'}. + cons_pattern -> '[' anno_pattern tail_pattern : #c_cons{hd='$2',tl='$3'}. @@ -240,6 +256,7 @@ single_expression -> primop_expr : '$1'. single_expression -> try_expr : '$1'. single_expression -> sequence : '$1'. single_expression -> catch_expr : '$1'. +single_expression -> map_expr : '$1'. literal -> atomic_literal : '$1'. literal -> tuple_literal : '$1'. @@ -267,6 +284,17 @@ tail_literal -> ',' literal tail_literal : #c_cons{hd='$2',tl='$3'}. tuple -> '{' '}' : c_tuple([]). tuple -> '{' anno_expressions '}' : c_tuple('$2'). +map_expr -> '~' '{' '}' '~' : #c_map{es=[]}. +map_expr -> '~' '{' map_pairs '}' '~' : #c_map{es='$3'}. +map_expr -> variable '~' '{' '}' '~' : #c_map{var='$',es=[]}. +map_expr -> variable '~' '{' map_pairs '}' '~' : #c_map{var='$1',es='$4'}. + +map_pairs -> map_pair : ['$1']. +map_pairs -> map_pair ',' map_pairs : ['$1' | '$3']. + +map_pair -> '~' '<' anno_expression ',' anno_expression'>' : + #c_map_pair{key='$3',val='$5'}. + cons -> '[' anno_expression tail : c_cons('$2', '$3'). tail -> ']' : #c_literal{val=[]}. diff --git a/lib/compiler/src/core_pp.erl b/lib/compiler/src/core_pp.erl index 1f91a52be3..c8c59b9246 100644 --- a/lib/compiler/src/core_pp.erl +++ b/lib/compiler/src/core_pp.erl @@ -161,6 +161,22 @@ format_1(#c_tuple{es=Es}, Ctxt) -> format_hseq(Es, ",", add_indent(Ctxt, 1), fun format/2), $} ]; +format_1(#c_map{var=#c_var{}=Var,es=Es}, Ctxt) -> + [format_1(Var, Ctxt), + "~{", + format_hseq(Es, ",", add_indent(Ctxt, 1), fun format/2), + "}~" + ]; +format_1(#c_map{es=Es}, Ctxt) -> + ["~{", + format_hseq(Es, ",", add_indent(Ctxt, 1), fun format/2), + "}~" + ]; +format_1(#c_map_pair{key=K,val=V}, Ctxt) -> + ["~<", + format_hseq([K,V], ",", add_indent(Ctxt, 1), fun format/2), + ">" + ]; format_1(#c_cons{hd=H,tl=T}, Ctxt) -> Txt = ["["|format(H, add_indent(Ctxt, 1))], [Txt|format_list_tail(T, add_indent(Ctxt, width(Txt, Ctxt)))]; -- cgit v1.2.3