changed length() over an array to return the number of items set.

added hawk::array_size() to return the last index + 1.
added hawk::array_tally() which works for an array only and acts like length()
This commit is contained in:
hyung-hwan 2020-04-29 13:03:02 +00:00
parent 881dfd2ce0
commit 0c184b6817
5 changed files with 103 additions and 16 deletions

View File

@ -145,13 +145,13 @@ const hawk_arr_style_t* hawk_get_arr_style (hawk_arr_style_kind_t kind)
return &style[kind];
}
int hawk_arr_init (hawk_arr_t* arr, hawk_gem_t* gem, hawk_oow_t capa)
{
HAWK_MEMSET (arr, 0, HAWK_SIZEOF(*arr));
arr->gem = gem;
arr->size = 0;
arr->tally = 0;
arr->capa = 0;
arr->slot = HAWK_NULL;
arr->scale = 1;
@ -170,6 +170,8 @@ void hawk_arr_fini (hawk_arr_t* arr)
hawk_gem_freemem (arr->gem, arr->slot);
arr->slot = HAWK_NULL;
arr->capa = 0;
arr->size = 0 ;
arr->tally = 0;
}
}
@ -217,7 +219,7 @@ hawk_arr_t* hawk_arr_setcapa (hawk_arr_t* arr, hawk_oow_t capa)
if (capa == arr->capa) return arr;
if (arr->size > capa)
if (capa < arr->size)
{
/* to trigger freeers on the items truncated */
hawk_arr_delete (arr, capa, arr->size - capa);
@ -238,6 +240,9 @@ hawk_arr_t* hawk_arr_setcapa (hawk_arr_t* arr, hawk_oow_t capa)
}
tmp = HAWK_NULL;
HAWK_ASSERT (arr->size == 0);
HAWK_ASSERT (arr->tally == 0);
}
arr->slot = tmp;
@ -359,6 +364,7 @@ hawk_oow_t hawk_arr_insert (hawk_arr_t* arr, hawk_oow_t pos, void* dptr, hawk_oo
if (pos > arr->size) arr->size = pos + 1;
else arr->size++;
arr->tally++;
return pos;
}
@ -379,6 +385,7 @@ hawk_oow_t hawk_arr_update (hawk_arr_t* arr, hawk_oow_t pos, void* dptr, hawk_oo
/* no previous data */
arr->slot[pos] = alloc_slot(arr, dptr, dlen);
if (arr->slot[pos] == HAWK_NULL) return HAWK_ARR_NIL;
arr->tally++;
}
else
{
@ -415,20 +422,20 @@ hawk_oow_t hawk_arr_delete (hawk_arr_t* arr, hawk_oow_t index, hawk_oow_t count)
for (i = index; i < index + count; i++)
{
slot_t* c = arr->slot[i];
if (c != HAWK_NULL)
if (c)
{
if (arr->style->freeer) arr->style->freeer (arr, DPTR(c), DLEN(c));
hawk_gem_freemem (arr->gem, c);
arr->slot[i] = HAWK_NULL;
arr->tally--;
}
}
for (i = index + count; i < arr->size; i++)
{
arr->slot[i-count] = arr->slot[i];
arr->slot[i - count] = arr->slot[i];
}
arr->slot[arr->size-1] = HAWK_NULL;
arr->slot[arr->size - 1] = HAWK_NULL;
arr->size -= count;
return count;
@ -446,12 +453,12 @@ hawk_oow_t hawk_arr_uplete (hawk_arr_t* arr, hawk_oow_t index, hawk_oow_t count)
for (i = index; i < index + count; i++)
{
slot_t* c = arr->slot[i];
if (c != HAWK_NULL)
if (c)
{
if (arr->style->freeer) arr->style->freeer (arr, DPTR(c), DLEN(c));
hawk_gem_freemem (arr->gem, c);
arr->slot[i] = HAWK_NULL;
arr->tally--;
}
}
@ -474,6 +481,7 @@ void hawk_arr_clear (hawk_arr_t* arr)
}
arr->size = 0;
arr->tally = 0;
}
hawk_oow_t hawk_arr_walk (hawk_arr_t* arr, walker_t walker, void* ctx)
@ -701,6 +709,7 @@ void hawk_arr_deleteheap (hawk_arr_t* arr, hawk_oow_t index)
/* empty the last slot */
arr->slot[arr->size] = HAWK_NULL;
arr->tally--;
}
hawk_oow_t hawk_arr_updateheap (hawk_arr_t* arr, hawk_oow_t index, void* dptr, hawk_oow_t dlen)

View File

@ -697,8 +697,8 @@ int hawk_fnc_length (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
len = HAWK_MAP_SIZE(((hawk_val_map_t*)v)->map);
break;
case HAWK_VAL_ARR:
len = HAWK_ARR_SIZE(((hawk_val_arr_t*)v)->arr);
case HAWK_VAL_ARR: /* returns the number of set items instead of the last index + 1 */
len = HAWK_ARR_TALLY(((hawk_val_arr_t*)v)->arr);
break;
case HAWK_VAL_STR:

View File

@ -56,8 +56,9 @@ typedef enum hawk_arr_walk_t hawk_arr_walk_t;
#define HAWK_ARR_NIL ((hawk_oow_t)-1)
#define HAWK_ARR_SIZE(arr) (*(const hawk_oow_t*)&(arr)->size)
#define HAWK_ARR_CAPA(arr) (*(const hawk_oow_t*)&(arr)->capa)
#define HAWK_ARR_SIZE(arr) ((arr)->size)
#define HAWK_ARR_CAPA(arr) ((arr)->capa)
#define HAWK_ARR_TALLY(arr) ((arr)->tally)
#define HAWK_ARR_SLOT(arr,index) ((arr)->slot[index])
#define HAWK_ARR_DPTL(arr,index) ((const hawk_ptl_t*)&(arr)->slot[index]->val)
@ -179,6 +180,7 @@ struct hawk_arr_t
hawk_oow_t heap_pos_offset; /* offset in the data element where position
* is stored when heap operation is performed. */
hawk_oow_t size; /* number of items */
hawk_oow_t tally; /* number of items set */
hawk_oow_t capa; /* capacity */
hawk_arr_slot_t** slot;
};

View File

@ -233,6 +233,44 @@ static int fnc_array (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
return 0;
}
static int fnc_array_size (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
{
hawk_val_t* a0;
hawk_oow_t iv;
a0 = hawk_rtx_getarg(rtx, 0);
if (HAWK_RTX_GETVALTYPE(rtx, a0) != HAWK_VAL_ARR)
{
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ENOTARR);
return -1;
}
iv = HAWK_ARR_SIZE(((hawk_val_arr_t*)a0)->arr);
HAWK_ASSERT (iv >= 0 && iv <= HAWK_QUICKINT_MAX);
hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, iv));
return 0;
}
static int fnc_array_tally (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
{
hawk_val_t* a0;
hawk_oow_t iv;
a0 = hawk_rtx_getarg(rtx, 0);
if (HAWK_RTX_GETVALTYPE(rtx, a0) != HAWK_VAL_ARR)
{
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ENOTARR);
return -1;
}
iv = HAWK_ARR_TALLY(((hawk_val_arr_t*)a0)->arr);
HAWK_ASSERT (iv >= 0 && iv <= HAWK_QUICKINT_MAX);
hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, iv));
return 0;
}
static int fnc_map (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
{
hawk_val_t* tmp;
@ -327,6 +365,9 @@ static fnctab_t fnctab[] =
{
/* keep this table sorted for binary search in query(). */
{ HAWK_T("array"), { { 0, A_MAX }, fnc_array, 0 } },
{ HAWK_T("array_size"), { { 1, 1 }, fnc_array_size, 0 } },
{ HAWK_T("array_tally"), { { 1, 1 }, fnc_array_tally, 0 } },
{ HAWK_T("call"), { { 1, A_MAX, HAWK_T("vR") }, fnc_call, 0 } },
{ HAWK_T("function_exists"), { { 1, 1, HAWK_NULL }, fnc_function_exists, 0 } },
{ HAWK_T("gc"), { { 0, 1, HAWK_NULL }, fnc_gc, 0 } },

View File

@ -94,13 +94,48 @@ function main()
ensure (a[0][40], "bye", SCRIPTNAME);
call_by_ref_3(a[0][40]);
ensure (a[0][40], "hello world", SCRIPTNAME);
ensure (length(a[0]), 41);
ensure (length(a[0]), 2, SCRIPTNAME);
ensure (hawk::array_size(a[0]), 41, SCRIPTNAME);
delete a[0][40];
ensure (length(a[0]), 41);
ensure (length(a[0]), 1, SCRIPTNAME);
ensure (hawk::array_size(a[0]), 41, SCRIPTNAME);
ensure (a[0][0], "farewell", SCRIPTNAME);
ensure (a[0][40], nil, SCRIPTNAME);
#hawk::splice (a[0], 40, 1);
#ensure (length(a[0]), 40);
#hawk::splice (a[0], 40, 1, SCRIPTNAME);
#ensure (length(a[0]), 40, SCRIPTNAME);
}
{
@local a, i;
a = hawk::array();
ensure (length(a), 0, SCRIPTNAME);
ensure (hawk::array_size(a), 0, SCRIPTNAME);
for (i = 0; i < 10; i++) a[i*i]=i;
ensure (length(a), 10, SCRIPTNAME);
ensure (hawk::array_size(a), 82, SCRIPTNAME);
delete a[0];
ensure (length(a), 9, SCRIPTNAME);
ensure (hawk::array_size(a), 82, SCRIPTNAME);
delete a[81];
ensure (length(a), 8, SCRIPTNAME);
ensure (hawk::array_size(a), 82, SCRIPTNAME);
delete a[36];
ensure (length(a), 7, SCRIPTNAME);
ensure (hawk::array_size(a), 82, SCRIPTNAME);
for (i = 0; i < 10; i++) delete a[i*i];
ensure (length(a), 0, SCRIPTNAME);
ensure (hawk::array_size(a), 82, SCRIPTNAME);
delete a;
ensure (length(a), 0, SCRIPTNAME);
ensure (hawk::array_size(a), 0, SCRIPTNAME);
}
print "SUCCESS"