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

ruby-changes:49753

From: mame <ko1@a...>
Date: Tue, 16 Jan 2018 16:24:59 +0900 (JST)
Subject: [ruby-changes:49753] mame:r61871 (trunk): node.c: Stop double meaning of NODE_FOR by introducing NODE_FOR_MASGN

mame	2018-01-16 16:24:53 +0900 (Tue, 16 Jan 2018)

  New Revision: 61871

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=61871

  Log:
    node.c: Stop double meaning of NODE_FOR by introducing NODE_FOR_MASGN
    
    NODE_FOR was used both for "for"-statement itself and for
    multi-assignment of for-statement (for x, y, in...end).
    This change separates the two purposes, NODE_FOR for the former, and
    newly introduced NODE_FOR_MASGN for the latter.

  Modified files:
    trunk/compile.c
    trunk/ext/-test-/ast/ast.c
    trunk/ext/objspace/objspace.c
    trunk/node.c
    trunk/node.h
    trunk/parse.y
Index: compile.c
===================================================================
--- compile.c	(revision 61870)
+++ compile.c	(revision 61871)
@@ -5019,38 +5019,33 @@ compile_iter(rb_iseq_t *iseq, LINK_ANCHO https://github.com/ruby/ruby/blob/trunk/compile.c#L5019
 }
 
 static int
-compile_for(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped)
+compile_for_masgn(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped)
 {
+    /* massign to var in "for"
+     * args.length == 1 && Array === (tmp = args[0]) ? tmp : args
+     */
     const int line = nd_line(node);
-    if (node->nd_var) {
-	/* massign to var in "for"
-	 * args.length == 1 && Array === (tmp = args[0]) ? tmp : args
-	 */
-	const NODE *var = node->nd_var;
-	LABEL *not_single = NEW_LABEL(nd_line(var));
-	LABEL *not_ary = NEW_LABEL(nd_line(var));
-	CHECK(COMPILE(ret, "for var", var));
-	ADD_INSN(ret, line, dup);
-	ADD_CALL(ret, line, idLength, INT2FIX(0));
-	ADD_INSN1(ret, line, putobject, INT2FIX(1));
-	ADD_CALL(ret, line, idEq, INT2FIX(1));
-	ADD_INSNL(ret, line, branchunless, not_single);
-	ADD_INSN(ret, line, dup);
-	ADD_INSN1(ret, line, putobject, INT2FIX(0));
-	ADD_CALL(ret, line, idAREF, INT2FIX(1));
-	ADD_INSN1(ret, line, putobject, rb_cArray);
-	ADD_INSN1(ret, line, topn, INT2FIX(1));
-	ADD_CALL(ret, line, idEqq, INT2FIX(1));
-	ADD_INSNL(ret, line, branchunless, not_ary);
-	ADD_INSN(ret, line, swap);
-	ADD_LABEL(ret, not_ary);
-	ADD_INSN(ret, line, pop);
-	ADD_LABEL(ret, not_single);
-	return COMPILE_OK;
-    }
-    else {
-	return compile_iter(iseq, ret, node, popped);
-    }
+    const NODE *var = node->nd_var;
+    LABEL *not_single = NEW_LABEL(nd_line(var));
+    LABEL *not_ary = NEW_LABEL(nd_line(var));
+    CHECK(COMPILE(ret, "for var", var));
+    ADD_INSN(ret, line, dup);
+    ADD_CALL(ret, line, idLength, INT2FIX(0));
+    ADD_INSN1(ret, line, putobject, INT2FIX(1));
+    ADD_CALL(ret, line, idEq, INT2FIX(1));
+    ADD_INSNL(ret, line, branchunless, not_single);
+    ADD_INSN(ret, line, dup);
+    ADD_INSN1(ret, line, putobject, INT2FIX(0));
+    ADD_CALL(ret, line, idAREF, INT2FIX(1));
+    ADD_INSN1(ret, line, putobject, rb_cArray);
+    ADD_INSN1(ret, line, topn, INT2FIX(1));
+    ADD_CALL(ret, line, idEqq, INT2FIX(1));
+    ADD_INSNL(ret, line, branchunless, not_ary);
+    ADD_INSN(ret, line, swap);
+    ADD_LABEL(ret, not_ary);
+    ADD_INSN(ret, line, pop);
+    ADD_LABEL(ret, not_single);
+    return COMPILE_OK;
 }
 
 static int
@@ -5560,11 +5555,12 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK https://github.com/ruby/ruby/blob/trunk/compile.c#L5555
 	CHECK(compile_loop(iseq, ret, node, popped, type));
 	break;
       case NODE_FOR:
-	CHECK(compile_for(iseq, ret, node, popped));
-	break;
       case NODE_ITER:
 	CHECK(compile_iter(iseq, ret, node, popped));
 	break;
+      case NODE_FOR_MASGN:
+	CHECK(compile_for_masgn(iseq, ret, node, popped));
+	break;
       case NODE_BREAK:
 	CHECK(compile_break(iseq, ret, node, popped));
 	break;
Index: parse.y
===================================================================
--- parse.y	(revision 61870)
+++ parse.y	(revision 61871)
@@ -2580,7 +2580,7 @@ primary		: literal https://github.com/ruby/ruby/blob/trunk/parse.y#L2580
 
 			switch (nd_type($2)) {
 			  case NODE_MASGN:
-			    m->nd_next = node_assign(p, $2, NEW_FOR(NEW_DVAR(id, &@2), 0, 0, &@2), &@2);
+			    m->nd_next = node_assign(p, $2, NEW_FOR_MASGN(NEW_DVAR(id, &@2), &@2), &@2);
 			    args = new_args(p, m, 0, id, 0, new_args_tail(p, 0, 0, 0, &@2), &@2);
 			    break;
 			  case NODE_LASGN:
@@ -2602,7 +2602,7 @@ primary		: literal https://github.com/ruby/ruby/blob/trunk/parse.y#L2602
 			add_mark_object(p, (VALUE)rb_imemo_alloc_new((VALUE)tbl, 0, 0, 0));
 			scope = NEW_NODE(NODE_SCOPE, tbl, $5, args, &@$);
 			tbl[0] = 1; tbl[1] = id;
-			$$ = NEW_FOR(0, $4, scope, &@$);
+			$$ = NEW_FOR($4, scope, &@$);
 			fixpos($$, $2);
 		    /*%
 			$$ = dispatch3(for, $2, $4, $5);
Index: ext/objspace/objspace.c
===================================================================
--- ext/objspace/objspace.c	(revision 61870)
+++ ext/objspace/objspace.c	(revision 61871)
@@ -382,6 +382,7 @@ count_nodes(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace.c#L382
 		COUNT_NODE(NODE_UNTIL);
 		COUNT_NODE(NODE_ITER);
 		COUNT_NODE(NODE_FOR);
+		COUNT_NODE(NODE_FOR_MASGN);
 		COUNT_NODE(NODE_BREAK);
 		COUNT_NODE(NODE_NEXT);
 		COUNT_NODE(NODE_REDO);
Index: ext/-test-/ast/ast.c
===================================================================
--- ext/-test-/ast/ast.c	(revision 61870)
+++ ext/-test-/ast/ast.c	(revision 61871)
@@ -198,10 +198,10 @@ node_children(rb_ast_t *ast, NODE *node) https://github.com/ruby/ruby/blob/trunk/ext/-test-/ast/ast.c#L198
       loop:
 	return rb_ary_new_from_node_args(ast, 2, node->nd_cond, node->nd_body);
       case NODE_ITER:
-	goto iter;
       case NODE_FOR:
-      iter:
 	return rb_ary_new_from_node_args(ast, 2, node->nd_iter, node->nd_body);
+      case NODE_FOR_MASGN:
+	return rb_ary_new_from_node_args(ast, 1, node->nd_var);
       case NODE_BREAK:
 	goto jump;
       case NODE_NEXT:
Index: node.c
===================================================================
--- node.c	(revision 61870)
+++ node.c	(revision 61871)
@@ -240,6 +240,14 @@ dump_node(VALUE buf, VALUE indent, int c https://github.com/ruby/ruby/blob/trunk/node.c#L240
 	F_NODE(nd_body, "body");
 	return;
 
+      case NODE_FOR_MASGN:
+	ANN("vars of for statement with masgn");
+	ANN("format: for [nd_var] in ... do ... end");
+	ANN("example: for x, y in 1..3 do foo end");
+	LAST_NODE;
+	F_NODE(nd_var, "var");
+	return;
+
       case NODE_BREAK:
 	ANN("break statement");
 	ANN("format: break [nd_stts]");
Index: node.h
===================================================================
--- node.h	(revision 61870)
+++ node.h	(revision 61871)
@@ -42,6 +42,8 @@ enum node_type { https://github.com/ruby/ruby/blob/trunk/node.h#L42
 #define NODE_ITER        NODE_ITER
     NODE_FOR,
 #define NODE_FOR         NODE_FOR
+    NODE_FOR_MASGN,
+#define NODE_FOR_MASGN   NODE_FOR_MASGN
     NODE_BREAK,
 #define NODE_BREAK       NODE_BREAK
     NODE_NEXT,
@@ -382,7 +384,8 @@ typedef struct RNode { https://github.com/ruby/ruby/blob/trunk/node.h#L384
 #define NEW_WHEN(c,t,e,loc) NEW_NODE(NODE_WHEN,c,t,e,loc)
 #define NEW_WHILE(c,b,n,loc) NEW_NODE(NODE_WHILE,c,b,n,loc)
 #define NEW_UNTIL(c,b,n,loc) NEW_NODE(NODE_UNTIL,c,b,n,loc)
-#define NEW_FOR(v,i,b,loc) NEW_NODE(NODE_FOR,v,b,i,loc)
+#define NEW_FOR(i,b,loc) NEW_NODE(NODE_FOR,0,b,i,loc)
+#define NEW_FOR_MASGN(v,loc) NEW_NODE(NODE_FOR_MASGN,v,0,0,loc)
 #define NEW_ITER(a,b,loc) NEW_NODE(NODE_ITER,0,NEW_SCOPE(a,b,loc),0,loc)
 #define NEW_LAMBDA(a,b,loc) NEW_NODE(NODE_LAMBDA,0,NEW_SCOPE(a,b,loc),0,loc)
 #define NEW_BREAK(s,loc) NEW_NODE(NODE_BREAK,s,0,0,loc)

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

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