changed some numeric primitives to support fpdec

This commit is contained in:
hyunghwan.chung 2019-01-09 16:07:27 +00:00
parent 29f7058ebf
commit c62a0ce3c5
4 changed files with 125 additions and 24 deletions

View File

@ -110,26 +110,26 @@ class(#limited) Number(Magnitude)
{ {
method + aNumber method + aNumber
{ {
<primitive: #_integer_add> <primitive: #_number_add>
self primitiveFailed. self primitiveFailed.
} }
method - aNumber method - aNumber
{ {
<primitive: #_integer_sub> <primitive: #_number_sub>
self primitiveFailed. self primitiveFailed.
} }
method * aNumber method * aNumber
{ {
<primitive: #_integer_mul> <primitive: #_number_mul>
self primitiveFailed. self primitiveFailed.
} }
method div: aNumber method div: aNumber
{ {
## integer division rounded toward zero ## integer division rounded toward zero
<primitive: #_integer_div> <primitive: #_number_div>
self primitiveFailed. self primitiveFailed.
} }
@ -161,13 +161,13 @@ class(#limited) Number(Magnitude)
method = aNumber method = aNumber
{ {
<primitive: #_integer_eq> <primitive: #_number_eq>
self primitiveFailed. self primitiveFailed.
} }
method ~= aNumber method ~= aNumber
{ {
<primitive: #_integer_ne> <primitive: #_number_ne>
self primitiveFailed. self primitiveFailed.
} }

View File

@ -711,7 +711,6 @@ static moo_oop_t string_to_fpdec (moo_t* moo, moo_oocs_t* str)
moo_oop_t v; moo_oop_t v;
int base = 10; int base = 10;
MOO_DEBUG2 (moo, "string to fpdec... %.*js\n", str->len, str->ptr);
pos = str->len; pos = str->len;
while (pos > 0) while (pos > 0)
{ {
@ -1493,13 +1492,12 @@ static int get_numlit (moo_t* moo, int negated)
} }
while (is_digitchar(c)); 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? /* 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. */ * 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); SET_TOKEN_TYPE (moo, MOO_IOTOK_FPDECLIT);
unget_char (moo, &moo->c->lxc);
} }
} }
else else

View File

@ -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) static moo_pfrc_t pf_integer_add (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
{ {
moo_oop_t rcv, arg, res; moo_oop_t rcv, arg, res;
@ -3653,6 +3751,13 @@ static pf_t pftab[] =
{ "_integer_rem", { pf_integer_rem, 1, 1 } }, { "_integer_rem", { pf_integer_rem, 1, 1 } },
{ "_integer_sub", { pf_integer_sub, 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_seqlen", { moo_pf_utf8_seqlen, 0, 0 } },
{ "_utf8_to_uc", { moo_pf_utf8_to_uc, 0, 0 } }, { "_utf8_to_uc", { moo_pf_utf8_to_uc, 0, 0 } },
}; };

View File

@ -26,8 +26,6 @@
#include "moo-prv.h" #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_t moo_makefpdec (moo_t* moo, moo_oop_t value, moo_ooi_t scale)
{ {
moo_oop_fpdec_t fpdec; 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; xs = 0;
xv = *x; 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); xs = MOO_OOP_TO_SMOOI(((moo_oop_fpdec_t)xv)->scale);
xv = ((moo_oop_fpdec_t)xv)->value; 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); moo_seterrbfmt (moo, MOO_EINVAL, "parameter not numeric - %O", xv);
return -1; return -1;
} }
ys = 0; ys = 0;
yv = *y; 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); ys = MOO_OOP_TO_SMOOI(((moo_oop_fpdec_t)yv)->scale);
yv = ((moo_oop_fpdec_t)yv)->value; 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) 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 */ /* both are probably integers */
return moo_addints(moo, x, y); 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) 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 */ /* both are probably integers */
return moo_subints(moo, x, y); 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; xs = 0;
xv = x; 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); xs = MOO_OOP_TO_SMOOI(((moo_oop_fpdec_t)xv)->scale);
xv = ((moo_oop_fpdec_t)xv)->value; 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; ys = 0;
yv = y; 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); ys = MOO_OOP_TO_SMOOI(((moo_oop_fpdec_t)yv)->scale);
yv = ((moo_oop_fpdec_t)yv)->value; 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; xs = 0;
xv = x; 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); xs = MOO_OOP_TO_SMOOI(((moo_oop_fpdec_t)xv)->scale);
xv = ((moo_oop_fpdec_t)xv)->value; 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; ys = 0;
yv = y; 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); ys = MOO_OOP_TO_SMOOI(((moo_oop_fpdec_t)yv)->scale);
yv = ((moo_oop_fpdec_t)yv)->value; 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)) 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 */ /* both are probably integers */
return comper(moo, x, y); 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) 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); 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) 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); return moo_absint(moo, x);
} }