diff --git a/moo/kernel/Magnitu.moo b/moo/kernel/Magnitu.moo index 2eeade2..6a55bbd 100644 --- a/moo/kernel/Magnitu.moo +++ b/moo/kernel/Magnitu.moo @@ -143,7 +143,7 @@ class(#limited) Number(Magnitude) method mdiv: aNumber { ## integer division quotient - + self primitiveFailed. } @@ -173,31 +173,31 @@ class(#limited) Number(Magnitude) method < aNumber { - + self primitiveFailed. } method > aNumber { - + self primitiveFailed. } method <= aNumber { - + self primitiveFailed. } method >= aNumber { - + self primitiveFailed. } method negated { - + ^0 - self. } diff --git a/moo/lib/exec.c b/moo/lib/exec.c index 0d22f70..e6b875d 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -2879,13 +2879,43 @@ static moo_pfrc_t pf_number_div (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) rcv = MOO_STACK_GETRCV(moo, nargs); arg = MOO_STACK_GETARG(moo, nargs, 0); - res = moo_divnums(moo, rcv, arg); + res = moo_divnums(moo, rcv, arg, 0); if (!res) return (moo->errnum == MOO_EINVAL? MOO_PF_FAILURE: MOO_PF_HARD_FAILURE); MOO_STACK_SETRET (moo, nargs, res); return MOO_PF_SUCCESS; } +static moo_pfrc_t pf_number_mdiv (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) +{ + moo_oop_t rcv, arg, res; + + MOO_ASSERT (moo, nargs == 1); + + rcv = MOO_STACK_GETRCV(moo, nargs); + arg = MOO_STACK_GETARG(moo, nargs, 0); + + res = moo_divnums(moo, rcv, arg, 1); + if (!res) return (moo->errnum == MOO_EINVAL? MOO_PF_FAILURE: MOO_PF_HARD_FAILURE); + + MOO_STACK_SETRET (moo, nargs, res); + return MOO_PF_SUCCESS; +} + +static moo_pfrc_t pf_number_negated (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) +{ + moo_oop_t rcv, res; + + MOO_ASSERT (moo, nargs == 0); + + rcv = MOO_STACK_GETRCV(moo, nargs); + + res = moo_negatenum(moo, rcv); + if (!res) return (moo->errnum == MOO_EINVAL? MOO_PF_FAILURE: MOO_PF_HARD_FAILURE); + + MOO_STACK_SETRET (moo, nargs, res); + return MOO_PF_SUCCESS; +} static moo_pfrc_t pf_number_eq (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) { @@ -2919,6 +2949,70 @@ static moo_pfrc_t pf_number_ne (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) return MOO_PF_SUCCESS; } +static moo_pfrc_t pf_number_lt (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) +{ + moo_oop_t rcv, arg, res; + + MOO_ASSERT (moo, nargs == 1); + + rcv = MOO_STACK_GETRCV(moo, nargs); + arg = MOO_STACK_GETARG(moo, nargs, 0); + + res = moo_ltnums(moo, rcv, arg); + if (!res) return (moo->errnum == MOO_EINVAL? MOO_PF_FAILURE: MOO_PF_HARD_FAILURE); + + MOO_STACK_SETRET (moo, nargs, res); + return MOO_PF_SUCCESS; +} + +static moo_pfrc_t pf_number_gt (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) +{ + moo_oop_t rcv, arg, res; + + MOO_ASSERT (moo, nargs == 1); + + rcv = MOO_STACK_GETRCV(moo, nargs); + arg = MOO_STACK_GETARG(moo, nargs, 0); + + res = moo_gtnums(moo, rcv, arg); + if (!res) return (moo->errnum == MOO_EINVAL? MOO_PF_FAILURE: MOO_PF_HARD_FAILURE); + + MOO_STACK_SETRET (moo, nargs, res); + return MOO_PF_SUCCESS; +} + +static moo_pfrc_t pf_number_le (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) +{ + moo_oop_t rcv, arg, res; + + MOO_ASSERT (moo, nargs == 1); + + rcv = MOO_STACK_GETRCV(moo, nargs); + arg = MOO_STACK_GETARG(moo, nargs, 0); + + res = moo_lenums(moo, rcv, arg); + if (!res) return (moo->errnum == MOO_EINVAL? MOO_PF_FAILURE: MOO_PF_HARD_FAILURE); + + MOO_STACK_SETRET (moo, nargs, res); + return MOO_PF_SUCCESS; +} + +static moo_pfrc_t pf_number_ge (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) +{ + moo_oop_t rcv, arg, res; + + MOO_ASSERT (moo, nargs == 1); + + rcv = MOO_STACK_GETRCV(moo, nargs); + arg = MOO_STACK_GETARG(moo, nargs, 0); + + res = moo_genums(moo, rcv, arg); + if (!res) return (moo->errnum == MOO_EINVAL? MOO_PF_FAILURE: MOO_PF_HARD_FAILURE); + + MOO_STACK_SETRET (moo, nargs, res); + return MOO_PF_SUCCESS; +} + /* ------------------------------------------------------------------ */ static moo_pfrc_t pf_integer_add (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) { @@ -3040,7 +3134,7 @@ static moo_pfrc_t pf_integer_negated (moo_t* moo, moo_mod_t* mod, moo_ooi_t narg rcv = MOO_STACK_GETRCV(moo, nargs); - res = moo_negateint (moo, rcv); + res = moo_negateint(moo, rcv); if (!res) return (moo->errnum == MOO_EINVAL? MOO_PF_FAILURE: MOO_PF_HARD_FAILURE); MOO_STACK_SETRET (moo, nargs, res); @@ -3754,8 +3848,14 @@ static pf_t pftab[] = { "_number_add", { pf_number_add, 1, 1 } }, { "_number_div", { pf_number_div, 1, 1 } }, { "_number_eq", { pf_number_eq, 1, 1 } }, + { "_number_ge", { pf_number_ge, 1, 1 } }, + { "_number_gt", { pf_number_gt, 1, 1 } }, + { "_number_le", { pf_number_le, 1, 1 } }, + { "_number_lt", { pf_number_lt, 1, 1 } }, + { "_number_mdiv", { pf_number_mdiv, 1, 1 } }, { "_number_mul", { pf_number_mul, 1, 1 } }, { "_number_ne", { pf_number_ne, 1, 1 } }, + { "_number_negated", { pf_number_negated, 0, 0 } }, { "_number_sub", { pf_number_sub, 1, 1 } }, { "_utf8_seqlen", { moo_pf_utf8_seqlen, 0, 0 } }, diff --git a/moo/lib/moo-prv.h b/moo/lib/moo-prv.h index f9b7a7e..d91a014 100644 --- a/moo/lib/moo-prv.h +++ b/moo/lib/moo-prv.h @@ -1405,7 +1405,8 @@ moo_oop_t moo_mltnums ( moo_oop_t moo_divnums ( moo_t* moo, moo_oop_t x, - moo_oop_t y + moo_oop_t y, + int modulo ); moo_oop_t moo_gtnums ( @@ -1444,6 +1445,11 @@ moo_oop_t moo_nenums ( moo_oop_t y ); +moo_oop_t moo_negatenum ( + moo_t* moo, + moo_oop_t x +); + moo_oop_t moo_sqrtnum ( moo_t* moo, moo_oop_t x diff --git a/moo/lib/number.c b/moo/lib/number.c index 1ced6eb..a28908a 100644 --- a/moo/lib/number.c +++ b/moo/lib/number.c @@ -259,7 +259,7 @@ moo_oop_t moo_mltnums (moo_t* moo, moo_oop_t x, moo_oop_t y) return mul_nums(moo, x, y, 1); } -moo_oop_t moo_divnums (moo_t* moo, moo_oop_t x, moo_oop_t y) +moo_oop_t moo_divnums (moo_t* moo, moo_oop_t x, moo_oop_t y, int modulo) { moo_ooi_t xs, ys, i; moo_oop_t nv; @@ -304,7 +304,7 @@ moo_oop_t moo_divnums (moo_t* moo, moo_oop_t x, moo_oop_t y) } } - nv = moo_divints(moo, nv, yv, 0, MOO_NULL); + nv = moo_divints(moo, nv, yv, modulo, MOO_NULL); moo_popvolat (moo); if (!nv) return MOO_NULL; @@ -367,6 +367,28 @@ moo_oop_t moo_nenums (moo_t* moo, moo_oop_t x, moo_oop_t y) return comp_nums(moo, x, y, moo_neints); } + +moo_oop_t moo_negatenum (moo_t* moo, moo_oop_t x) +{ + if (!MOO_OOP_IS_FPDEC(moo, x)) + { + return moo_negateint(moo, x); + } + else + { + moo_oop_t v; + moo_ooi_t scale; + + scale = MOO_OOP_TO_SMOOI(((moo_oop_fpdec_t)x)->scale); + v = ((moo_oop_fpdec_t)x)->value; + + v = moo_negateint(moo, v); + if (!v) return MOO_NULL; + + return moo_makefpdec(moo, v, scale); + } +} + moo_oop_t moo_sqrtnum (moo_t* moo, moo_oop_t x) { if (!MOO_OOP_IS_FPDEC(moo, x)) @@ -411,10 +433,10 @@ moo_oop_t moo_absnum (moo_t* moo, moo_oop_t x) scale = MOO_OOP_TO_SMOOI(((moo_oop_fpdec_t)x)->scale); v = ((moo_oop_fpdec_t)x)->value; - + v = moo_absint(moo, v); if (!v) return MOO_NULL; - + return moo_makefpdec(moo, v, scale); } }