summaryrefslogtreecommitdiff
path: root/parse.y
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-09-06 18:39:36 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-09-06 18:39:36 +0000
commit929e0b91be4ddf58b5d0791f538862a872203f93 (patch)
tree876cf927985459d507eb71e3325d00692290f957 /parse.y
parent04d3593b26ccf65e930bebbc6e47cc37bfd557bd (diff)
* parse.y (f_block_optarg): allow default for block parameters as
long as the value is primary. a patch from Eric Mahurin <eric.mahurin at gmail.com> in [ruby-core:16880]. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19199 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'parse.y')
-rw-r--r--parse.y105
1 files changed, 104 insertions, 1 deletions
diff --git a/parse.y b/parse.y
index e6bff49538..eab982b75f 100644
--- a/parse.y
+++ b/parse.y
@@ -673,6 +673,7 @@ static void token_info_pop(struct parser_params*, const char *token);
%type <node> paren_args opt_paren_args
%type <node> command_args aref_args opt_block_arg block_arg var_ref var_lhs
%type <node> mrhs superclass block_call block_command
+%type <node> f_block_optarg f_block_opt
%type <node> f_arglist f_args f_arg f_arg_item f_optarg f_marg f_marg_list f_margs
%type <node> assoc_list assocs assoc undef_list backref string_dvar for_var
%type <node> block_param opt_block_param block_param_def f_opt
@@ -3206,7 +3207,39 @@ f_margs : f_marg_list
}
;
-block_param : f_arg ',' f_rest_arg opt_f_block_arg
+block_param : f_arg ',' f_block_optarg ',' f_rest_arg opt_f_block_arg
+ {
+ /*%%%*/
+ $$ = new_args($1, $3, $5, 0, $6);
+ /*%
+ $$ = params_new($1, $3, $5, Qnil, escape_Qundef($6));
+ %*/
+ }
+ | f_arg ',' f_block_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg
+ {
+ /*%%%*/
+ $$ = new_args($1, $3, $5, $7, $8);
+ /*%
+ $$ = params_new($1, $3, $5, $7, escape_Qundef($8));
+ %*/
+ }
+ | f_arg ',' f_block_optarg opt_f_block_arg
+ {
+ /*%%%*/
+ $$ = new_args($1, $3, 0, 0, $4);
+ /*%
+ $$ = params_new($1, $3, Qnil, Qnil, escape_Qundef($4));
+ %*/
+ }
+ | f_arg ',' f_block_optarg ',' f_arg opt_f_block_arg
+ {
+ /*%%%*/
+ $$ = new_args($1, $3, 0, $5, $6);
+ /*%
+ $$ = params_new($1, $3, Qnil, $5, escape_Qundef($6));
+ %*/
+ }
+ | f_arg ',' f_rest_arg opt_f_block_arg
{
/*%%%*/
$$ = new_args($1, 0, $3, 0, $4);
@@ -3239,6 +3272,38 @@ block_param : f_arg ',' f_rest_arg opt_f_block_arg
$$ = params_new($1, Qnil,Qnil, Qnil, escape_Qundef($2));
%*/
}
+ | f_block_optarg ',' f_rest_arg opt_f_block_arg
+ {
+ /*%%%*/
+ $$ = new_args(0, $1, $3, 0, $4);
+ /*%
+ $$ = params_new(Qnil, $1, $3, Qnil, escape_Qundef($4));
+ %*/
+ }
+ | f_block_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg
+ {
+ /*%%%*/
+ $$ = new_args(0, $1, $3, $5, $6);
+ /*%
+ $$ = params_new(Qnil, $1, $3, $5, escape_Qundef($6));
+ %*/
+ }
+ | f_block_optarg opt_f_block_arg
+ {
+ /*%%%*/
+ $$ = new_args(0, $1, 0, 0, $2);
+ /*%
+ $$ = params_new(Qnil, $1, Qnil, Qnil,escape_Qundef($2));
+ %*/
+ }
+ | f_block_optarg ',' f_arg opt_f_block_arg
+ {
+ /*%%%*/
+ $$ = new_args(0, $1, 0, $3, $4);
+ /*%
+ $$ = params_new(Qnil, $1, Qnil, $3, escape_Qundef($4));
+ %*/
+ }
| f_rest_arg opt_f_block_arg
{
/*%%%*/
@@ -4339,6 +4404,44 @@ f_opt : tIDENTIFIER '=' arg_value
}
;
+f_block_opt : tIDENTIFIER '=' primary_value
+ {
+ /*%%%*/
+ if (!is_local_id($1))
+ yyerror("formal argument must be local variable");
+ shadowing_lvar($1);
+ arg_var($1);
+ $$ = NEW_OPT_ARG(0, assignable($1, $3));
+ /*%
+ $$ = rb_assoc_new($1, $3);
+ %*/
+ }
+ ;
+
+f_block_optarg : f_block_opt
+ {
+ /*%%%*/
+ $$ = $1;
+ /*%
+ $$ = rb_ary_new3(1, $1);
+ %*/
+ }
+ | f_block_optarg ',' f_block_opt
+ {
+ /*%%%*/
+ NODE *opts = $1;
+
+ while (opts->nd_next) {
+ opts = opts->nd_next;
+ }
+ opts->nd_next = $3;
+ $$ = $1;
+ /*%
+ $$ = rb_ary_push($1, $3);
+ %*/
+ }
+ ;
+
f_optarg : f_opt
{
/*%%%*/