diff options
| -rw-r--r-- | mrbgems/mruby-compiler/core/parse.y | 71 | ||||
| -rw-r--r-- | test/t/syntax.rb | 10 |
2 files changed, 43 insertions, 38 deletions
diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y index cdb239645..061bbd58a 100644 --- a/mrbgems/mruby-compiler/core/parse.y +++ b/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,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: diff --git a/test/t/syntax.rb b/test/t/syntax.rb index 1dca8fd24..af63fcef9 100644 --- a/test/t/syntax.rb +++ b/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 |
