Project

General

Profile

Feature #6070 » for_loop_scope_fix_2.diff

shugo (Shugo Maeda), 02/24/2012 02:25 PM

View differences:

parse.y
ID id;
int num;
const struct vtable *vars;
struct local_vars *local;
}
/*%%%*/
......
$$ = dispatch2(case, Qnil, $3);
%*/
}
| k_for for_var keyword_in
{COND_PUSH(1);}
| k_for
{
$<vars>1 = dyna_push();
/*%%%*/
$<num>$ = ruby_sourceline;
/*%
%*/
}
block_param keyword_in
{
COND_PUSH(1);
$<local>$ = ALLOC(struct local_vars);
memcpy($<local>$, lvtbl, sizeof(struct local_vars));
lvtbl->args = lvtbl->args->prev;
lvtbl->vars = lvtbl->vars->prev;
if (lvtbl->used) {
lvtbl->used = lvtbl->used->prev;
}
}
expr_value do
{COND_POP();}
{
memcpy(lvtbl, $<local>5, sizeof(struct local_vars));
xfree($<local>5);
COND_POP();
}
compstmt
k_end
{
......
* #=>
* e.each{|x| a, = x}
*/
ID id = internal_id();
ID *tbl = ALLOC_N(ID, 2);
NODE *m = NEW_ARGS_AUX(0, 0);
NODE *args, *scope;
if (nd_type($2) == NODE_MASGN) {
/* if args.length == 1 && args[0].kind_of?(Array)
* args = args[0]
* end
*/
NODE *one = NEW_LIST(NEW_LIT(INT2FIX(1)));
NODE *zero = NEW_LIST(NEW_LIT(INT2FIX(0)));
m->nd_next = block_append(
NEW_IF(
NEW_NODE(NODE_AND,
NEW_CALL(NEW_CALL(NEW_DVAR(id), rb_intern("length"), 0),
rb_intern("=="), one),
NEW_CALL(NEW_CALL(NEW_DVAR(id), rb_intern("[]"), zero),
rb_intern("kind_of?"), NEW_LIST(NEW_LIT(rb_cArray))),
0),
NEW_DASGN_CURR(id,
NEW_CALL(NEW_DVAR(id), rb_intern("[]"), zero)),
0),
node_assign($2, NEW_DVAR(id)));
args = new_args(m, 0, id, 0, 0, 0, 0);
}
else {
if (nd_type($2) == NODE_LASGN ||
nd_type($2) == NODE_DASGN ||
nd_type($2) == NODE_DASGN_CURR) {
$2->nd_value = NEW_DVAR(id);
m->nd_plen = 1;
m->nd_next = $2;
args = new_args(m, 0, 0, 0, 0, 0, 0);
}
else {
m->nd_next = node_assign(NEW_MASGN(NEW_LIST($2), 0), NEW_DVAR(id));
args = new_args(m, 0, id, 0, 0, 0, 0);
}
}
scope = NEW_NODE(NODE_SCOPE, tbl, $8, args);
tbl[0] = 1; tbl[1] = id;
$$ = NEW_FOR(0, $5, scope);
fixpos($$, $2);
$$ = NEW_ITER($3, $9);
$$->nd_iter = NEW_CALL($6, rb_intern("each"), 0);
/* fixpos($$, $3); */
nd_set_line($$, $<num>2);
/*%
$$ = dispatch3(for, $2, $5, $8);
$$ = dispatch3(for, $3, $6, $9);
%*/
dyna_pop($<vars>1);
}
| k_class cpath superclass
{
(2-2/4)