summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-compiler
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2019-12-26 18:38:49 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2019-12-27 11:05:56 +0900
commitff16331754cd63c54279592fe4be77991bb6327d (patch)
tree6d775a0be6cedf453cefee0b698fe2002496de10 /mrbgems/mruby-compiler
parentd8a5163b24489bc0ff046e13a67fdc3feb01f7cd (diff)
downloadmruby-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
Diffstat (limited to 'mrbgems/mruby-compiler')
-rw-r--r--mrbgems/mruby-compiler/core/parse.y40
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;