added stix_isint(), stix_inttooow(), stix_oowtoint().
added stix_eqints(), stix_neints(), stix_gtints(), stix_geints(), stix_ltints(), stix_leints(). enhanced some primitive handlers to support large integers
This commit is contained in:
225
stix/lib/exec.c
225
stix/lib/exec.c
@ -650,14 +650,9 @@ static int prim_basic_new_with_size (stix_t* stix, stix_ooi_t nargs)
|
||||
}
|
||||
|
||||
szoop = ACTIVE_STACK_GET(stix, stix->sp);
|
||||
if (STIX_OOP_IS_SMOOI(szoop))
|
||||
if (stix_inttooow (stix, szoop, &size) <= 0)
|
||||
{
|
||||
size = STIX_OOP_TO_SMOOI(szoop);
|
||||
}
|
||||
/* TODO: support LargeInteger */
|
||||
else
|
||||
{
|
||||
/* size is not a proper numeric object */
|
||||
/* integer out of range or not integer */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -679,6 +674,40 @@ static int prim_basic_new_with_size (stix_t* stix, stix_ooi_t nargs)
|
||||
return 1; /* success */
|
||||
}
|
||||
|
||||
static int prim_ngc_new (stix_t* stix, stix_ooi_t nargs)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = prim_basic_new (stix, nargs);
|
||||
if (n <= 0) return n;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int prim_ngc_new_with_size (stix_t* stix, stix_ooi_t nargs)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = prim_basic_new_with_size (stix, nargs);
|
||||
if (n <= 0) return n;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int prim_ngc_dispose (stix_t* stix, stix_ooi_t nargs)
|
||||
{
|
||||
stix_oop_t rcv;
|
||||
|
||||
STIX_ASSERT (nargs == 0);
|
||||
rcv = ACTIVE_STACK_GETTOP (stix);
|
||||
|
||||
stix_freemem (stix, rcv);
|
||||
|
||||
ACTIVE_STACK_SETTOP (stix, stix->_nil);
|
||||
return 1; /* success */
|
||||
}
|
||||
|
||||
static int prim_shallow_copy (stix_t* stix, stix_ooi_t nargs)
|
||||
{
|
||||
stix_oop_t rcv, obj;
|
||||
@ -697,19 +726,23 @@ static int prim_shallow_copy (stix_t* stix, stix_ooi_t nargs)
|
||||
|
||||
static int prim_basic_size (stix_t* stix, stix_ooi_t nargs)
|
||||
{
|
||||
stix_oop_t rcv;
|
||||
stix_oop_t rcv, sz;
|
||||
|
||||
STIX_ASSERT (nargs == 0);
|
||||
|
||||
rcv = ACTIVE_STACK_GETTOP(stix);
|
||||
ACTIVE_STACK_SETTOP(stix, STIX_SMOOI_TO_OOP(STIX_OBJ_GET_SIZE(rcv)));
|
||||
/* TODO: use LargeInteger if the size is very big */
|
||||
|
||||
sz = stix_oowtoint (stix, STIX_OBJ_GET_SIZE(rcv));
|
||||
if (!sz) return -1; /* hard failure */
|
||||
ACTIVE_STACK_SETTOP(stix, sz);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int prim_basic_at (stix_t* stix, stix_ooi_t nargs)
|
||||
{
|
||||
stix_oop_t rcv, pos, v;
|
||||
stix_ooi_t idx;
|
||||
stix_oow_t idx;
|
||||
|
||||
STIX_ASSERT (nargs == 1);
|
||||
|
||||
@ -721,21 +754,18 @@ static int prim_basic_at (stix_t* stix, stix_ooi_t nargs)
|
||||
}
|
||||
|
||||
pos = ACTIVE_STACK_GET(stix, stix->sp);
|
||||
if (!STIX_OOP_IS_SMOOI(pos))
|
||||
if (stix_inttooow (stix, pos, &idx) <= 0)
|
||||
{
|
||||
/* TODO: handle LargeInteger */
|
||||
/* the position must be an integer */
|
||||
/* integer out of range or not integer */
|
||||
return 0;
|
||||
}
|
||||
|
||||
idx = STIX_OOP_TO_SMOOI(pos);
|
||||
if (idx < 1 || idx > STIX_OBJ_GET_SIZE(rcv))
|
||||
{
|
||||
/* index out of range */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* [NOTE] basicAt: and basicAt:put: used a 1-based index. */
|
||||
/* [NOTE] basicAt: and basicAt:put: uses a 1-based index. */
|
||||
idx = idx - 1;
|
||||
|
||||
switch (STIX_OBJ_GET_FLAGS_TYPE(rcv))
|
||||
@ -775,7 +805,7 @@ static int prim_basic_at (stix_t* stix, stix_ooi_t nargs)
|
||||
static int prim_basic_at_put (stix_t* stix, stix_ooi_t nargs)
|
||||
{
|
||||
stix_oop_t rcv, pos, val;
|
||||
stix_ooi_t idx;
|
||||
stix_oow_t idx;
|
||||
|
||||
STIX_ASSERT (nargs == 2);
|
||||
|
||||
@ -785,18 +815,14 @@ static int prim_basic_at_put (stix_t* stix, stix_ooi_t nargs)
|
||||
/* the receiver is a special numeric object, not a normal pointer */
|
||||
return 0;
|
||||
}
|
||||
|
||||
pos = ACTIVE_STACK_GET(stix, stix->sp - 1);
|
||||
if (!STIX_OOP_IS_SMOOI(pos))
|
||||
{
|
||||
/* TODO: handle LargeInteger */
|
||||
/* the position must be an integer */
|
||||
return 0;
|
||||
}
|
||||
|
||||
val = ACTIVE_STACK_GET(stix, stix->sp);
|
||||
|
||||
idx = STIX_OOP_TO_SMOOI(pos);
|
||||
if (stix_inttooow (stix, pos, &idx) <= 0)
|
||||
{
|
||||
/* integer out of range or not integer */
|
||||
return 0;
|
||||
}
|
||||
if (idx < 1 || idx > STIX_OBJ_GET_SIZE(rcv))
|
||||
{
|
||||
/* index out of range */
|
||||
@ -811,7 +837,7 @@ static int prim_basic_at_put (stix_t* stix, stix_ooi_t nargs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* [NOTE] basicAt: and basicAt:put: used a 1-based index. */
|
||||
/* [NOTE] basicAt: and basicAt:put: uses a 1-based index. */
|
||||
idx = idx - 1;
|
||||
|
||||
switch (STIX_OBJ_GET_FLAGS_TYPE(rcv))
|
||||
@ -847,7 +873,7 @@ static int prim_basic_at_put (stix_t* stix, stix_ooi_t nargs)
|
||||
break;
|
||||
|
||||
case STIX_OBJ_TYPE_WORD:
|
||||
/* TODO: handle largeINteger */
|
||||
/* TODO: handle LargeInteger */
|
||||
if (!STIX_OOP_IS_SMOOI(val))
|
||||
{
|
||||
/* the value is not a number */
|
||||
@ -1306,168 +1332,104 @@ static int prim_integer_bitshift (stix_t* stix, stix_ooi_t nargs)
|
||||
|
||||
static int prim_integer_eq (stix_t* stix, stix_ooi_t nargs)
|
||||
{
|
||||
stix_oop_t rcv, arg;
|
||||
stix_oop_t rcv, arg, res;
|
||||
|
||||
STIX_ASSERT (nargs == 1);
|
||||
|
||||
rcv = ACTIVE_STACK_GET(stix, stix->sp - 1);
|
||||
arg = ACTIVE_STACK_GET(stix, stix->sp);
|
||||
|
||||
if (STIX_OOP_IS_SMOOI(rcv) && STIX_OOP_IS_SMOOI(arg))
|
||||
{
|
||||
ACTIVE_STACK_POP (stix);
|
||||
if (STIX_OOP_TO_SMOOI(rcv) == STIX_OOP_TO_SMOOI(arg))
|
||||
{
|
||||
ACTIVE_STACK_SETTOP (stix, stix->_true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ACTIVE_STACK_SETTOP (stix, stix->_false);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
res = stix_eqints (stix, rcv, arg);
|
||||
if (!res) return (stix->errnum == STIX_EINVAL? 0: -1); /* soft or hard failure */
|
||||
|
||||
/* TODO: handle LargeInteger */
|
||||
return 0;
|
||||
ACTIVE_STACK_POP (stix);
|
||||
ACTIVE_STACK_SETTOP (stix, res);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int prim_integer_ne (stix_t* stix, stix_ooi_t nargs)
|
||||
{
|
||||
stix_oop_t rcv, arg;
|
||||
stix_oop_t rcv, arg, res;
|
||||
|
||||
STIX_ASSERT (nargs == 1);
|
||||
|
||||
rcv = ACTIVE_STACK_GET(stix, stix->sp - 1);
|
||||
arg = ACTIVE_STACK_GET(stix, stix->sp);
|
||||
|
||||
if (STIX_OOP_IS_SMOOI(rcv) && STIX_OOP_IS_SMOOI(arg))
|
||||
{
|
||||
ACTIVE_STACK_POP (stix);
|
||||
if (STIX_OOP_TO_SMOOI(rcv) != STIX_OOP_TO_SMOOI(arg))
|
||||
{
|
||||
ACTIVE_STACK_SETTOP (stix, stix->_true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ACTIVE_STACK_SETTOP (stix, stix->_false);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
res = stix_neints (stix, rcv, arg);
|
||||
if (!res) return (stix->errnum == STIX_EINVAL? 0: -1); /* soft or hard failure */
|
||||
|
||||
/* TODO: handle LargeInteger */
|
||||
return 0;
|
||||
ACTIVE_STACK_POP (stix);
|
||||
ACTIVE_STACK_SETTOP (stix, res);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int prim_integer_lt (stix_t* stix, stix_ooi_t nargs)
|
||||
{
|
||||
stix_oop_t rcv, arg;
|
||||
stix_oop_t rcv, arg, res;
|
||||
|
||||
STIX_ASSERT (nargs == 1);
|
||||
|
||||
rcv = ACTIVE_STACK_GET(stix, stix->sp - 1);
|
||||
arg = ACTIVE_STACK_GET(stix, stix->sp);
|
||||
|
||||
if (STIX_OOP_IS_SMOOI(rcv) && STIX_OOP_IS_SMOOI(arg))
|
||||
{
|
||||
ACTIVE_STACK_POP (stix);
|
||||
if (STIX_OOP_TO_SMOOI(rcv) < STIX_OOP_TO_SMOOI(arg))
|
||||
{
|
||||
ACTIVE_STACK_SETTOP (stix, stix->_true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ACTIVE_STACK_SETTOP (stix, stix->_false);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
res = stix_ltints (stix, rcv, arg);
|
||||
if (!res) return (stix->errnum == STIX_EINVAL? 0: -1); /* soft or hard failure */
|
||||
|
||||
/* TODO: handle LargeInteger */
|
||||
return 0;
|
||||
ACTIVE_STACK_POP (stix);
|
||||
ACTIVE_STACK_SETTOP (stix, res);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int prim_integer_gt (stix_t* stix, stix_ooi_t nargs)
|
||||
{
|
||||
stix_oop_t rcv, arg;
|
||||
stix_oop_t rcv, arg, res;
|
||||
|
||||
STIX_ASSERT (nargs == 1);
|
||||
|
||||
rcv = ACTIVE_STACK_GET(stix, stix->sp - 1);
|
||||
arg = ACTIVE_STACK_GET(stix, stix->sp);
|
||||
|
||||
if (STIX_OOP_IS_SMOOI(rcv) && STIX_OOP_IS_SMOOI(arg))
|
||||
{
|
||||
ACTIVE_STACK_POP (stix);
|
||||
if (STIX_OOP_TO_SMOOI(rcv) > STIX_OOP_TO_SMOOI(arg))
|
||||
{
|
||||
ACTIVE_STACK_SETTOP (stix, stix->_true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ACTIVE_STACK_SETTOP (stix, stix->_false);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
res = stix_gtints (stix, rcv, arg);
|
||||
if (!res) return (stix->errnum == STIX_EINVAL? 0: -1); /* soft or hard failure */
|
||||
|
||||
/* TODO: handle LargeInteger */
|
||||
return 0;
|
||||
ACTIVE_STACK_POP (stix);
|
||||
ACTIVE_STACK_SETTOP (stix, res);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int prim_integer_le (stix_t* stix, stix_ooi_t nargs)
|
||||
{
|
||||
stix_oop_t rcv, arg;
|
||||
stix_oop_t rcv, arg, res;
|
||||
|
||||
STIX_ASSERT (nargs == 1);
|
||||
|
||||
rcv = ACTIVE_STACK_GET(stix, stix->sp - 1);
|
||||
arg = ACTIVE_STACK_GET(stix, stix->sp);
|
||||
|
||||
if (STIX_OOP_IS_SMOOI(rcv) && STIX_OOP_IS_SMOOI(arg))
|
||||
{
|
||||
ACTIVE_STACK_POP (stix);
|
||||
if (STIX_OOP_TO_SMOOI(rcv) <= STIX_OOP_TO_SMOOI(arg))
|
||||
{
|
||||
ACTIVE_STACK_SETTOP (stix, stix->_true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ACTIVE_STACK_SETTOP (stix, stix->_false);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
res = stix_leints (stix, rcv, arg);
|
||||
if (!res) return (stix->errnum == STIX_EINVAL? 0: -1); /* soft or hard failure */
|
||||
|
||||
/* TODO: handle LargeInteger */
|
||||
return 0;
|
||||
ACTIVE_STACK_POP (stix);
|
||||
ACTIVE_STACK_SETTOP (stix, res);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int prim_integer_ge (stix_t* stix, stix_ooi_t nargs)
|
||||
{
|
||||
stix_oop_t rcv, arg;
|
||||
stix_oop_t rcv, arg, res;
|
||||
|
||||
STIX_ASSERT (nargs == 1);
|
||||
|
||||
rcv = ACTIVE_STACK_GET(stix, stix->sp - 1);
|
||||
arg = ACTIVE_STACK_GET(stix, stix->sp);
|
||||
|
||||
if (STIX_OOP_IS_SMOOI(rcv) && STIX_OOP_IS_SMOOI(arg))
|
||||
{
|
||||
ACTIVE_STACK_POP (stix);
|
||||
if (STIX_OOP_TO_SMOOI(rcv) >= STIX_OOP_TO_SMOOI(arg))
|
||||
{
|
||||
ACTIVE_STACK_SETTOP (stix, stix->_true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ACTIVE_STACK_SETTOP (stix, stix->_false);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
res = stix_geints (stix, rcv, arg);
|
||||
if (!res) return (stix->errnum == STIX_EINVAL? 0: -1); /* soft or hard failure */
|
||||
|
||||
return 0;
|
||||
ACTIVE_STACK_POP (stix);
|
||||
ACTIVE_STACK_SETTOP (stix, res);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int prim_integer_inttostr (stix_t* stix, stix_ooi_t nargs)
|
||||
@ -1829,6 +1791,9 @@ static prim_t primitives[] =
|
||||
|
||||
{ 0, prim_basic_new, "_basic_new" },
|
||||
{ 1, prim_basic_new_with_size, "_basic_new_with_size" },
|
||||
{ 0, prim_ngc_new, "_ngc_new" },
|
||||
{ 1, prim_ngc_new_with_size, "_ngc_new_with_size" },
|
||||
{ 0, prim_ngc_dispose, "_ngc_dispose" },
|
||||
{ 0, prim_shallow_copy, "_shallow_copy" },
|
||||
|
||||
{ 0, prim_basic_size, "_basic_size" },
|
||||
|
Reference in New Issue
Block a user