Skip to content

Commit a64ec79

Browse files
committed
support ES6-like hash literals.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50443 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
1 parent f266d21 commit a64ec79

File tree

1 file changed

+72
-17
lines changed

1 file changed

+72
-17
lines changed

parse.y

Lines changed: 72 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,10 @@ static int reg_fragment_check_gen(struct parser_params*, VALUE, int);
477477
static NODE *reg_named_capture_assign_gen(struct parser_params* parser, VALUE regexp, NODE *match);
478478
#define reg_named_capture_assign(regexp,match) reg_named_capture_assign_gen(parser,(regexp),(match))
479479

480+
static NODE *assoc_concat_gen(struct parser_params*,NODE*,NODE*);
481+
#define assoc_concat(assocs,tail) assoc_concat_gen(parser,(assocs),(tail))
482+
static ID var_to_assoc_key(ID);
483+
480484
#define get_id(id) (id)
481485
#define get_value(val) (val)
482486
#else
@@ -820,7 +824,7 @@ static void token_info_pop(struct parser_params*, const char *token);
820824
%type <node> command_asgn mrhs mrhs_arg superclass block_call block_command
821825
%type <node> f_block_optarg f_block_opt
822826
%type <node> f_arglist f_args f_arg f_arg_item f_optarg f_marg f_marg_list f_margs
823-
%type <node> assoc_list assocs assoc undef_list backref string_dvar for_var
827+
%type <node> assoc_list assoc_items assoc_item assocs assoc undef_list backref string_dvar for_var
824828
%type <node> block_param opt_block_param block_param_def f_opt
825829
%type <node> f_kwarg f_kw f_block_kwarg f_block_kw
826830
%type <node> bv_decls opt_bv_decl bvar
@@ -5006,7 +5010,7 @@ singleton : var_ref
50065010
;
50075011

50085012
assoc_list : none
5009-
| assocs trailer
5013+
| assoc_items trailer
50105014
{
50115015
/*%%%*/
50125016
$$ = $1;
@@ -5016,6 +5020,38 @@ assoc_list : none
50165020
}
50175021
;
50185022

5023+
assoc_items : assoc_item
5024+
/*%c%*/
5025+
/*%c
5026+
{
5027+
$$ = rb_ary_new3(1, $1);
5028+
}
5029+
%*/
5030+
| assoc_items ',' assoc_item
5031+
{
5032+
/*%%%*/
5033+
$$ = assoc_concat($1, $3);
5034+
/*%
5035+
$$ = rb_ary_push($1, $3);
5036+
%*/
5037+
}
5038+
;
5039+
5040+
assoc_item : assoc
5041+
| user_variable
5042+
{
5043+
/*%%%*/
5044+
ID k = var_to_assoc_key($1);
5045+
NODE *key, *val;
5046+
key = NEW_LIT(ID2SYM(k));
5047+
if (!(val = gettable($1))) val = NEW_BEGIN(0);
5048+
$$ = list_append(NEW_LIST(key), val);
5049+
/*%
5050+
$$ = dispatch2(assoc_new, $1, id_is_var(get_id($1)) ? dispatch1(var_ref, $1) : dispatch1(vcall, $1));
5051+
%*/
5052+
}
5053+
;
5054+
50195055
assocs : assoc
50205056
/*%c%*/
50215057
/*%c
@@ -5026,21 +5062,7 @@ assocs : assoc
50265062
| assocs ',' assoc
50275063
{
50285064
/*%%%*/
5029-
NODE *assocs = $1;
5030-
NODE *tail = $3;
5031-
if (!assocs) {
5032-
assocs = tail;
5033-
}
5034-
else if (tail) {
5035-
if (assocs->nd_head &&
5036-
!tail->nd_head && nd_type(tail->nd_next) == NODE_ARRAY &&
5037-
nd_type(tail->nd_next->nd_head) == NODE_HASH) {
5038-
/* DSTAR */
5039-
tail = tail->nd_next->nd_head->nd_head;
5040-
}
5041-
assocs = list_concat(assocs, tail);
5042-
}
5043-
$$ = assocs;
5065+
$$ = assoc_concat($1, $3);
50445066
/*%
50455067
$$ = rb_ary_push($1, $3);
50465068
%*/
@@ -10427,6 +10449,39 @@ rb_parser_reg_compile(struct parser_params* parser, VALUE str, int options, VALU
1042710449
return re;
1042810450
}
1042910451

10452+
static NODE *
10453+
assoc_concat_gen(struct parser_params *parser, NODE *assocs, NODE *tail)
10454+
{
10455+
if (!assocs) {
10456+
assocs = tail;
10457+
}
10458+
else if (tail) {
10459+
if (assocs->nd_head &&
10460+
!tail->nd_head && nd_type(tail->nd_next) == NODE_ARRAY &&
10461+
nd_type(tail->nd_next->nd_head) == NODE_HASH) {
10462+
/* DSTAR */
10463+
tail = tail->nd_next->nd_head->nd_head;
10464+
}
10465+
assocs = list_concat(assocs, tail);
10466+
}
10467+
return assocs;
10468+
}
10469+
10470+
static ID var_to_assoc_key(ID var)
10471+
{
10472+
switch (id_type(var)) {
10473+
case ID_LOCAL:
10474+
case ID_CONST:
10475+
return var;
10476+
default: {
10477+
const char *name = rb_id2name(var);
10478+
while (*name == '$' || *name == '@')
10479+
name++;
10480+
return rb_intern(name);
10481+
}
10482+
}
10483+
}
10484+
1043010485
NODE*
1043110486
rb_parser_append_print(VALUE vparser, NODE *node)
1043210487
{

0 commit comments

Comments
 (0)