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

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)
{
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 } },
};

View File

@ -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);
}