changed STIX_SMOOI_MIN to -STIX_SMOOI_MAX instead of (-STIX_SMOOI_MAX - 1)
fixed tally range check bugs in dic.c/sym.c/gc.c simplificed some code resulting from STIX_SMOOI_MIN change.
This commit is contained in:
parent
5cebf7e8dc
commit
f618154aaf
@ -115,18 +115,15 @@
|
||||
{
|
||||
}
|
||||
|
||||
#class(#halfword) LargeInteger(Number)
|
||||
## #class(#word) LargeInteger(Number)
|
||||
#class(#liword) LargeInteger(Number)
|
||||
{
|
||||
}
|
||||
|
||||
#class(#halfword) LargePositiveInteger(LargeInteger)
|
||||
## #class(#word) LargePositiveInteger(LargeInteger)
|
||||
#class(#liword) LargePositiveInteger(LargeInteger)
|
||||
{
|
||||
}
|
||||
|
||||
#class(#halfword) LargeNegativeInteger(LargeInteger)
|
||||
## #class(#word) LargeNegativeInteger(LargeInteger)
|
||||
#class(#liword) LargeNegativeInteger(LargeInteger)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -266,6 +266,7 @@ PROCESS TESTING
|
||||
##(-16rFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF * 1) dump.
|
||||
##((-2305843009213693952 * -1) - 1 + 2) dump.
|
||||
((-2305843009213693952 * -2305843009213693952 * 2305843009213693952 * 2305843009213693952 * 2305843009213693952) - 1 + 2) dump.
|
||||
|
||||
|
||||
(2r111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 * 128971234897128931) dump.
|
||||
|
||||
|
@ -304,7 +304,7 @@ static stix_oop_t normalize_bigint (stix_t* stix, stix_oop_t oop)
|
||||
count = count_effective_digits (oop);
|
||||
|
||||
#if defined(STIX_USE_FULL_WORD)
|
||||
if (count == 1)
|
||||
if (count == 1) /* 1 word */
|
||||
{
|
||||
stix_oow_t w;
|
||||
|
||||
@ -315,13 +315,13 @@ static stix_oop_t normalize_bigint (stix_t* stix, stix_oop_t oop)
|
||||
}
|
||||
else
|
||||
{
|
||||
STIX_ASSERT (-STIX_SMOOI_MAX == STIX_SMOOI_MIN);
|
||||
STIX_ASSERT (STIX_OBJ_GET_CLASS(oop) == stix->_large_negative_integer);
|
||||
/*if (w <= -STIX_SMOOI_MIN) */
|
||||
if (w <= ((stix_oow_t)STIX_SMOOI_MAX + 1)) return STIX_SMOOI_TO_OOP(-(stix_ooi_t)w);
|
||||
if (w <= STIX_SMOOI_MAX) return STIX_SMOOI_TO_OOP(-(stix_ooi_t)w);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (count == 1)
|
||||
if (count == 1) /* 1 half-word */
|
||||
{
|
||||
if (STIX_OBJ_GET_CLASS(oop) == stix->_large_positive_integer)
|
||||
{
|
||||
@ -330,10 +330,10 @@ static stix_oop_t normalize_bigint (stix_t* stix, stix_oop_t oop)
|
||||
else
|
||||
{
|
||||
STIX_ASSERT (STIX_OBJ_GET_CLASS(oop) == stix->_large_negative_integer);
|
||||
return STIX_SMOOI_TO_OOP(-(stix_oow_t)((stix_oop_liword_t)oop)->slot[0]);
|
||||
return STIX_SMOOI_TO_OOP(-(stix_ooi_t)((stix_oop_liword_t)oop)->slot[0]);
|
||||
}
|
||||
}
|
||||
else if (count == 2)
|
||||
else if (count == 2) /* 2 half-words */
|
||||
{
|
||||
stix_oow_t w;
|
||||
|
||||
@ -344,9 +344,9 @@ static stix_oop_t normalize_bigint (stix_t* stix, stix_oop_t oop)
|
||||
}
|
||||
else
|
||||
{
|
||||
STIX_ASSERT (-STIX_SMOOI_MAX == STIX_SMOOI_MIN);
|
||||
STIX_ASSERT (STIX_OBJ_GET_CLASS(oop) == stix->_large_negative_integer);
|
||||
/*if (w <= -STIX_SMOOI_MIN) */
|
||||
if (w <= ((stix_oow_t)STIX_SMOOI_MAX + 1)) return STIX_SMOOI_TO_OOP(-(stix_ooi_t)w);
|
||||
if (w <= STIX_SMOOI_MAX) return STIX_SMOOI_TO_OOP(-(stix_ooi_t)w);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -632,6 +632,40 @@ static STIX_INLINE void rshift_unsigned_array (stix_liw_t* x, stix_oow_t xs, sti
|
||||
STIX_MEMSET (&x[xs - word_shifts], 0, word_shifts * STIX_SIZEOF(stix_liw_t));
|
||||
}
|
||||
|
||||
static void divide_unsigned_array (
|
||||
const stix_liw_t* x, stix_oow_t xs,
|
||||
const stix_liw_t* y, stix_oow_t ys,
|
||||
stix_liw_t* q, stix_liw_t* r)
|
||||
{
|
||||
/* TODO: this function needs to be rewritten for performance improvement. */
|
||||
|
||||
/* Perform binary long division.
|
||||
* http://en.wikipedia.org/wiki/Division_algorithm
|
||||
* ---------------------------------------------------------------------
|
||||
* Q := 0 initialize quotient and remainder to zero
|
||||
* R := 0
|
||||
* for i = n-1...0 do where n is number of bits in N
|
||||
* R := R << 1 left-shift R by 1 bit
|
||||
* R(0) := X(i) set the least-significant bit of R equal to bit i of the numerator
|
||||
* if R >= Y then
|
||||
* R = R - Y
|
||||
* Q(i) := 1
|
||||
* end
|
||||
* end
|
||||
*/
|
||||
|
||||
stix_liw_t* d;
|
||||
stix_oow_t ds;
|
||||
|
||||
/* TODO: */
|
||||
while (!is_less_unsigned_array (d, ds, y, ys)) /* while (y <= d) */
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
STIX_MEMCPY (r, d, ds);
|
||||
}
|
||||
|
||||
static stix_oop_t add_unsigned_integers (stix_t* stix, stix_oop_t x, stix_oop_t y)
|
||||
{
|
||||
stix_liw_t* a, * b;
|
||||
@ -981,6 +1015,7 @@ printf ("%0*lX ", (int)(STIX_SIZEOF(stix_liw_t) * 2), (unsigned long)((stix_oop_
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
lshift_unsigned_array (((stix_oop_liword_t)z)->slot, STIX_OBJ_GET_SIZE(z), 16 * 5 + 4);
|
||||
{ int i;
|
||||
printf ("LSHIFT10=>");
|
||||
@ -989,7 +1024,7 @@ for (i = STIX_OBJ_GET_SIZE(z); i > 0;)
|
||||
printf ("%0*lX ", (int)(STIX_SIZEOF(stix_liw_t) * 2), (unsigned long)((stix_oop_liword_t)z)->slot[--i]);
|
||||
}
|
||||
printf ("\n");
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
return normalize_bigint (stix, z);
|
||||
@ -1001,6 +1036,80 @@ oops_einval:
|
||||
|
||||
stix_oop_t stix_divints (stix_t* stix, stix_oop_t x, stix_oop_t y, stix_oop_t* rem)
|
||||
{
|
||||
stix_oop_t t;
|
||||
|
||||
if (STIX_OOP_IS_SMOOI(x) && STIX_OOP_IS_SMOOI(y))
|
||||
{
|
||||
stix_ooi_t xv, yv, q, r;
|
||||
|
||||
xv = STIX_OOP_TO_SMOOI(x);
|
||||
yv = STIX_OOP_TO_SMOOI(y);
|
||||
|
||||
if (yv == 0)
|
||||
{
|
||||
stix->errnum = STIX_EDIVBY0;
|
||||
return STIX_NULL;
|
||||
}
|
||||
|
||||
q = xv / yv;
|
||||
STIX_ASSERT (STIX_IN_SMOOI_RANGE(q));
|
||||
|
||||
#if 1
|
||||
/* TODO : verify this... */
|
||||
r = xv - yv * q;
|
||||
STIX_ASSERT (STIX_IN_SMOOI_RANGE(r));
|
||||
|
||||
/* handle sign difference */
|
||||
if (r && ((yv ^ r) < 0))
|
||||
{
|
||||
/* if the sign bit is different betwen yv and r,
|
||||
* the sign bit of (yv ^ r) must be set */
|
||||
r += yv;
|
||||
--q;
|
||||
|
||||
STIX_ASSERT (STIX_IN_SMOOI_RANGE(r));
|
||||
}
|
||||
#else
|
||||
r = xv % yv;
|
||||
STIX_ASSERT (STIX_IN_SMOOI_RANGE(r));
|
||||
#endif
|
||||
|
||||
*rem = STIX_SMOOI_TO_OOP(r);
|
||||
return STIX_SMOOI_TO_OOP((stix_ooi_t)q);
|
||||
}
|
||||
else if (STIX_OOP_IS_SMOOI(x))
|
||||
{
|
||||
if (STIX_OOP_TO_SMOOI(x) == 0)
|
||||
{
|
||||
t = clone_bigint (stix, y, STIX_OBJ_GET_SIZE(y));
|
||||
if (!t) return STIX_NULL;
|
||||
|
||||
*rem = t;
|
||||
return STIX_SMOOI_TO_OOP(0);
|
||||
}
|
||||
}
|
||||
else if (STIX_OOP_IS_SMOOI(y))
|
||||
{
|
||||
stix_ooi_t yv;
|
||||
|
||||
if (yv == 0)
|
||||
{
|
||||
stix->errnum = STIX_EDIVBY0;
|
||||
return STIX_NULL;
|
||||
}
|
||||
else if (yv == 1)
|
||||
{
|
||||
t = clone_bigint (stix, x, STIX_OBJ_GET_SIZE(x));
|
||||
if (!t) return STIX_NULL;
|
||||
|
||||
*rem = STIX_SMOOI_TO_OOP(0);
|
||||
return t;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
|
||||
return STIX_NULL;
|
||||
}
|
||||
|
||||
@ -1229,7 +1338,8 @@ printf ("\n");
|
||||
w = hwp[0];
|
||||
if (neg)
|
||||
{
|
||||
if (w <= STIX_SMOOI_MAX + 1) return STIX_SMOOI_TO_OOP(-(stix_ooi_t)w);
|
||||
STIX_ASSERT (-STIX_SMOOI_MAX == STIX_SMOOI_MIN);
|
||||
if (w <= STIX_SMOOI_MAX) return STIX_SMOOI_TO_OOP(-(stix_ooi_t)w);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1243,7 +1353,8 @@ printf ("\n");
|
||||
w = MAKE_WORD(hwp[0], hwp[1]);
|
||||
if (neg)
|
||||
{
|
||||
if (w <= STIX_SMOOI_MAX + 1) return STIX_SMOOI_TO_OOP(-(stix_ooi_t)w);
|
||||
STIX_ASSERT (-STIX_SMOOI_MAX == STIX_SMOOI_MIN);
|
||||
if (w <= STIX_SMOOI_MAX) return STIX_SMOOI_TO_OOP(-(stix_ooi_t)w);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
100
stix/lib/comp.c
100
stix/lib/comp.c
@ -421,7 +421,6 @@ static int string_to_smint (stix_t* stix, stix_oocs_t* str, int radixed, stix_oo
|
||||
* it assumes a certain pre-sanity check on the string
|
||||
* done by the lexical analyzer */
|
||||
|
||||
/* TODO: handle floating point numbers, etc, handle radix */
|
||||
int v, negsign, base;
|
||||
const stix_ooch_t* ptr, * end;
|
||||
stix_oow_t value, old_value;
|
||||
@ -477,27 +476,16 @@ static int string_to_smint (stix_t* stix, stix_oocs_t* str, int radixed, stix_oo
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (negsign)
|
||||
STIX_ASSERT (-STIX_SMOOI_MAX == STIX_SMOOI_MIN);
|
||||
if (value > STIX_SMOOI_MAX)
|
||||
{
|
||||
/*if (value > -STIX_SMOOI_MIN) */
|
||||
if (value > ((stix_oow_t)STIX_SMOOI_MAX + 1))
|
||||
{
|
||||
stix->errnum = STIX_ERANGE;
|
||||
return -1;
|
||||
}
|
||||
*num = value;
|
||||
*num *= -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value > STIX_SMOOI_MAX)
|
||||
{
|
||||
stix->errnum = STIX_ERANGE;
|
||||
return -1;
|
||||
}
|
||||
*num = value;
|
||||
stix->errnum = STIX_ERANGE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*num = value;
|
||||
if (negsign) *num *= -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1860,7 +1848,7 @@ static int add_literal (stix_t* stix, stix_oop_t lit, stix_size_t* index)
|
||||
|
||||
static STIX_INLINE int add_character_literal (stix_t* stix, stix_ooch_t ch, stix_size_t* index)
|
||||
{
|
||||
return add_literal (stix, STIX_OOP_FROM_CHAR(ch), index);
|
||||
return add_literal (stix, STIX_CHAR_TO_OOP(ch), index);
|
||||
}
|
||||
|
||||
static int add_string_literal (stix_t* stix, const stix_oocs_t* str, stix_size_t* index)
|
||||
@ -3181,8 +3169,9 @@ static int __read_byte_array_literal (stix_t* stix, stix_oop_t* xlit)
|
||||
* than the range error must not occur */
|
||||
STIX_ASSERT (stix->errnum == STIX_ERANGE);
|
||||
|
||||
printf ("NOT IMPLEMENTED LARGE_INTEGER or ERROR?\n");
|
||||
stix->errnum = STIX_ENOIMPL;
|
||||
/* if the token is out of the SMOOI range, it's too big or
|
||||
* to small to be a byte */
|
||||
set_syntax_error (stix, STIX_SYNERR_BYTERANGE, &stix->c->tok.loc, &stix->c->tok.name);
|
||||
return -1;
|
||||
}
|
||||
else if (tmp < 0 || tmp > 255)
|
||||
@ -3233,28 +3222,13 @@ static int __read_array_literal (stix_t* stix, stix_oop_t* xlit)
|
||||
|
||||
case STIX_IOTOK_NUMLIT:
|
||||
case STIX_IOTOK_RADNUMLIT:
|
||||
{
|
||||
stix_ooi_t tmp;
|
||||
|
||||
if (string_to_smint(stix, &stix->c->tok.name, stix->c->tok.type == STIX_IOTOK_RADNUMLIT, &tmp) <= -1)
|
||||
{
|
||||
/* the token reader reads a valid token. no other errors
|
||||
* than the range error must not occur */
|
||||
STIX_ASSERT (stix->errnum == STIX_ERANGE);
|
||||
|
||||
/* TODO: IMPLMENET LARGE INTEGER */
|
||||
printf ("LARGE NOT IMPLEMENTED IN COMPILE_ARRAY_LITERAL\n");
|
||||
stix->errnum = STIX_ENOIMPL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
lit = STIX_SMOOI_TO_OOP(tmp);
|
||||
lit = string_to_num (stix, &stix->c->tok.name, stix->c->tok.type == STIX_IOTOK_RADNUMLIT);
|
||||
if (!lit) return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
case STIX_IOTOK_CHARLIT:
|
||||
STIX_ASSERT (stix->c->tok.name.len == 1);
|
||||
lit = STIX_OOP_FROM_CHAR(stix->c->tok.name.ptr[0]);
|
||||
lit = STIX_CHAR_TO_OOP(stix->c->tok.name.ptr[0]);
|
||||
break;
|
||||
|
||||
case STIX_IOTOK_STRLIT:
|
||||
@ -3540,28 +3514,8 @@ printf ("\tpush symbol literal %d\n", (int)index);
|
||||
case STIX_IOTOK_NUMLIT:
|
||||
case STIX_IOTOK_RADNUMLIT:
|
||||
{
|
||||
/* TODO: other types of numbers, negative numbers, etc */
|
||||
#if 0
|
||||
/* TODO: proper numbeic literal handling */
|
||||
stix_ooi_t tmp;
|
||||
|
||||
if (string_to_smint(stix, &stix->c->tok.name, stix->c->tok.type == STIX_IOTOK_RADNUMLIT, &tmp) <= -1)
|
||||
{
|
||||
/* the token reader reads a valid token. no other errors
|
||||
* than the range error must not occur */
|
||||
STIX_ASSERT (stix->errnum == STIX_ERANGE);
|
||||
|
||||
printf ("NOT IMPLEMENTED LARGE_INTEGER or ERROR?\n");
|
||||
stix->errnum = STIX_ENOIMPL;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("\tpush int literal\n");
|
||||
if (emit_push_smint_literal(stix, tmp) <= -1) return -1;
|
||||
}
|
||||
#else
|
||||
|
||||
/* TODO: floating pointer number */
|
||||
/* TODO: other types of numbers, etc */
|
||||
stix_oop_t tmp;
|
||||
tmp = string_to_num (stix, &stix->c->tok.name, stix->c->tok.type == STIX_IOTOK_RADNUMLIT);
|
||||
if (!tmp) return -1;
|
||||
@ -3576,7 +3530,6 @@ printf ("\tpush int literal\n");
|
||||
if (add_literal(stix, tmp, &index) <= -1 ||
|
||||
emit_single_param_instruction(stix, BCODE_PUSH_LITERAL_0, index) <= -1) return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
GET_TOKEN (stix);
|
||||
break;
|
||||
@ -4947,7 +4900,7 @@ printf ("\n");
|
||||
|
||||
case STIX_IOTOK_CHARLIT:
|
||||
STIX_ASSERT (stix->c->tok.name.len == 1);
|
||||
lit = STIX_OOP_FROM_CHAR(stix->c->tok.name.ptr[0]);
|
||||
lit = STIX_CHAR_TO_OOP(stix->c->tok.name.ptr[0]);
|
||||
goto add_literal;
|
||||
|
||||
case STIX_IOTOK_STRLIT:
|
||||
@ -4963,27 +4916,8 @@ printf ("\n");
|
||||
case STIX_IOTOK_NUMLIT:
|
||||
case STIX_IOTOK_RADNUMLIT:
|
||||
{
|
||||
#if 0
|
||||
stix_ooi_t tmp;
|
||||
|
||||
if (string_to_smint(stix, &stix->c->tok.name, stix->c->tok.type == STIX_IOTOK_RADNUMLIT, &tmp) <= -1)
|
||||
{
|
||||
/* the token reader reads a valid token. no other errors
|
||||
* than the range error must not occur */
|
||||
STIX_ASSERT (stix->errnum == STIX_ERANGE);
|
||||
|
||||
printf ("NOT IMPLEMENTED LARGE_INTEGER or ERROR?\n");
|
||||
stix->errnum = STIX_ENOIMPL;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
lit = STIX_SMOOI_TO_OOP(tmp);
|
||||
}
|
||||
#else
|
||||
lit = string_to_num (stix, &stix->c->tok.name, stix->c->tok.type == STIX_IOTOK_RADNUMLIT);
|
||||
if (!lit) return -1;
|
||||
#endif
|
||||
goto add_literal;
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,8 @@ static stix_oop_oop_t expand_bucket (stix_t* stix, stix_oop_oop_t oldbuc)
|
||||
|
||||
static stix_oop_association_t find_or_upsert (stix_t* stix, stix_oop_set_t dic, stix_oop_char_t key, stix_oop_t value)
|
||||
{
|
||||
stix_oow_t index, tally;
|
||||
stix_ooi_t tally;
|
||||
stix_oow_t index;
|
||||
stix_oop_association_t ass;
|
||||
stix_oow_t tmp_count = 0;
|
||||
|
||||
@ -75,6 +76,7 @@ static stix_oop_association_t find_or_upsert (stix_t* stix, stix_oop_set_t dic,
|
||||
|
||||
index = stix_hashchars(key->slot, STIX_OBJ_GET_SIZE(key)) % STIX_OBJ_GET_SIZE(dic->bucket);
|
||||
|
||||
/* find */
|
||||
while (dic->bucket->slot[index] != stix->_nil)
|
||||
{
|
||||
ass = (stix_oop_association_t)dic->bucket->slot[index];
|
||||
@ -86,7 +88,7 @@ static stix_oop_association_t find_or_upsert (stix_t* stix, stix_oop_set_t dic,
|
||||
stix_equalchars (key->slot, ((stix_oop_char_t)ass->key)->slot, STIX_OBJ_GET_SIZE(key)))
|
||||
{
|
||||
/* the value of STIX_NULL indicates no insertion or update. */
|
||||
if (value) ass->value = value;
|
||||
if (value) ass->value = value; /* update */
|
||||
return ass;
|
||||
}
|
||||
|
||||
@ -101,20 +103,34 @@ static stix_oop_association_t find_or_upsert (stix_t* stix, stix_oop_set_t dic,
|
||||
return STIX_NULL;
|
||||
}
|
||||
|
||||
/* the key is not found. insert it. */
|
||||
STIX_ASSERT (STIX_OOP_IS_SMOOI(dic->tally));
|
||||
tally = STIX_OOP_TO_SMOOI(dic->tally);
|
||||
if (tally >= STIX_SMOOI_MAX)
|
||||
{
|
||||
/* this built-in dictionary is not allowed to hold more than
|
||||
* STIX_SMOOI_MAX items for efficiency sake */
|
||||
stix->errnum = STIX_EDFULL;
|
||||
return STIX_NULL;
|
||||
}
|
||||
|
||||
stix_pushtmp (stix, (stix_oop_t*)&dic); tmp_count++;
|
||||
stix_pushtmp (stix, (stix_oop_t*)&key); tmp_count++;
|
||||
stix_pushtmp (stix, &value); tmp_count++;
|
||||
|
||||
tally = STIX_OOP_TO_SMOOI(dic->tally);
|
||||
/* no conversion to stix_oow_t is necessary for tally + 1.
|
||||
* the maximum value of tally is checked to be STIX_SMOOI_MAX - 1.
|
||||
* tally + 1 can produce at most STIX_SMOOI_MAX. above all,
|
||||
* STIX_SMOOI_MAX is way smaller than STIX_TYPE_MAX(stix_ooi_t). */
|
||||
if (tally + 1 >= STIX_OBJ_GET_SIZE(dic->bucket))
|
||||
{
|
||||
stix_oop_oop_t bucket;
|
||||
|
||||
/* TODO: make the growth policy configurable instead of growing
|
||||
it just before it gets full. The polcy can be grow it
|
||||
it just before it gets full. The polcy can be grow it
|
||||
if it's 70% full */
|
||||
|
||||
/* Enlarge the symbol table before it gets full to
|
||||
/* enlarge the bucket before it gets full to
|
||||
* make sure that it has at least one free slot left
|
||||
* after having added a new symbol. this is to help
|
||||
* traversal end at a _nil slot if no entry is found. */
|
||||
@ -138,6 +154,8 @@ static stix_oop_association_t find_or_upsert (stix_t* stix, stix_oop_set_t dic,
|
||||
ass->key = (stix_oop_t)key;
|
||||
ass->value = value;
|
||||
|
||||
/* the current tally must be less than the maximum value. otherwise,
|
||||
* it overflows after increment below */
|
||||
STIX_ASSERT (tally < STIX_SMOOI_MAX);
|
||||
dic->tally = STIX_SMOOI_TO_OOP(tally + 1);
|
||||
dic->bucket->slot[index] = (stix_oop_t)ass;
|
||||
|
@ -688,7 +688,7 @@ static int prim_basic_at (stix_t* stix, stix_ooi_t nargs)
|
||||
break;
|
||||
|
||||
case STIX_OBJ_TYPE_CHAR:
|
||||
v = STIX_OOP_FROM_CHAR(((stix_oop_char_t)rcv)->slot[idx]);
|
||||
v = STIX_CHAR_TO_OOP(((stix_oop_char_t)rcv)->slot[idx]);
|
||||
break;
|
||||
|
||||
case STIX_OBJ_TYPE_HALFWORD:
|
||||
@ -1491,7 +1491,7 @@ printf ("CALL MODE 222 ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPPORTED_MOD
|
||||
case 'c':
|
||||
{
|
||||
char r = dcCallChar (dc, f);
|
||||
ACTIVE_STACK_SETTOP (stix, STIX_OOP_FROM_CHAR(r));
|
||||
ACTIVE_STACK_SETTOP (stix, STIX_CHAR_TO_OOP(r));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -29,18 +29,25 @@
|
||||
static void compact_symbol_table (stix_t* stix, stix_oop_t _nil)
|
||||
{
|
||||
stix_oop_char_t symbol;
|
||||
stix_oow_t tally, index, i, x, y, z;
|
||||
stix_oow_t bucket_size;
|
||||
stix_oow_t i, x, y, z;
|
||||
stix_oow_t bucket_size, index;
|
||||
stix_ooi_t tally;
|
||||
|
||||
#if defined(STIX_SUPPORT_GC_DURING_IGNITION)
|
||||
if (!stix->symtab) return; /* symbol table has not been created */
|
||||
#endif
|
||||
|
||||
bucket_size = STIX_OBJ_GET_SIZE(stix->symtab->bucket);
|
||||
|
||||
/* the symbol table doesn't allow more data items than STIX_SMOOI_MAX.
|
||||
* so stix->symtab->tally must always be a small integer */
|
||||
STIX_ASSERT (STIX_OOP_IS_SMOOI(stix->symtab->tally));
|
||||
tally = STIX_OOP_TO_SMOOI(stix->symtab->tally);
|
||||
STIX_ASSERT (tally >= 0); /* it must not be less than 0 */
|
||||
if (tally <= 0) return;
|
||||
|
||||
/* NOTE: in theory, the bucket size can be greater than STIX_SMOOI_MAX
|
||||
* as it is an internal header field and is of an unsigned type */
|
||||
bucket_size = STIX_OBJ_GET_SIZE(stix->symtab->bucket);
|
||||
|
||||
for (index = 0; index < bucket_size; )
|
||||
{
|
||||
if (STIX_OBJ_GET_FLAGS_MOVED(stix->symtab->bucket->slot[index]))
|
||||
@ -79,6 +86,7 @@ static void compact_symbol_table (stix_t* stix, stix_oop_t _nil)
|
||||
tally--;
|
||||
}
|
||||
|
||||
STIX_ASSERT (tally >= 0);
|
||||
STIX_ASSERT (tally <= STIX_SMOOI_MAX);
|
||||
stix->symtab->tally = STIX_SMOOI_TO_OOP(tally);
|
||||
}
|
||||
|
@ -49,6 +49,8 @@ enum stix_errnum_t
|
||||
STIX_EINVAL, /**< invalid parameter or data */
|
||||
STIX_ERANGE, /**< range error. overflow and underflow */
|
||||
STIX_ENOENT, /**< no matching entry */
|
||||
STIX_EDFULL, /**< dictionary full */
|
||||
STIX_EDIVBY0, /**< divide by zero */
|
||||
STIX_EIOERR, /**< I/O error */
|
||||
STIX_EECERR, /**< encoding conversion error */
|
||||
|
||||
@ -157,12 +159,15 @@ typedef struct stix_obj_word_t* stix_oop_word_t;
|
||||
#define STIX_OOP_IS_CHAR(oop) (((stix_oow_t)oop) & STIX_OOP_TAG_CHAR)
|
||||
#define STIX_SMOOI_TO_OOP(num) ((stix_oop_t)((((stix_ooi_t)(num)) << STIX_OOP_TAG_BITS) | STIX_OOP_TAG_SMINT))
|
||||
#define STIX_OOP_TO_SMOOI(oop) (((stix_ooi_t)oop) >> STIX_OOP_TAG_BITS)
|
||||
#define STIX_OOP_FROM_CHAR(num) ((stix_oop_t)((((stix_oow_t)(num)) << STIX_OOP_TAG_BITS) | STIX_OOP_TAG_CHAR))
|
||||
#define STIX_CHAR_TO_OOP(num) ((stix_oop_t)((((stix_oow_t)(num)) << STIX_OOP_TAG_BITS) | STIX_OOP_TAG_CHAR))
|
||||
#define STIX_OOP_TO_CHAR(oop) (((stix_oow_t)oop) >> STIX_OOP_TAG_BITS)
|
||||
|
||||
#define STIX_SMINT_BITS (STIX_SIZEOF(stix_ooi_t) * 8 - STIX_OOP_TAG_BITS)
|
||||
#define STIX_SMOOI_MAX ((stix_ooi_t)(~((stix_oow_t)0) >> (STIX_OOP_TAG_BITS + 1)))
|
||||
#define STIX_SMOOI_MIN (-STIX_SMOOI_MAX - 1)
|
||||
/* Sacrificing 1 bit pattern for a negative SMOOI makes implementation
|
||||
* a lot eaisier in many parts */
|
||||
/*#define STIX_SMOOI_MIN (-STIX_SMOOI_MAX - 1)*/
|
||||
#define STIX_SMOOI_MIN (-STIX_SMOOI_MAX)
|
||||
#define STIX_IN_SMOOI_RANGE(ooi) ((ooi) >= STIX_SMOOI_MIN && (ooi) <= STIX_SMOOI_MAX)
|
||||
|
||||
/* TODO: There are untested code where smint is converted to stix_oow_t.
|
||||
|
@ -60,7 +60,8 @@ static stix_oop_oop_t expand_bucket (stix_t* stix, stix_oop_oop_t oldbuc)
|
||||
|
||||
static stix_oop_t find_or_make_symbol (stix_t* stix, const stix_ooch_t* ptr, stix_oow_t len, int create)
|
||||
{
|
||||
stix_oow_t index, tally;
|
||||
stix_ooi_t tally;
|
||||
stix_oow_t index;
|
||||
stix_oop_char_t symbol;
|
||||
|
||||
STIX_ASSERT (len > 0);
|
||||
@ -95,7 +96,21 @@ static stix_oop_t find_or_make_symbol (stix_t* stix, const stix_ooch_t* ptr, sti
|
||||
return STIX_NULL;
|
||||
}
|
||||
|
||||
/* make a new symbol and insert it */
|
||||
STIX_ASSERT (STIX_OOP_IS_SMOOI(stix->symtab->tally));
|
||||
tally = STIX_OOP_TO_SMOOI(stix->symtab->tally);
|
||||
if (tally >= STIX_SMOOI_MAX)
|
||||
{
|
||||
/* this built-in table is not allowed to hold more than
|
||||
* STIX_SMOOI_MAX items for efficiency sake */
|
||||
stix->errnum = STIX_EDFULL;
|
||||
return STIX_NULL;
|
||||
}
|
||||
|
||||
/* no conversion to stix_oow_t is necessary for tally + 1.
|
||||
* the maximum value of tally is checked to be STIX_SMOOI_MAX - 1.
|
||||
* tally + 1 can produce at most STIX_SMOOI_MAX. above all,
|
||||
* STIX_SMOOI_MAX is way smaller than STIX_TYPE_MAX(stix_ooi_t). */
|
||||
if (tally + 1 >= STIX_OBJ_GET_SIZE(stix->symtab->bucket))
|
||||
{
|
||||
stix_oop_oop_t bucket;
|
||||
@ -104,7 +119,7 @@ static stix_oop_t find_or_make_symbol (stix_t* stix, const stix_ooch_t* ptr, sti
|
||||
it just before it gets full. The polcy can be grow it
|
||||
if it's 70% full */
|
||||
|
||||
/* Enlarge the symbol table before it gets full to
|
||||
/* enlarge the symbol table before it gets full to
|
||||
* make sure that it has at least one free slot left
|
||||
* after having added a new symbol. this is to help
|
||||
* traversal end at a _nil slot if no entry is found. */
|
||||
|
Loading…
Reference in New Issue
Block a user