diff --git a/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c b/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c index aae91b285..a72e07701 100644 --- a/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c +++ b/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c @@ -396,6 +396,10 @@ mrb_value mrb_complex_mul(mrb_state *mrb, mrb_value x, mrb_value y) { return mrb_nil_value(); } +mrb_value mrb_complex_div(mrb_state *mrb, mrb_value x, mrb_value y) +{ + return mrb_nil_value(); +} mrb_value mrb_complex_to_i(mrb_state *mrb, mrb_value x) { return mrb_nil_value(); @@ -423,6 +427,10 @@ mrb_value mrb_rational_mul(mrb_state *mrb, mrb_value x, mrb_value y) { return mrb_nil_value(); } +mrb_value mrb_rational_div(mrb_state *mrb, mrb_value x, mrb_value y) +{ + return mrb_nil_value(); +} mrb_value mrb_rational_to_i(mrb_state *mrb, mrb_value x) { return mrb_nil_value(); diff --git a/mrbgems/mruby-complex/src/complex.c b/mrbgems/mruby-complex/src/complex.c index 870e54a6a..2cd111ded 100644 --- a/mrbgems/mruby-complex/src/complex.c +++ b/mrbgems/mruby-complex/src/complex.c @@ -348,61 +348,6 @@ complex_div(mrb_state *mrb, mrb_value x) return mrb_complex_div(mrb, x, y); } -mrb_int mrb_div_int(mrb_state *mrb, mrb_int x, mrb_int y); -mrb_value mrb_rational_new(mrb_state *mrb, mrb_int n, mrb_int d); -mrb_value mrb_rational_div(mrb_state *mrb, mrb_value x, mrb_value y); - -/* 15.2.8.3.4 */ -/* - * redefine Integer#/ - */ -static mrb_value -complex_int_div(mrb_state *mrb, mrb_value x) -{ - mrb_value y = mrb_get_arg1(mrb); - mrb_int a = mrb_integer(x); - - if (mrb_integer_p(y)) { - mrb_int div = mrb_div_int(mrb, a, mrb_integer(y)); - return mrb_int_value(mrb, div); - } - switch (mrb_type(y)) { -#ifdef MRB_USE_RATIONAL - case MRB_TT_RATIONAL: - return mrb_rational_div(mrb, mrb_rational_new(mrb, a, 1), y); -#endif - case MRB_TT_COMPLEX: - x = complex_new(mrb, (mrb_float)a, 0); - return complex_div(mrb, x); - default: - return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y))); - } -} - -/* 15.2.9.3.19(x) */ -/* - * redefine Integer#quo - */ - -static mrb_value -complex_int_quo(mrb_state *mrb, mrb_value x) -{ - mrb_value y = mrb_get_arg1(mrb); - mrb_int a = mrb_integer(x); - - switch (mrb_type(y)) { -#ifdef MRB_USE_RATIONAL - case MRB_TT_RATIONAL: - return mrb_rational_div(mrb, mrb_rational_new(mrb, a, 1), y); -#endif - case MRB_TT_COMPLEX: - x = complex_new(mrb, (mrb_float)a, 0); - return complex_div(mrb, x); - default: - return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y))); - } -} - static mrb_value complex_float_div(mrb_state *mrb, mrb_value x) { @@ -447,8 +392,6 @@ void mrb_mruby_complex_gem_init(mrb_state *mrb) mrb_define_method(mrb, comp, "/", complex_div, MRB_ARGS_REQ(1)); mrb_define_method(mrb, comp, "quo", complex_div, MRB_ARGS_REQ(1)); mrb_define_method(mrb, comp, "==", complex_eq, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, mrb->integer_class, "/", complex_int_div, MRB_ARGS_REQ(1)); /* override */ - mrb_define_method(mrb, mrb->integer_class, "quo", complex_int_quo, MRB_ARGS_REQ(1)); /* override */ mrb_define_method(mrb, mrb->float_class, "/", complex_float_div, MRB_ARGS_REQ(1)); /* override */ mrb_define_method(mrb, mrb->float_class, "quo", complex_float_div, MRB_ARGS_REQ(1)); /* override */ } diff --git a/mrbgems/mruby-rational/src/rational.c b/mrbgems/mruby-rational/src/rational.c index 0730c3ecb..8fed218d3 100644 --- a/mrbgems/mruby-rational/src/rational.c +++ b/mrbgems/mruby-rational/src/rational.c @@ -664,7 +664,8 @@ mrb_rational_div(mrb_state *mrb, mrb_value x, mrb_value y) } } -mrb_value rational_div(mrb_state *mrb, mrb_value x) +static mrb_value +rational_div(mrb_state *mrb, mrb_value x) { mrb_value y = mrb_get_arg1(mrb); return mrb_rational_div(mrb, x, y); @@ -672,62 +673,6 @@ mrb_value rational_div(mrb_state *mrb, mrb_value x) mrb_int mrb_div_int(mrb_state *, mrb_int, mrb_int); -#ifndef MRB_USE_COMPLEX -/* 15.2.8.3.4 */ -/* - * redefine Integer#/ - */ -static mrb_value -rational_int_div(mrb_state *mrb, mrb_value x) -{ - mrb_value y = mrb_get_arg1(mrb); - mrb_int a = mrb_integer(x); - - if (mrb_integer_p(y)) { - mrb_int div = mrb_div_int(mrb, a, mrb_integer(y)); - return mrb_int_value(mrb, div); - } - switch (mrb_type(y)) { - case MRB_TT_RATIONAL: - return rational_div(mrb, rational_new(mrb, a, 1), y); - default: -#ifdef MRB_NO_FLOAT - case MRB_TT_FLOAT: - mrb_raise(mrb, E_TYPE_ERROR, "non integer multiplication"); -#else - return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y))); -#endif - } -} - -/* 15.2.9.3.19(x) */ -/* - * redefine Integer#quo - */ - -static mrb_value -rational_int_quo(mrb_state *mrb, mrb_value x) -{ - mrb_value y = mrb_get_arg1(mrb); - mrb_int a = mrb_integer(x); - - if (mrb_integer_p(y)) { - return rational_new(mrb, a, mrb_integer(y)); - } - switch (mrb_type(y)) { - case MRB_TT_RATIONAL: - x = rational_new(mrb, a, 1); - return mrb_rational_div(mrb, x, y); - default: -#ifdef MRB_NO_FLOAT - mrb_raise(mrb, E_TYPE_ERROR, "non integer multiplication"); -#else - return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y))); -#endif - } -} -#endif /* !MRB_USE_COMPLEX */ - void mrb_mruby_rational_gem_init(mrb_state *mrb) { struct RClass *rat; @@ -753,10 +698,6 @@ void mrb_mruby_rational_gem_init(mrb_state *mrb) mrb_define_method(mrb, rat, "/", rational_div, MRB_ARGS_REQ(1)); mrb_define_method(mrb, rat, "quo", rational_div, MRB_ARGS_REQ(1)); mrb_define_method(mrb, mrb->integer_class, "to_r", fix_to_r, MRB_ARGS_NONE()); -#ifndef MRB_USE_COMPLEX - mrb_define_method(mrb, mrb->integer_class, "/", rational_int_div, MRB_ARGS_REQ(1)); /* override */ - mrb_define_method(mrb, mrb->integer_class, "quo", rational_int_quo, MRB_ARGS_REQ(1)); /* override */ -#endif mrb_define_method(mrb, mrb->kernel_module, "Rational", rational_m, MRB_ARGS_ARG(1,1)); } diff --git a/src/numeric.c b/src/numeric.c index aa07853ac..d4e124c2b 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -25,12 +25,14 @@ mrb_value mrb_complex_new(mrb_state *mrb, mrb_float x, mrb_float y); mrb_value mrb_complex_add(mrb_state *mrb, mrb_value x, mrb_value y); mrb_value mrb_complex_sub(mrb_state *mrb, mrb_value x, mrb_value y); mrb_value mrb_complex_mul(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_complex_div(mrb_state *mrb, mrb_value x, mrb_value y); #endif mrb_value mrb_rational_new(mrb_state *mrb, mrb_int x, mrb_int y); mrb_value mrb_rational_add(mrb_state *mrb, mrb_value x, mrb_value y); mrb_value mrb_rational_sub(mrb_state *mrb, mrb_value x, mrb_value y); mrb_value mrb_rational_mul(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_rational_div(mrb_state *mrb, mrb_value x, mrb_value y); void mrb_int_overflow(mrb_state *mrb, const char *reason) @@ -138,11 +140,23 @@ int_div(mrb_state *mrb, mrb_value x) mrb_int div = mrb_div_int(mrb, a, mrb_integer(y)); return mrb_int_value(mrb, div); } -#ifdef MRB_NO_FLOAT - mrb_raise(mrb, E_TYPE_ERROR, "non integer division"); -#else - return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y))); + switch (mrb_type(y)) { +#ifdef MRB_USE_RATIONAL + case MRB_TT_RATIONAL: + return mrb_rational_div(mrb, mrb_rational_new(mrb, a, 1), y); #endif +#ifdef MRB_USE_COMPLEX + case MRB_TT_COMPLEX: + x = mrb_complex_new(mrb, (mrb_float)a, 0); + return mrb_complex_div(mrb, x, y); +#endif + default: +#ifdef MRB_NO_FLOAT + mrb_raise(mrb, E_TYPE_ERROR, "non integer division"); +#else + return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y))); +#endif + } } /* 15.2.9.3.19(x) */ @@ -172,8 +186,12 @@ int_idiv(mrb_state *mrb, mrb_value x) } static mrb_value -int_quo(mrb_state *mrb, mrb_value xv) +int_quo(mrb_state *mrb, mrb_value x) { + mrb_value y = mrb_get_arg1(mrb); + mrb_int a = mrb_integer(x); + +#ifndef MRB_USE_RATIONAL #ifdef MRB_NO_FLOAT return int_idiv(mrb, xv); #else @@ -185,6 +203,22 @@ int_quo(mrb_state *mrb, mrb_value xv) } return mrb_float_value(mrb, mrb_integer(xv) / y); #endif +#else + if (mrb_integer_p(y) && mrb_class_defined_id(mrb, MRB_SYM(Rational))) { + return mrb_rational_new(mrb, a, mrb_integer(y)); + } + switch (mrb_type(y)) { + case MRB_TT_RATIONAL: + x = mrb_rational_new(mrb, a, 1); + return mrb_rational_div(mrb, x, y); + default: +#ifdef MRB_NO_FLOAT + mrb_raise(mrb, E_TYPE_ERROR, "non integer division"); +#else + return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y))); +#endif + } +#endif } static mrb_value diff --git a/test/t/integer.rb b/test/t/integer.rb index d4076f38a..71066bfb1 100644 --- a/test/t/integer.rb +++ b/test/t/integer.rb @@ -45,10 +45,17 @@ assert('Integer#/', '15.2.8.3.4') do assert_equal 2.0, b end -assert('Integer#quo') do - a = 6.quo(5) - assert_equal 1.2, a -end if Object.const_defined?(:Float) +if Object.const_defined?(:Rational) + assert('Integer#quo') do + a = 6.quo(5) + assert_equal 5/6r, a + end +elsif Object.const_defined?(:Float) + assert('Integer#quo') do + a = 6.quo(5) + assert_equal 1.2, a + end +end assert('Integer#%', '15.2.8.3.5') do a = 1%1