Support new numbered parameter syntax `_1` instead of `@1`.

parent 72d57ad0
......@@ -74,7 +74,7 @@ typedef unsigned int stack_type;
#define NUM_SUFFIX_R (1<<0)
#define NUM_SUFFIX_I (1<<1)
#define NUMPARAM_MAX 31
#define NUMPARAM_MAX 9
static inline mrb_sym
intern_cstr_gen(parser_state *p, const char *s)
......@@ -845,7 +845,6 @@ setup_args(parser_state *p, node *a)
int nvars = intn(p->nvars->cdr);
if (nvars > 0) {
int i;
char buf[5];
mrb_sym sym;
// m || opt || rest || tail
if (a && (a->car || (a->cdr && a->cdr->car) || (a->cdr->cdr && a->cdr->cdr->car) || (a->cdr->cdr->cdr->cdr && a->cdr->cdr->cdr->cdr->car))) {
......@@ -853,7 +852,11 @@ setup_args(parser_state *p, node *a)
} else {
node* args = 0;
for (i = nvars; i > 0; i--) {
sprintf(buf, "@%d", i);
char buf[3];
buf[0] = '_';
buf[1] = i+'0';
buf[3] = '\0';
sym = intern_cstr(buf);
args = cons(new_arg(p, sym), args);
p->locals->car = cons(nsym(sym), p->locals->car);
......@@ -2395,6 +2398,10 @@ primary : literal
| heredoc
| var_ref
| backref
| tNUMPARAM
{
$$ = new_nvar(p, $1);
}
| tFID
{
$$ = new_fcall(p, $1, 0);
......@@ -3265,10 +3272,6 @@ variable : tIDENTIFIER
{
$$ = new_cvar(p, $1);
}
| tNUMPARAM
{
$$ = new_nvar(p, $1);
}
| tCONSTANT
{
$$ = new_const(p, $1);
......@@ -5875,36 +5878,14 @@ parser_yylex(parser_state *p)
}
else if (ISDIGIT(c)) {
if (p->tidx == 1) {
if (last_state == EXPR_FNAME) {
yyerror_c(p, "wrong instance variable name: @", c);
return 0;
}
if (c == '0') {
yyerror(p, "leading zero is not allowed as a numbered parameter");
return 0;
}
do {
tokadd(p, c);
c = nextc(p);
} while (c >= 0 && ISDIGIT(c));
pushback(p, c);
tokfix(p);
{
unsigned long n = strtoul(tok(p) + 1, NULL, 10);
if (n > NUMPARAM_MAX || n < 0) {
yyerror(p, "too large numbered parameter");
return 0;
}
pylval.num = n;
}
p->lstate = EXPR_END;
return tNUMPARAM;
yyerror_c(p, "wrong instance variable name: @", c);
}
else {
yyerror_c(p, "wrong class variable name: @@", c);
return 0;
}
} else if (!identchar(c)) {
return 0;
}
if (!identchar(c)) {
pushback(p, c);
return '@';
}
......@@ -5912,6 +5893,30 @@ parser_yylex(parser_state *p)
case '_':
token_column = newtok(p);
tokadd(p, c);
c = nextc(p);
if (ISDIGIT(c)) {
int n = 0;
while (c >= 0 && ISDIGIT(c)) {
n *= 10;
n += c - '0';
tokadd(p, c);
c = nextc(p);
}
pushback(p, c);
if (n == 0) {
yyerror(p, "_0 is not available");
return 0;
}
if (n > NUMPARAM_MAX || n < 0) {
yyerror(p, "too large numbered parameter");
return 0;
}
pylval.num = n;
p->lstate = EXPR_END;
return tNUMPARAM;
}
break;
default:
......
......@@ -674,9 +674,9 @@ end
assert('numbered parameters') do
assert_equal(15, [1,2,3,4,5].reduce {@1+@2})
assert_equal(3, ->{@1+@2}.call(1,2))
assert_equal(4, ->(a=->{@1}){a}.call.call(4))
assert_equal(5, -> a: ->{@1} {a}.call.call(5))
assert_equal(55, Proc.new do @1 + @2 + @3 + @4 + @5 + @6 + @7 + @8 + @9 + @10 end.call(*[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))
assert_equal(15, [1,2,3,4,5].reduce {_1+_2})
assert_equal(3, ->{_1+_2}.call(1,2))
assert_equal(4, ->(a=->{_1}){a}.call.call(4))
assert_equal(5, -> a: ->{_1} {a}.call.call(5))
assert_equal(45, Proc.new do _1 + _2 + _3 + _4 + _5 + _6 + _7 + _8 + _9 end.call(*[1, 2, 3, 4, 5, 6, 7, 8, 9]))
end
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