1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

parse.y: numbered parameter in lambda

* parse.y (lambda): support numbered parameters, only when no
  argument list including empty parentheses, like empty vertical
  bars.  [ruby-core:91859] [Bug #15672]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67295 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2019-03-18 12:48:18 +00:00
parent f9e5b8d09c
commit 964bbc1686
2 changed files with 33 additions and 5 deletions

34
parse.y
View file

@ -414,6 +414,7 @@ static NODE *new_qcall(struct parser_params* p, ID atype, NODE *recv, ID mid, NO
static NODE *new_command_qcall(struct parser_params* p, ID atype, NODE *recv, ID mid, NODE *args, NODE *block, const YYLTYPE *op_loc, const YYLTYPE *loc);
static NODE *method_add_block(struct parser_params*p, NODE *m, NODE *b, const YYLTYPE *loc) {b->nd_iter = m; b->nd_loc = *loc; return b;}
static bool args_info_empty_p(struct rb_args_info *args);
static NODE *new_args(struct parser_params*,NODE*,NODE*,ID,NODE*,NODE*,const YYLTYPE*);
static NODE *new_args_tail(struct parser_params*,NODE*,ID,ID,const YYLTYPE*);
static NODE *new_kw_arg(struct parser_params *p, NODE *k, const YYLTYPE *loc);
@ -3186,23 +3187,29 @@ lambda : {
$<num>$ = p->lex.lpar_beg;
p->lex.lpar_beg = p->lex.paren_nest;
}
{
$<num>$ = p->max_numparam;
}
f_larglist
{
CMDARG_PUSH(0);
}
lambda_body
{
int max_numparam = p->max_numparam;
p->lex.lpar_beg = $<num>2;
p->max_numparam = $<num>3;
CMDARG_POP();
$4 = args_with_numbered(p, $4, max_numparam);
/*%%%*/
{
YYLTYPE loc = code_loc_gen(&@3, &@5);
$$ = NEW_LAMBDA($3, $5, &loc);
nd_set_line($$->nd_body, @5.end_pos.lineno);
nd_set_line($$, @3.end_pos.lineno);
YYLTYPE loc = code_loc_gen(&@4, &@6);
$$ = NEW_LAMBDA($4, $6, &loc);
nd_set_line($$->nd_body, @6.end_pos.lineno);
nd_set_line($$, @4.end_pos.lineno);
}
/*% %*/
/*% ripper: lambda!($3, $5) %*/
/*% ripper: lambda!($4, $6) %*/
dyna_pop(p, $<vars>1);
}
;
@ -3211,11 +3218,16 @@ f_larglist : '(' f_args opt_bv_decl ')'
{
/*%%%*/
$$ = $2;
p->max_numparam = -1;
/*% %*/
/*% ripper: paren!($2) %*/
}
| f_args
{
/*%%%*/
if (!args_info_empty_p($1->nd_ainfo))
p->max_numparam = -1;
/*% %*/
$$ = $1;
}
;
@ -10253,6 +10265,18 @@ arg_blk_pass(NODE *node1, NODE *node2)
return node1;
}
static bool
args_info_empty_p(struct rb_args_info *args)
{
if (args->pre_args_num) return false;
if (args->post_args_num) return false;
if (args->rest_arg) return false;
if (args->opt_args) return false;
if (args->block_arg) return false;
if (args->kw_args) return false;
if (args->kw_rest_arg) return false;
return true;
}
static NODE*
new_args(struct parser_params *p, NODE *pre_args, NODE *opt_args, ID rest_arg, NODE *post_args, NODE *tail, const YYLTYPE *loc)

View file

@ -1295,8 +1295,12 @@ eom
assert_valid_syntax('proc {@1}')
assert_equal(3, eval('[1,2].then {@1+@2}'))
assert_equal("12", eval('[1,2].then {"#@1#@2"}'))
assert_equal(3, eval('->{@1+@2}.call(1,2)'))
assert_syntax_error('proc {|| @1}', /ordinary parameter is defined/)
assert_syntax_error('proc {|x| @1}', /ordinary parameter is defined/)
assert_syntax_error('->(){@1}', /ordinary parameter is defined/)
assert_syntax_error('->(x){@1}', /ordinary parameter is defined/)
assert_syntax_error('->x{@1}', /ordinary parameter is defined/)
assert_syntax_error('proc {@1 = nil}', /Can't assign to numbered parameter @1/)
assert_syntax_error('proc {@01}', /leading zero/)
assert_syntax_error('proc {@1_}', /unexpected/)