mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	parse.y: quoted ID key
* parse.y (assoc): allow quoted ID as a key of a hash literal. [ruby-core:34453] [Feature #4276] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47649 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									7190c04417
								
							
						
					
					
						commit
						b0c03f63e5
					
				
					 6 changed files with 66 additions and 9 deletions
				
			
		| 
						 | 
				
			
			@ -1,3 +1,8 @@
 | 
			
		|||
Sat Sep 20 10:48:41 2014  Nobuyoshi Nakada  <nobu@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* parse.y (assoc): allow quoted ID as a key of a hash literal.
 | 
			
		||||
	  [ruby-core:34453] [Feature #4276]
 | 
			
		||||
 | 
			
		||||
Sat Sep 20 10:23:00 2014  Nobuyoshi Nakada  <nobu@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* compile.c (iseq_set_arguments): store local variable IDs in
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,6 +46,7 @@ static ID ripper_id_rational;
 | 
			
		|||
static ID ripper_id_regexp_beg;
 | 
			
		||||
static ID ripper_id_regexp_end;
 | 
			
		||||
static ID ripper_id_label;
 | 
			
		||||
static ID ripper_id_label_end;
 | 
			
		||||
static ID ripper_id_tlambda;
 | 
			
		||||
static ID ripper_id_tlambeg;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -103,6 +104,7 @@ ripper_init_eventids2(void)
 | 
			
		|||
    ripper_id_regexp_beg = rb_intern_const("on_regexp_beg");
 | 
			
		||||
    ripper_id_regexp_end = rb_intern_const("on_regexp_end");
 | 
			
		||||
    ripper_id_label = rb_intern_const("on_label");
 | 
			
		||||
    ripper_id_label_end = rb_intern_const("on_label_end");
 | 
			
		||||
    ripper_id_tlambda = rb_intern_const("on_tlambda");
 | 
			
		||||
    ripper_id_tlambeg = rb_intern_const("on_tlambeg");
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -259,6 +261,7 @@ static const struct token_assoc {
 | 
			
		|||
    {tWORDS_BEG,	&ripper_id_words_beg},
 | 
			
		||||
    {tXSTRING_BEG,	&ripper_id_backtick},
 | 
			
		||||
    {tLABEL,		&ripper_id_label},
 | 
			
		||||
    {tLABEL_END,	&ripper_id_label_end},
 | 
			
		||||
    {tLAMBDA,		&ripper_id_tlambda},
 | 
			
		||||
    {tLAMBEG,		&ripper_id_tlambeg},
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										47
									
								
								parse.y
									
										
									
									
									
								
							
							
						
						
									
										47
									
								
								parse.y
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -823,7 +823,7 @@ static void token_info_pop(struct parser_params*, const char *token);
 | 
			
		|||
%token tAMPER		"&"
 | 
			
		||||
%token tLAMBDA		"->"
 | 
			
		||||
%token tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tWORDS_BEG tQWORDS_BEG tSYMBOLS_BEG tQSYMBOLS_BEG
 | 
			
		||||
%token tSTRING_DBEG tSTRING_DEND tSTRING_DVAR tSTRING_END tLAMBEG
 | 
			
		||||
%token tSTRING_DBEG tSTRING_DEND tSTRING_DVAR tSTRING_END tLAMBEG tLABEL_END
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *	precedence table
 | 
			
		||||
| 
						 | 
				
			
			@ -2305,14 +2305,24 @@ arg		: lhs '=' arg
 | 
			
		|||
			$$ = dispatch1(defined, $4);
 | 
			
		||||
		    %*/
 | 
			
		||||
		    }
 | 
			
		||||
		| arg '?' arg opt_nl ':' arg
 | 
			
		||||
		| arg '?'
 | 
			
		||||
		    {
 | 
			
		||||
			$<val>$ = cond_stack;
 | 
			
		||||
			cond_stack = 0;
 | 
			
		||||
			COND_PUSH(1);
 | 
			
		||||
		    }
 | 
			
		||||
		  arg opt_nl ':'
 | 
			
		||||
		    {
 | 
			
		||||
			cond_stack = $<val>3;
 | 
			
		||||
		    }
 | 
			
		||||
		  arg
 | 
			
		||||
		    {
 | 
			
		||||
		    /*%%%*/
 | 
			
		||||
			value_expr($1);
 | 
			
		||||
			$$ = NEW_IF(cond($1), $3, $6);
 | 
			
		||||
			$$ = NEW_IF(cond($1), $4, $8);
 | 
			
		||||
			fixpos($$, $1);
 | 
			
		||||
		    /*%
 | 
			
		||||
			$$ = dispatch3(ifop, $1, $3, $6);
 | 
			
		||||
			$$ = dispatch3(ifop, $1, $4, $8);
 | 
			
		||||
		    %*/
 | 
			
		||||
		    }
 | 
			
		||||
		| primary
 | 
			
		||||
| 
						 | 
				
			
			@ -4217,6 +4227,9 @@ string_content	: tSTRING_CONTENT
 | 
			
		|||
		    {
 | 
			
		||||
			$<node>$ = lex_strterm;
 | 
			
		||||
			lex_strterm = 0;
 | 
			
		||||
		    }
 | 
			
		||||
		    {
 | 
			
		||||
			$<num>$ = lex_state;
 | 
			
		||||
			lex_state = EXPR_BEG;
 | 
			
		||||
		    }
 | 
			
		||||
		    {
 | 
			
		||||
| 
						 | 
				
			
			@ -4228,12 +4241,13 @@ string_content	: tSTRING_CONTENT
 | 
			
		|||
			cond_stack = $<val>1;
 | 
			
		||||
			cmdarg_stack = $<val>2;
 | 
			
		||||
			lex_strterm = $<node>3;
 | 
			
		||||
			brace_nest = $<num>4;
 | 
			
		||||
			lex_state = $<num>4;
 | 
			
		||||
			brace_nest = $<num>5;
 | 
			
		||||
		    /*%%%*/
 | 
			
		||||
			if ($5) $5->flags &= ~NODE_FL_NEWLINE;
 | 
			
		||||
			$$ = new_evstr($5);
 | 
			
		||||
			if ($6) $6->flags &= ~NODE_FL_NEWLINE;
 | 
			
		||||
			$$ = new_evstr($6);
 | 
			
		||||
		    /*%
 | 
			
		||||
			$$ = dispatch1(string_embexpr, $5);
 | 
			
		||||
			$$ = dispatch1(string_embexpr, $6);
 | 
			
		||||
		    %*/
 | 
			
		||||
		    }
 | 
			
		||||
		;
 | 
			
		||||
| 
						 | 
				
			
			@ -4947,6 +4961,14 @@ assoc		: arg_value tASSOC arg_value
 | 
			
		|||
			$$ = dispatch2(assoc_new, $1, $2);
 | 
			
		||||
		    %*/
 | 
			
		||||
		    }
 | 
			
		||||
		| tSTRING_BEG string_contents tLABEL_END arg_value
 | 
			
		||||
		    {
 | 
			
		||||
		    /*%%%*/
 | 
			
		||||
			$$ = list_append(NEW_LIST(dsym_node($2)), $4);
 | 
			
		||||
		    /*%
 | 
			
		||||
			$$ = dispatch2(assoc_new, dispatch1(dyna_symbol, $2), $4);
 | 
			
		||||
		    %*/
 | 
			
		||||
		    }
 | 
			
		||||
		| tDSTAR arg_value
 | 
			
		||||
		    {
 | 
			
		||||
		    /*%%%*/
 | 
			
		||||
| 
						 | 
				
			
			@ -7653,7 +7675,14 @@ parser_yylex(struct parser_params *parser)
 | 
			
		|||
	}
 | 
			
		||||
	else {
 | 
			
		||||
	    token = parse_string(lex_strterm);
 | 
			
		||||
	    if (token == tSTRING_END || token == tREGEXP_END) {
 | 
			
		||||
	    if (token == tSTRING_END && (peek_n('\'', -1) || peek_n('"', -1))) {
 | 
			
		||||
		if (((IS_lex_state(EXPR_BEG | EXPR_ENDFN) && !COND_P()) || IS_ARG()) &&
 | 
			
		||||
		    IS_LABEL_SUFFIX(0)) {
 | 
			
		||||
		    nextc();
 | 
			
		||||
		    token = tLABEL_END;
 | 
			
		||||
		}
 | 
			
		||||
	    }
 | 
			
		||||
	    if (token == tSTRING_END || token == tREGEXP_END || token == tLABEL_END) {
 | 
			
		||||
		rb_gc_force_recycle((VALUE)lex_strterm);
 | 
			
		||||
		lex_strterm = 0;
 | 
			
		||||
		lex_state = EXPR_END;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -548,6 +548,10 @@ class TestRipper::ParserEvents < Test::Unit::TestCase
 | 
			
		|||
    thru_dyna_symbol = false
 | 
			
		||||
    parse(':"#{foo}"', :on_dyna_symbol) {thru_dyna_symbol = true}
 | 
			
		||||
    assert_equal true, thru_dyna_symbol
 | 
			
		||||
 | 
			
		||||
    thru_dyna_symbol = false
 | 
			
		||||
    parse('{"#{foo}": 1}', :on_dyna_symbol) {thru_dyna_symbol = true}
 | 
			
		||||
    assert_equal true, thru_dyna_symbol
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_else
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -878,6 +878,11 @@ class TestRipper::ScannerEvents < Test::Unit::TestCase
 | 
			
		|||
                 scan('label', '{foo: 1}')
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_label_end
 | 
			
		||||
    assert_equal %w(":),
 | 
			
		||||
                 scan('label_end', '{"foo-bar": 1}')
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_tlambda
 | 
			
		||||
    assert_equal %w(->),
 | 
			
		||||
                 scan('tlambda', '->{}')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1269,6 +1269,17 @@ class TestHash < Test::Unit::TestCase
 | 
			
		|||
    assert_equal(bug9381, hash[wrapper.new(5)])
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_label_syntax
 | 
			
		||||
    return unless @cls == Hash
 | 
			
		||||
 | 
			
		||||
    feature4935 = '[ruby-core:37553] [Feature #4935]'
 | 
			
		||||
    x = 'world'
 | 
			
		||||
    hash = assert_nothing_raised(SyntaxError) do
 | 
			
		||||
      break eval(%q({foo: 1, "foo-bar": 2, "hello-#{x}": 3, 'hello-#{x}': 4}))
 | 
			
		||||
    end
 | 
			
		||||
    assert_equal({:foo => 1, :'foo-bar' => 2, :'hello-world' => 3, :'hello-#{x}' => 4}, hash)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  class TestSubHash < TestHash
 | 
			
		||||
    class SubHash < Hash
 | 
			
		||||
      def reject(*)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue