From: Nobuyoshi Nakada Date: 2007-07-20T11:59:34+09:00 Subject: [ruby-dev:31267] Re: +:x doesn't raise exception なかだです。 At Thu, 19 Jul 2007 22:13:04 +0900, Yusuke ENDOH wrote in [ruby-dev:31264]: > Symbol#+@ や Regexp#+@ がないのに以下が例外にならないのは > 仕様でしょうか。 リテラルの単項+は無視してるんですが、エラーのほうがいいでしょ うか。ついでに単項−も可能なら変換するようにしてみましたが。 Index: parse.y =================================================================== --- parse.y (revision 12819) +++ parse.y (working copy) @@ -420,4 +420,9 @@ extern int rb_local_defined(ID); extern int rb_parse_in_eval(void); +#define numeric_p(val) (\ + FIXNUM_P(val) || \ + (!SPECIAL_CONST_P(val) && \ + (BUILTIN_TYPE(val) == T_FLOAT || BUILTIN_TYPE(val) == T_BIGNUM))) + #else #define remove_begin(node) (node) @@ -2007,5 +2012,6 @@ arg : lhs '=' arg { /*%%%*/ - if ($2 && nd_type($2) == NODE_LIT) { + $$ = 0; + if ($2 && nd_type($2) == NODE_LIT && numeric_p($2->nd_lit)) { $$ = $2; } @@ -2020,5 +2026,10 @@ arg : lhs '=' arg { /*%%%*/ - $$ = call_op($2, tUMINUS, 0, 0); + if ($2 && nd_type($2) == NODE_LIT && numeric_p($2->nd_lit)) { + $$ = negate_lit($2); + } + else { + $$ = call_op($2, tUMINUS, 0, 0); + } /*% $$ = dispatch2(unary, ripper_intern("-@"), $2); @@ -7901,8 +7912,8 @@ negate_lit(NODE *node) switch (TYPE(node->nd_lit)) { case T_FIXNUM: - node->nd_lit = LONG2FIX(-FIX2LONG(node->nd_lit)); + node->nd_lit = LONG2NUM(-FIX2LONG(node->nd_lit)); break; case T_BIGNUM: - node->nd_lit = rb_funcall(node->nd_lit,tUMINUS,0,0); + RBIGNUM(node->nd_lit)->sign = !RBIGNUM(node->nd_lit)->sign; break; case T_FLOAT: -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦