From c29212cf44e728a47d306bf9a25a9d8d8317a4f9 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 24 Apr 2020 15:54:27 +0900 Subject: Implement endless-def as in CRuby [Feature#16746]. --- mrbgems/mruby-compiler/core/parse.y | 117 ++++++++++++++++++++++++------------ 1 file changed, 80 insertions(+), 37 deletions(-) diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y index 73e928b20..83b9ad422 100644 --- a/mrbgems/mruby-compiler/core/parse.y +++ b/mrbgems/mruby-compiler/core/parse.y @@ -730,7 +730,19 @@ new_module(parser_state *p, node *m, node *b) static node* new_def(parser_state *p, mrb_sym m, node *a, node *b) { - return list5((node*)NODE_DEF, nsym(m), locals_node(p), a, b); + return list5((node*)NODE_DEF, nsym(m), 0, a, b); +} + +static void +defn_setup(parser_state *p, node *d, node *a, node *b) +{ + node *n = d->cdr->cdr; + + n->car = locals_node(p); + p->cmdarg_stack = intn(n->cdr->car); + n->cdr->car = a; + local_resume(p, n->cdr->cdr->car); + n->cdr->cdr->car = b; } /* (:sdef obj m lv (arg . body)) */ @@ -738,7 +750,19 @@ static node* new_sdef(parser_state *p, node *o, mrb_sym m, node *a, node *b) { void_expr_error(p, o); - return list6((node*)NODE_SDEF, o, nsym(m), locals_node(p), a, b); + return list6((node*)NODE_SDEF, o, nsym(m), 0, a, b); +} + +static void +defs_setup(parser_state *p, node *d, node *a, node *b) +{ + node *n = d->cdr->cdr->cdr; + + n->car = locals_node(p); + p->cmdarg_stack = intn(n->cdr->car); + n->cdr->car = a; + local_resume(p, n->cdr->cdr->car); + n->cdr->cdr->car = b; } /* (:arg . sym) */ @@ -1415,7 +1439,7 @@ heredoc_end(parser_state *p) %token tNUMPARAM %type singleton string string_fragment string_rep string_interp xstring regexp -%type literal numeric cpath symbol +%type literal numeric cpath symbol defn_head defs_head %type top_compstmt top_stmts top_stmt rassign %type bodystmt compstmt stmts stmt expr arg primary command command_call method_call %type expr_value arg_rhs primary_value @@ -1425,7 +1449,7 @@ heredoc_end(parser_state *p) %type command_args aref_args opt_block_arg block_arg var_ref var_lhs %type command_asgn command_rhs mrhs superclass block_call block_command %type f_block_optarg f_block_opt -%type f_arglist f_args f_arg f_arg_item f_optarg f_margs +%type f_arglist_paren f_arglist f_args f_arg f_arg_item f_optarg f_margs %type assoc_list assocs assoc undef_list backref for_var %type block_param opt_block_param block_param_def f_opt %type bv_decls opt_bv_decl bvar f_larglist lambda_body @@ -1681,7 +1705,7 @@ rassign : arg tASSOC lhs $$ = new_masgn(p, $3, $1); } ; - + command_asgn : lhs '=' command_rhs { $$ = new_asgn(p, $1, $3); @@ -1747,6 +1771,31 @@ expr : command_call | arg ; + +defn_head : keyword_def fname + { + $$ = new_def(p, $2, nint(p->cmdarg_stack), local_switch(p)); + p->cmdarg_stack = 0; + p->in_def++; + nvars_block(p); + } + ; + +defs_head : keyword_def singleton dot_or_colon + { + p->lstate = EXPR_FNAME; + } + fname + { + $$ = new_sdef(p, $2, $5, nint(p->cmdarg_stack), local_switch(p)); + p->cmdarg_stack = 0; + p->in_def++; + p->in_single++; + nvars_block(p); + p->lstate = EXPR_ENDFN; /* force for args */ + } + ; + expr_value : expr { if (!$1) $$ = new_nil(p); @@ -2267,6 +2316,21 @@ arg : lhs '=' arg_rhs { $$ = new_if(p, cond($1), $3, $6); } + | defn_head f_arglist_paren '=' arg + { + $$ = $1; + defn_setup(p, $$, $2, $4); + nvars_unnest(p); + p->in_def--; + } + | defs_head f_arglist_paren '=' arg + { + $$ = $1; + defs_setup(p, $$, $2, $4); + nvars_unnest(p); + p->in_def--; + p->in_single--; + } | primary { $$ = $1; @@ -2666,50 +2730,26 @@ primary : literal local_resume(p, $3); nvars_unnest(p); } - | keyword_def fname - { - $$ = p->cmdarg_stack; - p->cmdarg_stack = 0; - } - { - p->in_def++; - $$ = local_switch(p); - nvars_block(p); - } + | defn_head f_arglist bodystmt keyword_end { - $$ = new_def(p, $2, $5, $6); - SET_LINENO($$, $1); - local_resume(p, $4); + $$ = $1; + defn_setup(p, $$, $2, $3); nvars_unnest(p); p->in_def--; - p->cmdarg_stack = $3; - } - | keyword_def singleton dot_or_colon - { - p->lstate = EXPR_FNAME; - $$ = p->cmdarg_stack; - p->cmdarg_stack = 0; - } - fname - { - p->in_single++; - p->lstate = EXPR_ENDFN; /* force for args */ - $$ = local_switch(p); - nvars_block(p); } + | defs_head f_arglist bodystmt keyword_end { - $$ = new_sdef(p, $2, $5, $7, $8); - SET_LINENO($$, $1); - local_resume(p, $6); + $$ = $1; + defs_setup(p, $$, $2, $3); nvars_unnest(p); + p->in_def--; p->in_single--; - p->cmdarg_stack = $4; } | keyword_break { @@ -3420,7 +3460,7 @@ superclass : /* term */ } */ ; -f_arglist : '(' f_args rparen +f_arglist_paren : '(' f_args rparen { $$ = $2; p->lstate = EXPR_BEG; @@ -3444,6 +3484,9 @@ f_arglist : '(' f_args rparen new_args_tail(p, 0, new_kw_rest_args(p, nsym(k)), b)); #endif } + ; + +f_arglist : f_arglist_paren | f_args term { $$ = $1; -- cgit v1.2.3