summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-compiler/core/parse.y
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2018-11-25 09:01:14 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2018-11-25 09:07:49 +0900
commit762f682b80460929d9c69b1957bcb2aad108ec93 (patch)
treeedc7d10dd061949ca605a3fac88148c6b0283256 /mrbgems/mruby-compiler/core/parse.y
parente6b72b2121b981c504f902723b3c1531be001c02 (diff)
downloadmruby-762f682b80460929d9c69b1957bcb2aad108ec93.tar.gz
mruby-762f682b80460929d9c69b1957bcb2aad108ec93.zip
Allow destructuring in formal arguments.
e.g. ``` def m(a,(b,c),d); p [a,b,c,d]; end m(1,[2,3],4) # => [1,2,3,4] ``` mruby limitation: Destructured arguments (`b` and `c` in above example) cannot be accessed from the default expression of optional arguments and keyword arguments, since actual assignment is done after the evaluation of those default expressions. Thus: ``` def f(a,(b,c),d=b) p [a,b,c,d] end f(1,[2,3]) ``` raises `NoMethodError` for `b` in mruby.
Diffstat (limited to 'mrbgems/mruby-compiler/core/parse.y')
-rw-r--r--mrbgems/mruby-compiler/core/parse.y31
1 files changed, 29 insertions, 2 deletions
diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y
index 1485fb086..d143344c3 100644
--- a/mrbgems/mruby-compiler/core/parse.y
+++ b/mrbgems/mruby-compiler/core/parse.y
@@ -682,6 +682,25 @@ new_arg(parser_state *p, mrb_sym sym)
return cons((node*)NODE_ARG, nsym(sym));
}
+static void
+local_add_margs(parser_state *p, node *n)
+{
+ while (n) {
+ if (n->car->car == (node*)NODE_MASGN) {
+ node *t = n->car->cdr->cdr;
+
+ n->car->cdr->cdr = NULL;
+ while (t) {
+ local_add_f(p, sym(t->car));
+ t = t->cdr;
+ }
+ local_add_margs(p, n->car->cdr->car->car);
+ local_add_margs(p, n->car->cdr->car->cdr->cdr->car);
+ }
+ n = n->cdr;
+ }
+}
+
/* (m o r m2 tail) */
/* m: (a b c) */
/* o: ((a . e1) (b . e2)) */
@@ -693,6 +712,8 @@ new_args(parser_state *p, node *m, node *opt, mrb_sym rest, node *m2, node *tail
{
node *n;
+ local_add_margs(p, m);
+ local_add_margs(p, m2);
n = cons(m2, tail);
n = cons(nsym(rest), n);
n = cons(opt, n);
@@ -3275,9 +3296,15 @@ f_arg_item : f_norm_arg
{
$$ = new_arg(p, $1);
}
- | tLPAREN f_margs rparen
+ | tLPAREN
+ {
+ $<nd>$ = local_switch(p);
+ }
+ f_margs rparen
{
- $$ = new_masgn(p, $2, 0);
+ $$ = new_masgn(p, $3, p->locals->car);
+ local_resume(p, $<nd>2);
+ local_add_f(p, 0);
}
;