ruby-changes:24473
From: tenderlove <ko1@a...>
Date: Wed, 25 Jul 2012 03:11:23 +0900 (JST)
Subject: [ruby-changes:24473] tenderlove:r36524 (trunk): * parse.y: added symbols and qsymbols productions for %i and %I
tenderlove 2012-07-25 03:10:35 +0900 (Wed, 25 Jul 2012) New Revision: 36524 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=36524 Log: * parse.y: added symbols and qsymbols productions for %i and %I support. %i{ .. } returns a list of symbols without interpolation, %I{ .. } returns a list of symbols with interpolation. Thanks to Josh Susser for inspiration of this feature. [Feature #4985] * ext/ripper/eventids2.c: added ripper events for %i and %I. * test/ripper/test_parser_events.rb: ripper tests * test/ripper/test_scanner_events.rb: ditto * test/ruby/test_array.rb: test for %i and %I behavior Modified files: trunk/ChangeLog trunk/NEWS trunk/ext/ripper/eventids2.c trunk/parse.y trunk/test/ripper/test_parser_events.rb trunk/test/ripper/test_scanner_events.rb trunk/test/ruby/test_array.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 36523) +++ ChangeLog (revision 36524) @@ -1,3 +1,18 @@ +Wed Jul 25 03:05:06 2012 Aaron Patterson <aaron@t...> + + * parse.y: added symbols and qsymbols productions for %i and %I + support. %i{ .. } returns a list of symbols without interpolation, + %I{ .. } returns a list of symbols with interpolation. Thanks to + Josh Susser for inspiration of this feature. [Feature #4985] + + * ext/ripper/eventids2.c: added ripper events for %i and %I. + + * test/ripper/test_parser_events.rb: ripper tests + + * test/ripper/test_scanner_events.rb: ditto + + * test/ruby/test_array.rb: test for %i and %I behavior + Tue Jul 24 23:34:43 2012 Hiroshi Shirosaki <h.shirosaki@g...> * include/ruby/win32.h (rb_w32_pow): add new function. Index: parse.y =================================================================== --- parse.y (revision 36523) +++ parse.y (revision 36524) @@ -715,7 +715,7 @@ %type <node> singleton strings string string1 xstring regexp %type <node> string_contents xstring_contents regexp_contents string_content -%type <node> words qwords word_list qword_list word +%type <node> words symbols symbol_list qwords qsymbols word_list qword_list qsym_list word %type <node> literal numeric dsym cpath %type <node> top_compstmt top_stmts top_stmt %type <node> bodystmt compstmt stmts stmt_or_begin stmt expr arg primary command command_call method_call @@ -769,7 +769,7 @@ %token tDSTAR /* ** */ %token tAMPER /* & */ %token tLAMBDA /* -> */ -%token tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tWORDS_BEG tQWORDS_BEG +%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 /* @@ -2672,6 +2672,8 @@ | regexp | words | qwords + | symbols + | qsymbols | var_ref | backref | tFID @@ -4105,6 +4107,45 @@ } ; +symbols : tSYMBOLS_BEG ' ' tSTRING_END + { + /*%%%*/ + $$ = NEW_ZARRAY(); + /*% + $$ = dispatch0(symbols_new); + $$ = dispatch1(array, $$); + %*/ + } + | tSYMBOLS_BEG symbol_list tSTRING_END + { + /*%%%*/ + $$ = $2; + /*% + $$ = dispatch1(array, $2); + %*/ + } + ; + +symbol_list : /* none */ + { + /*%%%*/ + $$ = 0; + /*% + $$ = dispatch0(symbols_new); + %*/ + } + | symbol_list word ' ' + { + /*%%%*/ + $2 = evstr2dstr($2); + nd_set_type($2, NODE_DSYM); + $$ = list_append($1, $2); + /*% + $$ = dispatch2(symbols_add, $1, $2); + %*/ + } + ; + qwords : tQWORDS_BEG ' ' tSTRING_END { /*%%%*/ @@ -4124,6 +4165,25 @@ } ; +qsymbols : tQSYMBOLS_BEG ' ' tSTRING_END + { + /*%%%*/ + $$ = NEW_ZARRAY(); + /*% + $$ = dispatch0(qsymbols_new); + $$ = dispatch1(array, $$); + %*/ + } + | tQSYMBOLS_BEG qsym_list tSTRING_END + { + /*%%%*/ + $$ = $2; + /*% + $$ = dispatch1(array, $2); + %*/ + } + ; + qword_list : /* none */ { /*%%%*/ @@ -4142,6 +4202,28 @@ } ; +qsym_list : /* none */ + { + /*%%%*/ + $$ = 0; + /*% + $$ = dispatch0(qsymbols_new); + %*/ + } + | qsym_list tSTRING_CONTENT ' ' + { + /*%%%*/ + VALUE lit; + lit = $2->nd_lit; + $2->nd_lit = ID2SYM(rb_intern_str(lit)); + nd_set_type($2, NODE_LIT); + $$ = list_append($1, $2); + /*% + $$ = dispatch2(qsymbols_add, $1, $2); + %*/ + } + ; + string_contents : /* none */ { /*%%%*/ @@ -7796,6 +7878,18 @@ pushback(c); return tQWORDS_BEG; + case 'I': + lex_strterm = NEW_STRTERM(str_dword, term, paren); + do {c = nextc();} while (ISSPACE(c)); + pushback(c); + return tSYMBOLS_BEG; + + case 'i': + lex_strterm = NEW_STRTERM(str_sword, term, paren); + do {c = nextc();} while (ISSPACE(c)); + pushback(c); + return tQSYMBOLS_BEG; + case 'x': lex_strterm = NEW_STRTERM(str_xquote, term, paren); return tXSTRING_BEG; Index: ext/ripper/eventids2.c =================================================================== --- ext/ripper/eventids2.c (revision 36523) +++ ext/ripper/eventids2.c (revision 36524) @@ -38,6 +38,8 @@ static ID ripper_id_tstring_end; static ID ripper_id_words_beg; static ID ripper_id_qwords_beg; +static ID ripper_id_qsymbols_beg; +static ID ripper_id_symbols_beg; static ID ripper_id_words_sep; static ID ripper_id_regexp_beg; static ID ripper_id_regexp_end; @@ -91,6 +93,8 @@ ripper_id_tstring_end = rb_intern_const("on_tstring_end"); ripper_id_words_beg = rb_intern_const("on_words_beg"); ripper_id_qwords_beg = rb_intern_const("on_qwords_beg"); + ripper_id_qsymbols_beg = rb_intern_const("on_qsymbols_beg"); + ripper_id_symbols_beg = rb_intern_const("on_symbols_beg"); ripper_id_words_sep = rb_intern_const("on_words_sep"); ripper_id_regexp_beg = rb_intern_const("on_regexp_beg"); ripper_id_regexp_end = rb_intern_const("on_regexp_end"); @@ -228,6 +232,8 @@ {tOROP, &ripper_id_op}, {tPOW, &ripper_id_op}, {tQWORDS_BEG, &ripper_id_qwords_beg}, + {tQSYMBOLS_BEG, &ripper_id_qsymbols_beg}, + {tSYMBOLS_BEG, &ripper_id_symbols_beg}, {tREGEXP_BEG, &ripper_id_regexp_beg}, {tREGEXP_END, &ripper_id_regexp_end}, {tRPAREN, &ripper_id_rparen}, Index: NEWS =================================================================== --- NEWS (revision 36523) +++ NEWS (revision 36524) @@ -169,6 +169,9 @@ long. === Language changes + + * Added %i and %I for symbol list creation (similar to %w and %W). + === Compatibility issues (excluding feature bug fixes) * Signal.trap Index: test/ruby/test_array.rb =================================================================== --- test/ruby/test_array.rb (revision 36523) +++ test/ruby/test_array.rb (revision 36524) @@ -12,6 +12,17 @@ $VERBOSE = @verbose end + def test_percent_i + assert_equal([:foo, :bar], %i[foo bar]) + assert_equal([:"\"foo"], %i["foo]) + end + + def test_percent_I + x = 10 + assert_equal([:foo, :b10], %I[foo b#{x}]) + assert_equal([:"\"foo10"], %I["foo#{x}]) + end + def test_0_literal assert_equal([1, 2, 3, 4], [1, 2] + [3, 4]) assert_equal([1, 2, 1, 2], [1, 2] * 2) Index: test/ripper/test_parser_events.rb =================================================================== --- test/ripper/test_parser_events.rb (revision 36523) +++ test/ripper/test_parser_events.rb (revision 36524) @@ -755,12 +755,36 @@ assert_equal true, thru_qwords_add end + def test_qsymbols_add + thru_qsymbols_add = false + parse('%i[a]', :on_qsymbols_add) {thru_qsymbols_add = true} + assert_equal true, thru_qsymbols_add + end + + def test_symbols_add + thru_symbols_add = false + parse('%I[a]', :on_symbols_add) {thru_symbols_add = true} + assert_equal true, thru_symbols_add + end + def test_qwords_new thru_qwords_new = false parse('%w[]', :on_qwords_new) {thru_qwords_new = true} assert_equal true, thru_qwords_new end + def test_qsymbols_new + thru_qsymbols_new = false + parse('%i[]', :on_qsymbols_new) {thru_qsymbols_new = true} + assert_equal true, thru_qsymbols_new + end + + def test_symbols_new + thru_symbols_new = false + parse('%I[]', :on_symbols_new) {thru_symbols_new = true} + assert_equal true, thru_symbols_new + end + def test_redo thru_redo = false parse('redo', :on_redo) {thru_redo = true} Index: test/ripper/test_scanner_events.rb =================================================================== --- test/ripper/test_scanner_events.rb (revision 36523) +++ test/ripper/test_scanner_events.rb (revision 36524) @@ -608,6 +608,28 @@ scan('qwords_beg', '%w( w w w )') end + def test_qsymbols_beg + assert_equal [], + scan('qsymbols_beg', '') + assert_equal ['%i('], + scan('qsymbols_beg', '%i()') + assert_equal ['%i('], + scan('qsymbols_beg', '%i(w w w)') + assert_equal ['%i( '], + scan('qsymbols_beg', '%i( w w w )') + end + + def test_symbols_beg + assert_equal [], + scan('symbols_beg', '') + assert_equal ['%I('], + scan('symbols_beg', '%I()') + assert_equal ['%I('], + scan('symbols_beg', '%I(w w w)') + assert_equal ['%I( '], + scan('symbols_beg', '%I( w w w )') + end + # FIXME: Close paren must not present (`words_end' scanner event?). def test_words_sep assert_equal [], -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/