зеркало из https://github.com/github/ruby.git
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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61871 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
56524df980
Коммит
4b6f3bce25
60
compile.c
60
compile.c
|
@ -5019,38 +5019,33 @@ compile_iter(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in
|
|||
}
|
||||
|
||||
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_ANCHOR *const ret, const NODE *node, in
|
|||
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;
|
||||
|
|
|
@ -198,10 +198,10 @@ node_children(rb_ast_t *ast, NODE *node)
|
|||
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:
|
||||
|
|
|
@ -382,6 +382,7 @@ count_nodes(int argc, VALUE *argv, VALUE os)
|
|||
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);
|
||||
|
|
8
node.c
8
node.c
|
@ -240,6 +240,14 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node)
|
|||
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]");
|
||||
|
|
5
node.h
5
node.h
|
@ -42,6 +42,8 @@ enum node_type {
|
|||
#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 {
|
|||
#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)
|
||||
|
|
4
parse.y
4
parse.y
|
@ -2580,7 +2580,7 @@ primary : literal
|
|||
|
||||
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
|
|||
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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче