diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2005-08-12 08:13:28 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2005-08-12 08:13:28 +0000 |
commit | e439bc27dc5f6814b49309b4ad32b8d3ca54e9a4 (patch) | |
tree | 127adbc9559d0dd3f365f14a9ce9b5bc778f34e6 | |
parent | ec14c2c9b925f6add71f7f4d25e0a281f8adb252 (diff) |
* parse.y (f_larglist): allow optional arguments even when
parentheses are omitted. based on Nobu's patch from
http://www.rubyist.net/~nobu/t/20050805.html
* parse.y (parser_yylex): update & maintain lpar_beg for detect
lambda parameters.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@8971 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | bignum.c | 4 | ||||
-rw-r--r-- | gc.c | 2 | ||||
-rw-r--r-- | intern.h | 2 | ||||
-rw-r--r-- | numeric.c | 42 | ||||
-rw-r--r-- | parse.y | 54 |
6 files changed, 73 insertions, 40 deletions
@@ -1,3 +1,12 @@ +Fri Aug 12 17:06:53 2005 Yukihiro Matsumoto <matz@ruby-lang.org> + + * parse.y (f_larglist): allow optional arguments even when + parentheses are omitted. based on Nobu's patch from + http://www.rubyist.net/~nobu/t/20050805.html + + * parse.y (parser_yylex): update & maintain lpar_beg for detect + lambda parameters. + Thu Aug 11 23:29:03 2005 Nobuyoshi Nakada <nobu@ruby-lang.org> * ext/stringio/stringio.c: keep holding string after closed. @@ -922,7 +922,7 @@ rb_big_to_f(x) * */ -static VALUE +VALUE rb_big_cmp(x, y) VALUE x, y; { @@ -968,7 +968,7 @@ rb_big_cmp(x, y) * 68719476736 == 68719476736.0 #=> true */ -static VALUE +VALUE rb_big_eq(x, y) VALUE x, y; { @@ -1802,8 +1802,8 @@ rb_gc_finalize_deferred() deferred_final_list = 0; if (p) { finalize_list(p); - free_unused_heaps(); } + free_unused_heaps(); } void @@ -95,6 +95,8 @@ void rb_quad_pack _((char*,VALUE)); VALUE rb_quad_unpack _((const char*,int)); VALUE rb_dbl2big _((double)); double rb_big2dbl _((VALUE)); +VALUE rb_big_cmp _((VALUE, VALUE)); +VALUE rb_big_eq _((VALUE, VALUE)); VALUE rb_big_plus _((VALUE, VALUE)); VALUE rb_big_minus _((VALUE, VALUE)); VALUE rb_big_mul _((VALUE, VALUE)); @@ -2289,7 +2289,12 @@ fix_equal(x, y) if (FIXNUM_P(y)) { return (FIX2LONG(x) == FIX2LONG(y))?Qtrue:Qfalse; } - else { + switch (TYPE(y)) { + case T_BIGNUM: + return rb_big_eq(y, x); + case T_FLOAT: + return (double)FIX2LONG(x) == RFLOAT(y)->value ? Qtrue : Qfalse; + default: return num_equal(x, y); } } @@ -2314,7 +2319,12 @@ fix_cmp(x, y) if (a > b) return INT2FIX(1); return INT2FIX(-1); } - else { + switch (TYPE(y)) { + case T_BIGNUM: + return rb_big_cmp(rb_int2big(FIX2LONG(x)), y); + case T_FLOAT: + return rb_dbl_cmp((double)FIX2LONG(x), RFLOAT(y)->value); + default: return rb_num_coerce_cmp(x, y); } } @@ -2337,7 +2347,12 @@ fix_gt(x, y) if (a > b) return Qtrue; return Qfalse; } - else { + switch (TYPE(y)) { + case T_BIGNUM: + return FIX2INT(rb_big_cmp(rb_int2big(FIX2LONG(x)), y)) > 0 ? Qtrue : Qfalse; + case T_FLOAT: + return (double)FIX2LONG(x) > RFLOAT(y)->value ? Qtrue : Qfalse; + default: return rb_num_coerce_relop(x, y); } } @@ -2360,7 +2375,12 @@ fix_ge(x, y) if (a >= b) return Qtrue; return Qfalse; } - else { + switch (TYPE(y)) { + case T_BIGNUM: + return FIX2INT(rb_big_cmp(rb_int2big(FIX2LONG(x)), y)) >= 0 ? Qtrue : Qfalse; + case T_FLOAT: + return (double)FIX2LONG(x) >= RFLOAT(y)->value ? Qtrue : Qfalse; + default: return rb_num_coerce_relop(x, y); } } @@ -2383,7 +2403,12 @@ fix_lt(x, y) if (a < b) return Qtrue; return Qfalse; } - else { + switch (TYPE(y)) { + case T_BIGNUM: + return FIX2INT(rb_big_cmp(rb_int2big(FIX2LONG(x)), y)) < 0 ? Qtrue : Qfalse; + case T_FLOAT: + return (double)FIX2LONG(x) < RFLOAT(y)->value ? Qtrue : Qfalse; + default: return rb_num_coerce_relop(x, y); } } @@ -2406,7 +2431,12 @@ fix_le(x, y) if (a <= b) return Qtrue; return Qfalse; } - else { + switch (TYPE(y)) { + case T_BIGNUM: + return FIX2INT(rb_big_cmp(rb_int2big(FIX2LONG(x)), y)) <= 0 ? Qtrue : Qfalse; + case T_FLOAT: + return (double)FIX2LONG(x) <= RFLOAT(y)->value ? Qtrue : Qfalse; + default: return rb_num_coerce_relop(x, y); } } @@ -126,6 +126,8 @@ struct parser_params { stack_type parser_cond_stack; stack_type parser_cmdarg_stack; int parser_class_nest; + int parser_paren_nest; + int parser_lpar_beg; int parser_in_single; int parser_in_def; int parser_compile_for_eval; @@ -182,6 +184,8 @@ static int parser_yyerror _((struct parser_params*, const char*)); #define cond_stack (parser->parser_cond_stack) #define cmdarg_stack (parser->parser_cmdarg_stack) #define class_nest (parser->parser_class_nest) +#define paren_nest (parser->parser_paren_nest) +#define lpar_beg (parser->parser_lpar_beg) #define in_single (parser->parser_in_single) #define in_def (parser->parser_in_def) #define compile_for_eval (parser->parser_compile_for_eval) @@ -476,6 +480,7 @@ static void ripper_compile_error _((struct parser_params*, const char *fmt, ...) kDO kDO_COND kDO_BLOCK + kDO_LAMBDA kRETURN kYIELD kSUPER @@ -555,7 +560,7 @@ static void ripper_compile_error _((struct parser_params*, const char *fmt, ...) %token tLAMBDA /* -> */ %token tLAMBDA_ARG /* -> */ %token tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tWORDS_BEG tQWORDS_BEG -%token tSTRING_DBEG tSTRING_DVAR tSTRING_END +%token tSTRING_DBEG tSTRING_DVAR tSTRING_END tLAMBEG /* * precedence table @@ -3173,6 +3178,8 @@ bv_decl : tIDENTIFIER ; lambda : { + $<num>$ = lpar_beg; + lpar_beg = ++paren_nest; /*%%%*/ $<vars>$ = dyna_push(); /*% @@ -3202,47 +3209,23 @@ f_larglist : '(' f_args opt_bv_decl rparen $$ = dispatch1(paren, $2); %*/ } - | f_arg opt_f_block_arg opt_bv_decl + | f_args opt_bv_decl { /*%%%*/ - $$ = NEW_LAMBDA(new_args($1, 0, 0, $2), $3); + $$ = NEW_LAMBDA($1, $2); /*% - $$ = dispatch4(params, $1, Qnil, Qnil, Qnil); - %*/ - } - | f_arg ',' f_rest_arg opt_f_block_arg opt_bv_decl - { - /*%%%*/ - $$ = NEW_LAMBDA(new_args($1, 0, $3, $4), $5); - /*% - $$ = dispatch4(params, $1, Qnil, $3, Qnil); - %*/ - } - | f_rest_arg opt_f_block_arg opt_bv_decl - { - /*%%%*/ - $$ = NEW_LAMBDA(new_args(0, 0, $1, $2), $3); - /*% - $$ = dispatch4(params, Qnil, Qnil, $1, Qnil); - %*/ - } - | opt_f_block_arg opt_bv_decl - { - /*%%%*/ - $$ = NEW_LAMBDA(new_args(0, 0, 0, $1), $2); - /*% - $$ = dispatch4(params, Qnil, Qnil, Qnil, Qnil); + $$ = $1; %*/ } ; -lambda_body : '{' +lambda_body : tLAMBEG compstmt '}' { $$ = $2; } - | kDO + | kDO_LAMBDA compstmt kEND { @@ -6348,9 +6331,10 @@ parser_yylex(parser) return tINTEGER; } + case ')': + paren_nest--; case ']': case '}': - case ')': COND_LEXPOP(); CMDARG_LEXPOP(); lex_state = EXPR_END; @@ -6468,6 +6452,7 @@ parser_yylex(parser) c = '('; } } + paren_nest++; COND_PUSH(0); CMDARG_PUSH(0); lex_state = EXPR_BEG; @@ -6498,6 +6483,10 @@ parser_yylex(parser) return c; case '{': + if (lpar_beg && lpar_beg == paren_nest) { + lex_state = EXPR_BEG; + return tLAMBEG; + } if (IS_ARG() || lex_state == EXPR_END || lex_state == EXPR_END2) c = '{'; /* block (primary) */ else if (lex_state == EXPR_ENDARG) @@ -6815,6 +6804,9 @@ parser_yylex(parser) set_yylval_id(rb_intern(kw->name)); } if (kw->id[0] == kDO) { + if (lpar_beg && lpar_beg == paren_nest) { + return kDO_LAMBDA; + } if (COND_P()) return kDO_COND; if (CMDARG_P() && state != EXPR_CMDARG) return kDO_BLOCK; |