summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2019-10-03 07:52:31 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2019-10-03 07:52:31 +0900
commit47cdda370e55debe40d72c21fa520e32a3d00ac2 (patch)
tree9b39f4d177629e6d370f8a983a9f30f60cf1287d
parent306f02117b81620568548172bfc8ec85e1c653a2 (diff)
downloadmruby-47cdda370e55debe40d72c21fa520e32a3d00ac2.tar.gz
mruby-47cdda370e55debe40d72c21fa520e32a3d00ac2.zip
Need to reorder local variables defined in `opt`; fix #4746
For example, local variables in the following def: ```ruby def foo(a = (not_set = true), &block) ... end ``` should be `a, block, not_set`, but were `a, not_set, block`.
-rw-r--r--mrbgems/mruby-compiler/core/parse.y17
1 files changed, 15 insertions, 2 deletions
diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y
index 4abe1c506..f7ae3913f 100644
--- a/mrbgems/mruby-compiler/core/parse.y
+++ b/mrbgems/mruby-compiler/core/parse.y
@@ -763,6 +763,16 @@ new_args(parser_state *p, node *m, node *opt, mrb_sym rest, node *m2, node *tail
n = cons(m2, tail);
n = cons(nsym(rest), n);
n = cons(opt, n);
+ while (opt) {
+ /* opt: (sym . (opt . lv)) -> (sym . opt) */
+ node *lv = opt->car->cdr->cdr;
+ while (lv) {
+ local_add_f(p, sym(lv->car));
+ lv = lv->cdr;
+ }
+ opt->car->cdr = opt->car->cdr->car;
+ opt = opt->cdr;
+ }
return cons(m, n);
}
@@ -3502,6 +3512,7 @@ f_arg : f_arg_item
f_opt_asgn : tIDENTIFIER '='
{
local_add_f(p, $1);
+ local_nest(p);
$$ = $1;
}
;
@@ -3509,14 +3520,16 @@ f_opt_asgn : tIDENTIFIER '='
f_opt : f_opt_asgn arg
{
void_expr_error(p, $2);
- $$ = cons(nsym($1), $2);
+ $$ = cons(nsym($1), cons($2, locals_node(p)));
+ local_unnest(p);
}
;
f_block_opt : f_opt_asgn primary_value
{
void_expr_error(p, $2);
- $$ = cons(nsym($1), $2);
+ $$ = cons(nsym($1), cons($2, locals_node(p)));
+ local_unnest(p);
}
;