summaryrefslogtreecommitdiff
path: root/parse.y
diff options
context:
space:
mode:
authornagachika <nagachika@ruby-lang.org>2020-12-31 15:19:16 +0900
committernagachika <nagachika@ruby-lang.org>2020-12-31 15:19:16 +0900
commit27fca66207f2c35f2f44f6a7cbbe6fd153546082 (patch)
treefe095cf3096a4c60fc429726b69c85c4ceec1d5e /parse.y
parente249f37f24ffa207a5e67f85306f3266aff18429 (diff)
Add leading arguments support to arguments forwarding
Implements [Feature #16378]
Diffstat (limited to 'parse.y')
-rw-r--r--parse.y41
1 files changed, 41 insertions, 0 deletions
diff --git a/parse.y b/parse.y
index 0fd0c46114..f3522a8215 100644
--- a/parse.y
+++ b/parse.y
@@ -2418,6 +2418,32 @@ paren_args : '(' opt_call_args rparen
/*% %*/
/*% ripper: arg_paren!(escape_Qundef($2)) %*/
}
+ | '(' args ',' args_forward rparen
+ {
+ if (!local_id(p, idFWD_REST) ||
+#if idFWD_KWREST
+ !local_id(p, idFWD_KWREST) ||
+#endif
+ !local_id(p, idFWD_BLOCK)) {
+ compile_error(p, "unexpected ...");
+ $$ = Qnone;
+ }
+ else {
+ /*%%%*/
+ NODE *splat = NEW_SPLAT(NEW_LVAR(idFWD_REST, &@4), &@4);
+#if idFWD_KWREST
+ NODE *kwrest = list_append(p, NEW_LIST(0, &@4), NEW_LVAR(idFWD_KWREST, &@4));
+#endif
+ NODE *block = NEW_BLOCK_PASS(NEW_LVAR(idFWD_BLOCK, &@4), &@4);
+ $$ = rest_arg_append(p, $2, splat, &@$);
+#if idFWD_KWREST
+ $$ = arg_append(p, $$, new_hash(p, kwrest, &@4), &@4);
+#endif
+ $$ = arg_blk_pass($$, block);
+ /*% %*/
+ /*% ripper: arg_paren!(args_add!($2, $4)) %*/
+ }
+ }
| '(' args_forward rparen
{
if (!local_id(p, idFWD_REST) ||
@@ -4818,6 +4844,21 @@ f_arglist : '(' f_args rparen
SET_LEX_STATE(EXPR_BEG);
p->command_start = TRUE;
}
+ | '(' f_arg ',' args_forward rparen
+ {
+ arg_var(p, idFWD_REST);
+#if idFWD_KWREST
+ arg_var(p, idFWD_KWREST);
+#endif
+ arg_var(p, idFWD_BLOCK);
+ /*%%%*/
+ $$ = new_args_tail(p, Qnone, idFWD_KWREST, idFWD_BLOCK, &@4);
+ $$ = new_args(p, $2, Qnone, idFWD_REST, Qnone, $$, &@4);
+ /*% %*/
+ /*% ripper: paren!(params_new($2, Qnone, $4, Qnone, Qnone, Qnone, Qnone)) %*/
+ SET_LEX_STATE(EXPR_BEG);
+ p->command_start = TRUE;
+ }
| '(' args_forward rparen
{
arg_var(p, idFWD_REST);