@@ -477,6 +477,10 @@ static int reg_fragment_check_gen(struct parser_params*, VALUE, int);
477477static 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
50085012assoc_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+
50195055assocs : 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+
1043010485NODE*
1043110486rb_parser_append_print (VALUE vparser, NODE *node)
1043210487{
0 commit comments