diff --git a/moo/kernel/Magnitu.moo b/moo/kernel/Magnitu.moo index 7cbea74..2eeade2 100644 --- a/moo/kernel/Magnitu.moo +++ b/moo/kernel/Magnitu.moo @@ -110,26 +110,26 @@ class(#limited) Number(Magnitude) { method + aNumber { - + self primitiveFailed. } method - aNumber { - + self primitiveFailed. } method * aNumber { - + self primitiveFailed. } method div: aNumber { ## integer division rounded toward zero - + self primitiveFailed. } @@ -161,13 +161,13 @@ class(#limited) Number(Magnitude) method = aNumber { - + self primitiveFailed. } method ~= aNumber { - + self primitiveFailed. } diff --git a/moo/lib/comp.c b/moo/lib/comp.c index 384fe52..0649b40 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -711,7 +711,6 @@ static moo_oop_t string_to_fpdec (moo_t* moo, moo_oocs_t* str) moo_oop_t v; int base = 10; -MOO_DEBUG2 (moo, "string to fpdec... %.*js\n", str->len, str->ptr); pos = str->len; while (pos > 0) { @@ -1493,13 +1492,12 @@ static int get_numlit (moo_t* moo, int negated) } while (is_digitchar(c)); - MOO_ASSERT (moo, scale > 0); + MOO_ASSERT (moo, scale > 0 && scale <= MOO_SMOOI_MAX); /* TODO: handle floating-point? fpdec if only suffixed with 's' like 1.23s4?, 'e','g' for floating point? * for now, there is no floating point support. as long as a point appears, it's a fpdec number. */ - -MOO_DEBUG2 (moo, "FPDEC LITERAL [%.*js]\n", TOKEN_NAME_LEN(moo), TOKEN_NAME_PTR(moo)); SET_TOKEN_TYPE (moo, MOO_IOTOK_FPDECLIT); + unget_char (moo, &moo->c->lxc); } } else diff --git a/moo/lib/exec.c b/moo/lib/exec.c index 5908139..0d22f70 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -2822,6 +2822,104 @@ static moo_pfrc_t pf_system_return_value_to_context (moo_t* moo, moo_mod_t* mod, /* ------------------------------------------------------------------ */ +static moo_pfrc_t pf_number_add (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_addnums(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_sub (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_subnums(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_mul (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_mulnums(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_div (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); + 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) +{ + 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_eqnums(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_ne (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_nenums(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) { moo_oop_t rcv, arg, res; @@ -3653,6 +3751,13 @@ static pf_t pftab[] = { "_integer_rem", { pf_integer_rem, 1, 1 } }, { "_integer_sub", { pf_integer_sub, 1, 1 } }, + { "_number_add", { pf_number_add, 1, 1 } }, + { "_number_div", { pf_number_div, 1, 1 } }, + { "_number_eq", { pf_number_eq, 1, 1 } }, + { "_number_mul", { pf_number_mul, 1, 1 } }, + { "_number_ne", { pf_number_ne, 1, 1 } }, + { "_number_sub", { pf_number_sub, 1, 1 } }, + { "_utf8_seqlen", { moo_pf_utf8_seqlen, 0, 0 } }, { "_utf8_to_uc", { moo_pf_utf8_to_uc, 0, 0 } }, }; diff --git a/moo/lib/number.c b/moo/lib/number.c index 5f1eee9..1ced6eb 100644 --- a/moo/lib/number.c +++ b/moo/lib/number.c @@ -26,8 +26,6 @@ #include "moo-prv.h" -#define MOO_IS_FPDEC(moo, x) (MOO_OBJ_GET_CLASS(x) == (moo)->_fixed_point_decimal) - moo_oop_t moo_makefpdec (moo_t* moo, moo_oop_t value, moo_ooi_t scale) { moo_oop_fpdec_t fpdec; @@ -62,7 +60,7 @@ static moo_ooi_t equalize_scale (moo_t* moo, moo_oop_t* x, moo_oop_t* y) xs = 0; xv = *x; - if (MOO_IS_FPDEC(moo, xv)) + if (MOO_OOP_IS_FPDEC(moo, xv)) { xs = MOO_OOP_TO_SMOOI(((moo_oop_fpdec_t)xv)->scale); xv = ((moo_oop_fpdec_t)xv)->value; @@ -72,10 +70,10 @@ static moo_ooi_t equalize_scale (moo_t* moo, moo_oop_t* x, moo_oop_t* y) moo_seterrbfmt (moo, MOO_EINVAL, "parameter not numeric - %O", xv); return -1; } - + ys = 0; yv = *y; - if (MOO_IS_FPDEC(moo, *y)) + if (MOO_OOP_IS_FPDEC(moo, yv)) { ys = MOO_OOP_TO_SMOOI(((moo_oop_fpdec_t)yv)->scale); yv = ((moo_oop_fpdec_t)yv)->value; @@ -143,7 +141,7 @@ moo_oop_t moo_truncfpdecval (moo_t* moo, moo_oop_t iv, moo_ooi_t cs, moo_ooi_t n moo_oop_t moo_addnums (moo_t* moo, moo_oop_t x, moo_oop_t y) { - if (!MOO_IS_FPDEC(moo, x) && !MOO_IS_FPDEC(moo, y)) + if (!MOO_OOP_IS_FPDEC(moo, x) && !MOO_OOP_IS_FPDEC(moo, y)) { /* both are probably integers */ return moo_addints(moo, x, y); @@ -172,7 +170,7 @@ moo_oop_t moo_addnums (moo_t* moo, moo_oop_t x, moo_oop_t y) moo_oop_t moo_subnums (moo_t* moo, moo_oop_t x, moo_oop_t y) { - if (!MOO_IS_FPDEC(moo, x) && !MOO_IS_FPDEC(moo, y)) + if (!MOO_OOP_IS_FPDEC(moo, x) && !MOO_OOP_IS_FPDEC(moo, y)) { /* both are probably integers */ return moo_subints(moo, x, y); @@ -207,7 +205,7 @@ static moo_oop_t mul_nums (moo_t* moo, moo_oop_t x, moo_oop_t y, int mult) xs = 0; xv = x; - if (MOO_IS_FPDEC(moo, xv)) + if (MOO_OOP_IS_FPDEC(moo, xv)) { xs = MOO_OOP_TO_SMOOI(((moo_oop_fpdec_t)xv)->scale); xv = ((moo_oop_fpdec_t)xv)->value; @@ -220,7 +218,7 @@ static moo_oop_t mul_nums (moo_t* moo, moo_oop_t x, moo_oop_t y, int mult) ys = 0; yv = y; - if (MOO_IS_FPDEC(moo, y)) + if (MOO_OOP_IS_FPDEC(moo, y)) { ys = MOO_OOP_TO_SMOOI(((moo_oop_fpdec_t)yv)->scale); yv = ((moo_oop_fpdec_t)yv)->value; @@ -269,7 +267,7 @@ moo_oop_t moo_divnums (moo_t* moo, moo_oop_t x, moo_oop_t y) xs = 0; xv = x; - if (MOO_IS_FPDEC(moo, xv)) + if (MOO_OOP_IS_FPDEC(moo, xv)) { xs = MOO_OOP_TO_SMOOI(((moo_oop_fpdec_t)xv)->scale); xv = ((moo_oop_fpdec_t)xv)->value; @@ -282,7 +280,7 @@ moo_oop_t moo_divnums (moo_t* moo, moo_oop_t x, moo_oop_t y) ys = 0; yv = y; - if (MOO_IS_FPDEC(moo, y)) + if (MOO_OOP_IS_FPDEC(moo, y)) { ys = MOO_OOP_TO_SMOOI(((moo_oop_fpdec_t)yv)->scale); yv = ((moo_oop_fpdec_t)yv)->value; @@ -315,7 +313,7 @@ moo_oop_t moo_divnums (moo_t* moo, moo_oop_t x, moo_oop_t y) static moo_oop_t comp_nums (moo_t* moo, moo_oop_t x, moo_oop_t y, moo_oop_t (*comper) (moo_t*, moo_oop_t, moo_oop_t)) { - if (!MOO_IS_FPDEC(moo, x) && !MOO_IS_FPDEC(moo, y)) + if (!MOO_OOP_IS_FPDEC(moo, x) && !MOO_OOP_IS_FPDEC(moo, y)) { /* both are probably integers */ return comper(moo, x, y); @@ -371,7 +369,7 @@ moo_oop_t moo_nenums (moo_t* moo, moo_oop_t x, moo_oop_t y) moo_oop_t moo_sqrtnum (moo_t* moo, moo_oop_t x) { - if (!MOO_IS_FPDEC(moo, x)) + if (!MOO_OOP_IS_FPDEC(moo, x)) { return moo_sqrtint(moo, x); } @@ -402,7 +400,7 @@ moo_oop_t moo_sqrtnum (moo_t* moo, moo_oop_t x) moo_oop_t moo_absnum (moo_t* moo, moo_oop_t x) { - if (!MOO_IS_FPDEC(moo, x)) + if (!MOO_OOP_IS_FPDEC(moo, x)) { return moo_absint(moo, x); }