diff options
Diffstat (limited to 'numeric.c')
-rw-r--r-- | numeric.c | 57 |
1 files changed, 39 insertions, 18 deletions
@@ -6,7 +6,7 @@ $Date$ created at: Fri Aug 13 18:33:09 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ @@ -37,23 +37,49 @@ static VALUE num_coerce(x, y) VALUE x, y; { - return assoc_new(rb_Float(x),rb_Float(y)); + if (CLASS_OF(x) == CLASS_OF(y)) + return assoc_new(x, y); + return assoc_new(rb_Float(x), rb_Float(y)); } -VALUE -num_coerce_bin(x, y) - VALUE x, y; +coerce_body(x) + VALUE *x; +{ + return rb_funcall(x[1], coerce, 1, x[0]); +} + +coerce_rescue(x) + VALUE *x; +{ + TypeError("%s can't be coerced into %s", + rb_class2name(CLASS_OF(x[1])), + rb_class2name(CLASS_OF(x[0]))); +} + +static void +do_coerce(x, y) + VALUE *x, *y; { VALUE ary; + VALUE a[2]; - ary = rb_funcall(y, coerce, 1, x); + a[0] = *x; a[1] = *y; + ary = rb_rescue(coerce_body, a, coerce_rescue, a); if (TYPE(ary) != T_ARRAY || RARRAY(ary)->len != 2) { TypeError("coerce must return [x, y]"); } - x = RARRAY(ary)->ptr[0]; - y = RARRAY(ary)->ptr[1]; + *x = RARRAY(ary)->ptr[0]; + *y = RARRAY(ary)->ptr[1]; +} + +VALUE +num_coerce_bin(x, y) + VALUE x, y; +{ + VALUE ary; + do_coerce(&x, &y); return rb_funcall(x, rb_frame_last_func(), 1, y); } @@ -68,17 +94,12 @@ static VALUE num_uminus(num) VALUE num; { - VALUE ary, x, y; - - ary = rb_funcall(num, coerce, 1, INT2FIX(0)); - if (TYPE(ary) != T_ARRAY || RARRAY(ary)->len != 2) { - TypeError("coerce must return [x, y]"); - } + VALUE zero; - x = RARRAY(ary)->ptr[0]; - y = RARRAY(ary)->ptr[1]; + zero = INT2FIX(0); + do_coerce(&num, &zero); - return rb_funcall(x, '-', 1, y); + return rb_funcall(zero, '-', 1, num); } static VALUE @@ -824,7 +845,7 @@ fix_rshift(x, y) long i, val; i = NUM2INT(y); - if (y < 32) { + if (i < sizeof(INT) * 8) { val = RSHIFT(FIX2INT(x), i); return INT2FIX(val); } |