summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog22
-rw-r--r--bignum.c32
-rw-r--r--eval.c6
-rw-r--r--numeric.c176
-rw-r--r--parse.y28
5 files changed, 140 insertions, 124 deletions
diff --git a/ChangeLog b/ChangeLog
index c6ccebf82d9..d159ab9cf7f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+Mon Jul 3 13:15:02 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * 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 <eban@os.rim.or.jp>
* configure.in: use AC_CANONICAL_SYSTEM.
@@ -14,6 +27,10 @@ Sun Jul 2 21:17:37 2000 WATANABE Hirofumi <eban@os.rim.or.jp>
* util.c (ruby_mktemp): remove unused ruby_mktemp().
+Sun Jul 2 14:18:04 2000 Koji Arai <JCA02266@nifty.ne.jp>
+
+ * eval.c (TMP_PROTECT_END): tmp__protect_tmp may be NULL.
+
Sun Jul 2 03:37:50 2000 Minero Aoki <aamine@dp.u-netsurf.ne.jp>
* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.25.
@@ -24,6 +41,11 @@ Sun Jul 2 03:37:50 2000 Minero Aoki <aamine@dp.u-netsurf.ne.jp>
Sat Jul 1 15:22:35 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
+ * numeric.c (fix_rshift): should handle shift value more than
+ sizeof(long).
+
+Sat Jul 1 15:22:35 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
+
* eval.c (rb_eval): the value from RTEST() is not valid Ruby
objct. result shoule be either true or false.
diff --git a/bignum.c b/bignum.c
index 9510be66ed2..9a095ae3da2 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 0610455f1cb..7415581d63c 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 589f06bfc04..af00d23da53 100644
--- a/numeric.c
+++ b/numeric.c
@@ -133,6 +133,14 @@ num_divmod(x, y)
}
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 VALUE
-fix_div(x, y)
- VALUE x, y;
+static void
+fixdivmod(x, y, divp, modp)
+ long x, y;
+ long *divp, *modp;
{
- if (FIXNUM_P(y)) {
- long i;
+ long div, mod;
- i = FIX2LONG(y);
- if (i == 0) rb_num_zerodiv();
- i = FIX2LONG(x)/i;
- return INT2NUM(i); /* FIXNUM_MIN / -1 > FIXNUM_MAX */
+ if (y == 0) rb_num_zerodiv();
+ if (y < 0) {
+ if (x < 0)
+ div = -x / -y;
+ else
+ div = - (x / -y);
}
- return rb_num_coerce_bin(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_modulo(x, y, modulo)
+fix_div(x, y)
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);
+ long div;
+
+ 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 2f530edb761..da36f28d72d 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);
}