[前][次][番号順一覧][スレッド一覧]

ruby-changes:60720

From: Nobuyoshi <ko1@a...>
Date: Fri, 10 Apr 2020 16:11:09 +0900 (JST)
Subject: [ruby-changes:60720] 1b2d351b21 (master): Rightward-assign by ASSOC

https://git.ruby-lang.org/ruby.git/commit/?id=1b2d351b21

From 1b2d351b216661e03d497dfdce216e0d51474664 Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Tue, 11 Jun 2019 22:57:33 +0900
Subject: Rightward-assign by ASSOC

[Feature #15921]

diff --git a/NEWS.md b/NEWS.md
index 7003c33..d3ca3d9 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -38,6 +38,12 @@ sufficient information, see the ChangeLog file or Redmine https://github.com/ruby/ruby/blob/trunk/NEWS.md#L38
   instead of a warning. yield in a class definition outside of a method
   is now a SyntaxError instead of a LocalJumpError.  [[Feature #15575]]
 
+* Rightward assignment statement is added. [[Feature #15921]]
+
+    ```ruby
+    fib(10) => x
+    ```
+
 ## Command line options
 
 ## Core classes updates
@@ -170,5 +176,6 @@ Excluding feature bug fixes. https://github.com/ruby/ruby/blob/trunk/NEWS.md#L176
 [Feature #16274]: https://bugs.ruby-lang.org/issues/16274
 [Feature #16377]: https://bugs.ruby-lang.org/issues/16377
 [Bug #12706]:     https://bugs.ruby-lang.org/issues/12706
+[Feature #15921]: https://bugs.ruby-lang.org/issues/15921
 [Feature #16555]: https://bugs.ruby-lang.org/issues/16555
 [GH-2991]:        https://github.com/ruby/ruby/pull/2991
diff --git a/parse.y b/parse.y
index 10976f7..1c5ee84 100644
--- a/parse.y
+++ b/parse.y
@@ -1083,7 +1083,7 @@ static int looking_at_eol_p(struct parser_params *p); https://github.com/ruby/ruby/blob/trunk/parse.y#L1083
 %type <node> string_contents xstring_contents regexp_contents string_content
 %type <node> words symbols symbol_list qwords qsymbols word_list qword_list qsym_list word
 %type <node> literal numeric simple_numeric ssym dsym symbol cpath
-%type <node> top_compstmt top_stmts top_stmt begin_block
+%type <node> top_compstmt top_stmts top_stmt begin_block rassign
 %type <node> bodystmt compstmt stmts stmt_or_begin stmt expr arg primary command command_call method_call
 %type <node> expr_value expr_value_do arg_value primary_value fcall rel_expr
 %type <node> if_tail opt_else case_body case_args cases opt_rescue exc_list exc_var opt_ensure
@@ -1481,9 +1481,44 @@ stmt		: keyword_alias fitem {SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);} fitem https://github.com/ruby/ruby/blob/trunk/parse.y#L1481
 		    /*% %*/
 		    /*% ripper: massign!($1, $3) %*/
 		    }
+		| rassign
 		| expr
 		;
 
+rassign 	: primary tASSOC lhs
+		    {
+		    /*%%%*/
+			value_expr($1);
+			$$ = node_assign(p, $3, $1, &@$);
+		    /*% %*/
+		    /*% ripper: assign!($3, $1) %*/
+		    }
+		| primary tASSOC mlhs
+		    {
+		    /*%%%*/
+			value_expr($1);
+			$$ = node_assign(p, $3, $1, &@$);
+		    /*% %*/
+		    /*% ripper: massign!($3, $1) %*/
+		    }
+		| rassign tASSOC lhs
+		    {
+		    /*%%%*/
+			value_expr($1);
+			$$ = node_assign(p, $3, $1, &@$);
+		    /*% %*/
+		    /*% ripper: assign!($3, $1) %*/
+		    }
+		| rassign tASSOC mlhs
+		    {
+		    /*%%%*/
+			value_expr($1);
+			$$ = node_assign(p, $3, $1, &@$);
+		    /*% %*/
+		    /*% ripper: massign!($3, $1) %*/
+		    }
+		;
+
 command_asgn	: lhs '=' command_rhs
 		    {
 		    /*%%%*/
@@ -8866,10 +8901,11 @@ parser_yylex(struct parser_params *p) https://github.com/ruby/ruby/blob/trunk/parse.y#L8901
 		pushback(p, c);
 		if (space_seen) dispatch_scan_event(p, tSP);
 		goto retry;
+	      case '=':
 	      case '&':
 	      case '.': {
 		dispatch_delayed_token(p, tIGNORED_NL);
-		if (peek(p, '.') == (c == '&')) {
+		if (c == '=' ? peek(p, '>') : (peek(p, '.') == (c == '&'))) {
 		    pushback(p, c);
 		    dispatch_scan_event(p, tSP);
 		    goto retry;
diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb
index a0c2bf6..04e98ec 100644
--- a/test/ruby/test_syntax.rb
+++ b/test/ruby/test_syntax.rb
@@ -1559,6 +1559,13 @@ eom https://github.com/ruby/ruby/blob/trunk/test/ruby/test_syntax.rb#L1559
     end
   end
 
+  def test_rightward_assign
+    assert_equal(1, eval("1 => a"))
+    assert_equal([2,3], eval("13.divmod(5) => a,b; [a, b]"))
+    assert_equal([2,3,2,3], eval("13.divmod(5) => a,b => c, d; [a, b, c, d]"))
+    assert_equal([2,3], eval("13.divmod(5)\n => a,b; [a, b]"))
+  end
+
   private
 
   def not_label(x) @result = x; @not_label ||= nil end
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]