diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2019-12-26 18:38:49 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2019-12-27 11:05:56 +0900 |
| commit | ff16331754cd63c54279592fe4be77991bb6327d (patch) | |
| tree | 6d775a0be6cedf453cefee0b698fe2002496de10 | |
| parent | d8a5163b24489bc0ff046e13a67fdc3feb01f7cd (diff) | |
| download | mruby-ff16331754cd63c54279592fe4be77991bb6327d.tar.gz mruby-ff16331754cd63c54279592fe4be77991bb6327d.zip | |
Allow non numbered-parameter identifier like `_1` outside of blocks.
But it causes warnings as CRuby does; fix #4892 fix #489
| -rw-r--r-- | mrbgems/mruby-compiler/core/parse.y | 40 |
1 files changed, 29 insertions, 11 deletions
diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y index 2f433aaf0..45c6229da 100644 --- a/mrbgems/mruby-compiler/core/parse.y +++ b/mrbgems/mruby-compiler/core/parse.y @@ -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->car) < -1) { - yyerror(p, "numbered parameter outside block"); - } else { - int nvars = intn(p->nvars->car); - p->nvars->car = 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)); } @@ -5962,21 +5959,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->cdr; while (nvars) { - if (intn(nvars->car) > 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->car = nint(-1); nvars = nvars->cdr; } - pylval.num = n; - p->lstate = EXPR_END; - return tNUMPARAM; + 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"); + } } } /* fall through */ @@ -5995,6 +6004,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; |
