Support new numbered parameter syntax `_1` instead of `@1`.
MODIFY
mrbgems/mruby-compiler/core/parse.y
mrbgems/mruby-compiler/core/parse.y
@@ -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,43 +5878,45 @@ 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");
+ else {
+ yyerror_c(p, "wrong class variable name: @@", c);
+ }
return 0;
}
- do {
+ if (!identchar(c)) {
+ pushback(p, c);
+ return '@';
+ }
+ break;
+
+ case '_':
+ token_column = newtok(p);
tokadd(p, c);
c = nextc(p);
- } while (c >= 0 && ISDIGIT(c));
+ 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);
- tokfix(p);
- {
- unsigned long n = strtoul(tok(p) + 1, NULL, 10);
+ 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;
}
- else {
- yyerror_c(p, "wrong class variable name: @@", c);
- return 0;
- }
- } else if (!identchar(c)) {
- pushback(p, c);
- return '@';
- }
- break;
-
- case '_':
- token_column = newtok(p);
break;
default:

MODIFY
test/t/syntax.rb
test/t/syntax.rb
@@ -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

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