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/