Allow non numbered-parameter identifier like `_1` outside of blocks.

But it causes warnings as CRuby does; fix #4892 fix #489
parent d8a5163b
...@@ -671,12 +671,9 @@ new_cvar(parser_state *p, mrb_sym sym) ...@@ -671,12 +671,9 @@ new_cvar(parser_state *p, mrb_sym sym)
static node* static node*
new_nvar(parser_state *p, int num) new_nvar(parser_state *p, int num)
{ {
if (!p->nvars || intn(p->nvars->car) < -1) { int nvars = intn(p->nvars->car);
yyerror(p, "numbered parameter outside block");
} else { 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)); return cons((node*)NODE_NVAR, nint(num));
} }
...@@ -5962,21 +5959,33 @@ parser_yylex(parser_state *p) ...@@ -5962,21 +5959,33 @@ parser_yylex(parser_state *p)
case '_': case '_':
if (toklen(p) == 2 && ISDIGIT(tok(p)[1]) && p->nvars) { if (toklen(p) == 2 && ISDIGIT(tok(p)[1]) && p->nvars) {
int n = tok(p)[1] - '0'; int n = tok(p)[1] - '0';
int nvar;
if (n > 0) { if (n > 0) {
node *nvars = p->nvars->cdr; node *nvars = p->nvars->cdr;
while (nvars) { while (nvars) {
if (intn(nvars->car) > 0) { nvar = intn(nvars->car);
yywarning(p, "numbered parameter in nested block"); if (nvar == -2) break; /* top of the scope */
if (nvar > 0) {
yywarning(p, "numbered parameter used in outer block");
break; break;
} }
nvars->car = nint(-1); nvars->car = nint(-1);
nvars = nvars->cdr; nvars = nvars->cdr;
} }
pylval.num = n; nvar = intn(p->nvars->car);
p->lstate = EXPR_END; if (nvar == -1) {
return tNUMPARAM; 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 */ /* fall through */
...@@ -5995,6 +6004,15 @@ parser_yylex(parser_state *p) ...@@ -5995,6 +6004,15 @@ parser_yylex(parser_state *p)
else { else {
pushback(p, c); 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])) { if (result == 0 && ISUPPER(tok(p)[0])) {
result = tCONSTANT; result = tCONSTANT;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment