diff options
Diffstat (limited to 'mrbgems/mruby-compiler')
| -rw-r--r-- | mrbgems/mruby-compiler/core/parse.y | 68 |
1 files changed, 48 insertions, 20 deletions
diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y index de875a1ae..f8db486a5 100644 --- a/mrbgems/mruby-compiler/core/parse.y +++ b/mrbgems/mruby-compiler/core/parse.y @@ -318,19 +318,19 @@ locals_node(parser_state *p) static void nvars_nest(parser_state *p) { - p->nvars = cons(p->nvars, nint(0)); + p->nvars = cons(nint(0), p->nvars); } static void nvars_block(parser_state *p) { - p->nvars = cons(p->nvars, nint(-2)); + p->nvars = cons(nint(-2), p->nvars); } static void nvars_unnest(parser_state *p) { - p->nvars = p->nvars->car; + p->nvars = p->nvars->cdr; } /* (:scope (vars..) (prog...)) */ @@ -671,12 +671,9 @@ new_cvar(parser_state *p, mrb_sym sym) static node* new_nvar(parser_state *p, int num) { - if (!p->nvars || intn(p->nvars->cdr) < -1) { - yyerror(p, "numbered parameter outside block"); - } else { - int nvars = intn(p->nvars->cdr); - p->nvars->cdr = nint(nvars > num ? nvars : num); - } + int nvars = intn(p->nvars->car); + + p->nvars->car = nint(nvars > num ? nvars : num); return cons((node*)NODE_NVAR, nint(num)); } @@ -840,7 +837,7 @@ new_block_arg(parser_state *p, node *a) static node* setup_numparams(parser_state *p, node *a) { - int nvars = intn(p->nvars->cdr); + int nvars = intn(p->nvars->car); if (nvars > 0) { int i; mrb_sym sym; @@ -1955,6 +1952,10 @@ lhs : variable backref_error(p, $1); $$ = 0; } + | tNUMPARAM + { + yyerror(p, "can't assign to numbered parameter"); + } ; cname : tIDENTIFIER @@ -3278,6 +3279,10 @@ var_lhs : variable { assignable(p, $1); } + | tNUMPARAM + { + yyerror(p, "can't assign to numbered parameter"); + } ; var_ref : variable @@ -3538,6 +3543,11 @@ f_bad_arg : tCONSTANT yyerror(p, "formal argument cannot be a class variable"); $$ = 0; } + | tNUMPARAM + { + yyerror(p, "formal argument cannot be a numbered parameter"); + $$ = 0; + } ; f_norm_arg : f_bad_arg @@ -5957,24 +5967,33 @@ parser_yylex(parser_state *p) case '_': if (toklen(p) == 2 && ISDIGIT(tok(p)[1]) && p->nvars) { int n = tok(p)[1] - '0'; + int nvar; if (n > 0) { - node *nvars = p->nvars->car; + node *nvars = p->nvars->cdr; while (nvars) { - if (intn(nvars->cdr) > 0) { - yywarning(p, "numbered parameter in nested block"); + nvar = intn(nvars->car); + if (nvar == -2) break; /* top of the scope */ + if (nvar > 0) { + yywarning(p, "numbered parameter used in outer block"); break; } - nvars->cdr = nint(-1); - nvars = nvars->car; + nvars->car = nint(-1); + nvars = nvars->cdr; } - if (intn(p->nvars->cdr) < 0) { - yywarning(p, "numbered parameter in nested block"); + nvar = intn(p->nvars->car); + if (nvar == -1) { + yywarning(p, "numbered parameter used in inner block"); + } + if (nvar >= -1) { + pylval.num = n; + p->lstate = EXPR_END; + return tNUMPARAM; + } + else { + yywarning(p, "identifier for numbered parameter; consider another name"); } - pylval.num = n; - p->lstate = EXPR_END; - return tNUMPARAM; } } /* fall through */ @@ -5993,6 +6012,15 @@ parser_yylex(parser_state *p) else { pushback(p, c); } + if ((c = nextc(p)) == '=' && !peek(p, '~') && !peek(p, '>') && + (!peek(p, '=') || (peek_n(p, '>', 1)))) { + result = tIDENTIFIER; + tokadd(p, c); + tokfix(p); + } + else { + pushback(p, c); + } } if (result == 0 && ISUPPER(tok(p)[0])) { result = tCONSTANT; |
