From 6ad90f5ad4961b26287c87c2d34056829c59755d Mon Sep 17 00:00:00 2001 From: matz Date: Mon, 3 Jul 2000 05:46:36 +0000 Subject: [PATCH] matz git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@802 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 22 +++++++ bignum.c | 32 ++-------- eval.c | 6 +- numeric.c | 182 ++++++++++++++++++++++++++++-------------------------- parse.y | 28 ++++++--- 5 files changed, 143 insertions(+), 127 deletions(-) diff --git a/ChangeLog b/ChangeLog index c6ccebf82d..d159ab9cf7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +Mon Jul 3 13:15:02 2000 Yukihiro Matsumoto + + * numeric.c (fix_divmod): x * d + m = y where d, m = x.divmod(y). + + * bignum.c (rb_big_divmod): ditto. + + * numeric.c (fixdivmod): does not depend C's undifined % + behavior. adopt to fmod(3m) behavior. + + * numeric.c (flo_mod): modulo now reserves fmod(3m) behavior. + + * numeric.c (num_remainder): 'deprecated' warning. + Mon Jul 3 10:27:28 2000 WATANABE Hirofumi * configure.in: use AC_CANONICAL_SYSTEM. @@ -14,6 +27,10 @@ Sun Jul 2 21:17:37 2000 WATANABE Hirofumi * util.c (ruby_mktemp): remove unused ruby_mktemp(). +Sun Jul 2 14:18:04 2000 Koji Arai + + * eval.c (TMP_PROTECT_END): tmp__protect_tmp may be NULL. + Sun Jul 2 03:37:50 2000 Minero Aoki * lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.25. @@ -22,6 +39,11 @@ Sun Jul 2 03:37:50 2000 Minero Aoki * lib/net/smtp.rb: allow String for to_addr of SMTP#sendmail +Sat Jul 1 15:22:35 2000 Yukihiro Matsumoto + + * numeric.c (fix_rshift): should handle shift value more than + sizeof(long). + Sat Jul 1 15:22:35 2000 Yukihiro Matsumoto * eval.c (rb_eval): the value from RTEST() is not valid Ruby diff --git a/bignum.c b/bignum.c index 9510be66ed..9a095ae3da 100644 --- a/bignum.c +++ b/bignum.c @@ -777,10 +777,9 @@ rb_big_mul(x, y) } static void -bigdivmod(x, y, div, mod, modulo) +bigdivmod(x, y, div, mod) VALUE x, y; VALUE *div, *mod; - int modulo; { long nx = RBIGNUM(x)->len, ny = RBIGNUM(y)->len; long i, j; @@ -812,9 +811,6 @@ bigdivmod(x, y, div, mod, modulo) if (div) *div = bignorm(z); if (mod) { if (!RBIGNUM(x)->sign) t2 = -(long)t2; - if (modulo && RBIGNUM(x)->sign != RBIGNUM(y)->sign) { - t2 = t2 + yds[0] * (RBIGNUM(y)->sign ? 1 : -1); - } *mod = INT2NUM(t2); } return; @@ -898,10 +894,6 @@ bigdivmod(x, y, div, mod, modulo) } RBIGNUM(*mod)->len = ny; RBIGNUM(*mod)->sign = RBIGNUM(x)->sign; - if (modulo && RBIGNUM(x)->sign != RBIGNUM(y)->sign) { - *mod = bigadd(*mod, y, 1); - return; - } *mod = bignorm(*mod); } } @@ -933,9 +925,8 @@ rb_big_div(x, y) static VALUE -rb_big_modulo(x, y, modulo) +rb_big_mod(x, y) VALUE x, y; - int modulo; { VALUE z; @@ -954,25 +945,11 @@ rb_big_modulo(x, y, modulo) default: return rb_num_coerce_bin(x, y); } - bigdivmod(x, y, 0, &z, modulo); + bigdivmod(x, y, 0, &z); return z; } -static VALUE -rb_big_mod(x, y) - VALUE x, y; -{ - return rb_big_modulo(x, y, 1); -} - -static VALUE -rb_big_remainder(x, y) - VALUE x, y; -{ - return rb_big_modulo(x, y, 0); -} - VALUE rb_big_divmod(x, y) VALUE x, y; @@ -994,7 +971,7 @@ rb_big_divmod(x, y) default: return rb_num_coerce_bin(x, y); } - bigdivmod(x, y, &div, &mod, 1); + bigdivmod(x, y, &div, &mod); return rb_assoc_new(div, mod); } @@ -1382,7 +1359,6 @@ Init_Bignum() rb_define_method(rb_cBignum, "/", rb_big_div, 1); rb_define_method(rb_cBignum, "%", rb_big_mod, 1); rb_define_method(rb_cBignum, "divmod", rb_big_divmod, 1); - rb_define_method(rb_cBignum, "remainder", rb_big_remainder, 1); rb_define_method(rb_cBignum, "**", rb_big_pow, 1); rb_define_method(rb_cBignum, "&", rb_big_and, 1); rb_define_method(rb_cBignum, "|", rb_big_or, 1); diff --git a/eval.c b/eval.c index 0610455f1c..7415581d63 100644 --- a/eval.c +++ b/eval.c @@ -1539,8 +1539,10 @@ rb_mod_alias_method(mod, newname, oldname) ALLOC_N(VALUE,n),tmp__protect_tmp,n), \ (void*)tmp__protect_tmp->nd_head) # define TMP_PROTECT_END do {\ - rb_gc_force_recycle((VALUE)tmp__protect_tmp);\ - alloca(0);\ + if (tmp__protect_tmp) {\ + rb_gc_force_recycle((VALUE)tmp__protect_tmp);\ + alloca(0);\ + }\ } while (0) #else # define TMP_PROTECT typedef int foobazzz diff --git a/numeric.c b/numeric.c index 589f06bfc0..af00d23da5 100644 --- a/numeric.c +++ b/numeric.c @@ -132,6 +132,14 @@ num_divmod(x, y) return rb_assoc_new(div, mod); } +static VALUE +num_remainder(x, y) + VALUE x, y; +{ + rb_warn("remainder is deprecated; use % opearator"); + return rb_funcall(x, '%', 1, y); +} + static VALUE num_int_p(num) VALUE num; @@ -295,94 +303,73 @@ flo_div(x, y) } } -static VALUE -flo_modulo(x, y, modulo) - VALUE x, y; - int modulo; +static void +flodivmod(x, y, divp, modp) + double x, y; + double *divp, *modp; { - double value, result; - - switch (TYPE(y)) { - case T_FIXNUM: - value = (double)FIX2LONG(y); - break; - case T_BIGNUM: - value = rb_big2dbl(y); - break; - case T_FLOAT: - value = RFLOAT(y)->value; - break; - default: - return rb_num_coerce_bin(x, y); - } + double mod; #ifdef HAVE_FMOD - result = fmod(RFLOAT(x)->value, value); + mod = fmod(x, y); #else { - double value1 = RFLOAT(x)->value; - double value2; + double z; - modf(value1/value, &value2); - result = value1 - value2 * value; + modf(x/y, &); + mod = x - z * x; } #endif - if (modulo && value*result<0.0) { - result += value; + if (modp) *modp = mod; + if (divp) { + *divp = (x - mod) / y; } - return rb_float_new(result); } static VALUE flo_mod(x, y) VALUE x, y; { - return flo_modulo(x,y,1); -} + double fy, mod; -static VALUE -flo_remainder(x, y) - VALUE x, y; -{ - return flo_modulo(x,y,0); + switch (TYPE(y)) { + case T_FIXNUM: + fy = (double)FIX2LONG(y); + break; + case T_BIGNUM: + fy = rb_big2dbl(y); + break; + case T_FLOAT: + fy = RFLOAT(y)->value; + break; + default: + return rb_num_coerce_bin(x, y); + } + flodivmod(RFLOAT(x)->value, fy, 0, &mod); + return rb_float_new(mod); } static VALUE flo_divmod(x, y) VALUE x, y; { - double value, div, mod; + double fy; + VALUE div, mod; switch (TYPE(y)) { case T_FIXNUM: - value = (double)FIX2LONG(y); + fy = (double)FIX2LONG(y); break; case T_BIGNUM: - value = rb_big2dbl(y); + fy = rb_big2dbl(y); break; case T_FLOAT: - value = RFLOAT(y)->value; + fy = RFLOAT(y)->value; break; default: return rb_num_coerce_bin(x, y); } - -#ifdef HAVE_FMOD - mod = fmod(RFLOAT(x)->value, value); -#else - { - double value1 = RFLOAT(x)->value; - double value2; - - modf(value1/value, &value2); - mod = value1 - value2 * value; - } -#endif - div = (RFLOAT(x)->value - mod) / value; - if (value*mod<0.0) { - mod += value; - div -= 1.0; - } + flodivmod(RFLOAT(x)->value, fy, &div, &mod); return rb_assoc_new(rb_float_new(div), rb_float_new(mod)); } @@ -1010,37 +997,40 @@ fix_mul(x, y) return rb_num_coerce_bin(x, y); } +static void +fixdivmod(x, y, divp, modp) + long x, y; + long *divp, *modp; +{ + long div, mod; + + if (y == 0) rb_num_zerodiv(); + if (y < 0) { + if (x < 0) + div = -x / -y; + else + div = - (x / -y); + } + else { + if (x < 0) + div = - (-x / y); + else + div = x / y; + } + mod = x - div*y; + if (divp) *divp = div; + if (modp) *modp = mod; +} + static VALUE fix_div(x, y) VALUE x, y; { if (FIXNUM_P(y)) { - long i; + long div; - i = FIX2LONG(y); - if (i == 0) rb_num_zerodiv(); - i = FIX2LONG(x)/i; - return INT2NUM(i); /* FIXNUM_MIN / -1 > FIXNUM_MAX */ - } - return rb_num_coerce_bin(x, y); -} - -static VALUE -fix_modulo(x, y, modulo) - VALUE x, y; -{ - long i; - - if (FIXNUM_P(y)) { - i = FIX2LONG(y); - if (i == 0) rb_num_zerodiv(); - i = FIX2LONG(x)%i; - if (modulo && - (FIX2LONG(x) < 0) != (FIX2LONG(y) < 0) && - i != 0) { - i += FIX2LONG(y); - } - return INT2FIX(i); + fixdivmod(FIX2LONG(x), FIX2LONG(y), &div, 0); + return INT2NUM(div); } return rb_num_coerce_bin(x, y); } @@ -1049,14 +1039,27 @@ static VALUE fix_mod(x, y) VALUE x, y; { - return fix_modulo(x, y, 1); + if (FIXNUM_P(y)) { + long mod; + + fixdivmod(FIX2LONG(x), FIX2LONG(y), 0, &mod); + return INT2NUM(mod); + } + return rb_num_coerce_bin(x, y); } static VALUE -fix_remainder(x, y) +fix_divmod(x, y) VALUE x, y; { - return fix_modulo(x, y, 0); + if (FIXNUM_P(y)) { + long div, mod; + + fixdivmod(FIX2LONG(x), FIX2LONG(y), &div, &mod); + + return rb_assoc_new(INT2NUM(div), INT2NUM(mod)); + } + return rb_num_coerce_bin(x, y); } static VALUE @@ -1219,11 +1222,10 @@ static VALUE fix_lshift(x, y) VALUE x, y; { - long val; - int width; + long val, width; val = NUM2LONG(x); - width = NUM2INT(y); + width = NUM2LONG(y); if (width > (sizeof(VALUE)*CHAR_BIT-1) || ((unsigned long)val)>>(sizeof(VALUE)*CHAR_BIT-1-width) > 0) { return rb_big_lshift(rb_int2big(val), y); @@ -1241,6 +1243,11 @@ fix_rshift(x, y) i = NUM2LONG(y); if (i < 0) return fix_lshift(x, INT2FIX(-i)); + if (i == 0) return x; + if (i >= sizeof(long)*CHAR_BIT-1) { + if (i < 0) return INT2FIX(-1); + return INT2FIX(0); + } val = RSHIFT(FIX2LONG(x), i); return INT2FIX(val); } @@ -1536,7 +1543,7 @@ Init_Numeric() rb_define_method(rb_cFixnum, "*", fix_mul, 1); rb_define_method(rb_cFixnum, "/", fix_div, 1); rb_define_method(rb_cFixnum, "%", fix_mod, 1); - rb_define_method(rb_cFixnum, "remainder", fix_remainder, 1); + rb_define_method(rb_cFixnum, "divmod", fix_divmod, 1); rb_define_method(rb_cFixnum, "**", fix_pow, 1); rb_define_method(rb_cFixnum, "abs", fix_abs, 0); @@ -1586,7 +1593,6 @@ Init_Numeric() rb_define_method(rb_cFloat, "/", flo_div, 1); rb_define_method(rb_cFloat, "%", flo_mod, 1); rb_define_method(rb_cFloat, "divmod", flo_divmod, 1); - rb_define_method(rb_cFloat, "remainder", flo_remainder, 1); rb_define_method(rb_cFloat, "**", flo_pow, 1); rb_define_method(rb_cFloat, "==", flo_eq, 1); rb_define_method(rb_cFloat, "<=>", flo_cmp, 1); diff --git a/parse.y b/parse.y index 2f530edb76..da36f28d72 100644 --- a/parse.y +++ b/parse.y @@ -426,7 +426,6 @@ expr : mlhs '=' mrhs } | '!' command_call { - value_expr($2); $$ = NEW_NOT(cond($2)); } | arg @@ -849,13 +848,25 @@ arg : lhs '=' arg $$ = $1; } -aref_args : opt_call_args +aref_args : none + | args opt_nl { - if ($1 && nd_type($1) == NODE_BLOCK_PASS) { - rb_compile_error("block argument should not be given"); - } $$ = $1; } + | args ',' opt_nl + { + $$ = $1; + } + | args ',' tSTAR arg opt_nl + { + value_expr($4); + $$ = arg_concat($1, $4); + } + | tSTAR arg opt_nl + { + value_expr($2); + $$ = NEW_RESTARGS($2); + } opt_call_args : none | call_args opt_nl @@ -864,10 +875,6 @@ call_args : command_call { $$ = NEW_LIST($1); } - | args ',' - { - $$ = $1; - } | args ',' command_call { $$ = list_append($1, $3); @@ -878,6 +885,7 @@ call_args : command_call } | args ',' tSTAR arg opt_block_arg { + value_expr($4); $$ = arg_concat($1, $4); $$ = arg_blk_pass($$, $5); } @@ -892,6 +900,7 @@ call_args : command_call } | assocs ',' tSTAR arg opt_block_arg { + value_expr($4); $$ = arg_concat(NEW_LIST(NEW_HASH($1)), $4); $$ = arg_blk_pass($$, $5); } @@ -906,6 +915,7 @@ call_args : command_call } | args ',' assocs ',' tSTAR arg opt_block_arg { + value_expr($6); $$ = arg_concat(list_append($1, NEW_HASH($3)), $6); $$ = arg_blk_pass($$, $7); }