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]; return &style[kind];
} }
int hawk_arr_init (hawk_arr_t* arr, hawk_gem_t* gem, hawk_oow_t capa) int hawk_arr_init (hawk_arr_t* arr, hawk_gem_t* gem, hawk_oow_t capa)
{ {
HAWK_MEMSET (arr, 0, HAWK_SIZEOF(*arr)); HAWK_MEMSET (arr, 0, HAWK_SIZEOF(*arr));
arr->gem = gem; arr->gem = gem;
arr->size = 0; arr->size = 0;
arr->tally = 0;
arr->capa = 0; arr->capa = 0;
arr->slot = HAWK_NULL; arr->slot = HAWK_NULL;
arr->scale = 1; arr->scale = 1;
@ -170,6 +170,8 @@ void hawk_arr_fini (hawk_arr_t* arr)
hawk_gem_freemem (arr->gem, arr->slot); hawk_gem_freemem (arr->gem, arr->slot);
arr->slot = HAWK_NULL; arr->slot = HAWK_NULL;
arr->capa = 0; 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 (capa == arr->capa) return arr;
if (arr->size > capa) if (capa < arr->size)
{ {
/* to trigger freeers on the items truncated */ /* to trigger freeers on the items truncated */
hawk_arr_delete (arr, capa, arr->size - capa); 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; tmp = HAWK_NULL;
HAWK_ASSERT (arr->size == 0);
HAWK_ASSERT (arr->tally == 0);
} }
arr->slot = tmp; 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; if (pos > arr->size) arr->size = pos + 1;
else arr->size++; else arr->size++;
arr->tally++;
return pos; 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 */ /* no previous data */
arr->slot[pos] = alloc_slot(arr, dptr, dlen); arr->slot[pos] = alloc_slot(arr, dptr, dlen);
if (arr->slot[pos] == HAWK_NULL) return HAWK_ARR_NIL; if (arr->slot[pos] == HAWK_NULL) return HAWK_ARR_NIL;
arr->tally++;
} }
else 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++) for (i = index; i < index + count; i++)
{ {
slot_t* c = arr->slot[i]; slot_t* c = arr->slot[i];
if (c)
if (c != HAWK_NULL)
{ {
if (arr->style->freeer) arr->style->freeer (arr, DPTR(c), DLEN(c)); if (arr->style->freeer) arr->style->freeer (arr, DPTR(c), DLEN(c));
hawk_gem_freemem (arr->gem, c); hawk_gem_freemem (arr->gem, c);
arr->slot[i] = HAWK_NULL; arr->slot[i] = HAWK_NULL;
arr->tally--;
} }
} }
for (i = index + count; i < arr->size; i++) 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; arr->size -= count;
return 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++) for (i = index; i < index + count; i++)
{ {
slot_t* c = arr->slot[i]; slot_t* c = arr->slot[i];
if (c)
if (c != HAWK_NULL)
{ {
if (arr->style->freeer) arr->style->freeer (arr, DPTR(c), DLEN(c)); if (arr->style->freeer) arr->style->freeer (arr, DPTR(c), DLEN(c));
hawk_gem_freemem (arr->gem, c); hawk_gem_freemem (arr->gem, c);
arr->slot[i] = HAWK_NULL; arr->slot[i] = HAWK_NULL;
arr->tally--;
} }
} }
@ -474,6 +481,7 @@ void hawk_arr_clear (hawk_arr_t* arr)
} }
arr->size = 0; arr->size = 0;
arr->tally = 0;
} }
hawk_oow_t hawk_arr_walk (hawk_arr_t* arr, walker_t walker, void* ctx) 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 */ /* empty the last slot */
arr->slot[arr->size] = HAWK_NULL; 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) 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); len = HAWK_MAP_SIZE(((hawk_val_map_t*)v)->map);
break; break;
case HAWK_VAL_ARR: case HAWK_VAL_ARR: /* returns the number of set items instead of the last index + 1 */
len = HAWK_ARR_SIZE(((hawk_val_arr_t*)v)->arr); len = HAWK_ARR_TALLY(((hawk_val_arr_t*)v)->arr);
break; break;
case HAWK_VAL_STR: 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_NIL ((hawk_oow_t)-1)
#define HAWK_ARR_SIZE(arr) (*(const hawk_oow_t*)&(arr)->size) #define HAWK_ARR_SIZE(arr) ((arr)->size)
#define HAWK_ARR_CAPA(arr) (*(const hawk_oow_t*)&(arr)->capa) #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_SLOT(arr,index) ((arr)->slot[index])
#define HAWK_ARR_DPTL(arr,index) ((const hawk_ptl_t*)&(arr)->slot[index]->val) #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 hawk_oow_t heap_pos_offset; /* offset in the data element where position
* is stored when heap operation is performed. */ * is stored when heap operation is performed. */
hawk_oow_t size; /* number of items */ hawk_oow_t size; /* number of items */
hawk_oow_t tally; /* number of items set */
hawk_oow_t capa; /* capacity */ hawk_oow_t capa; /* capacity */
hawk_arr_slot_t** slot; 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; 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) static int fnc_map (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
{ {
hawk_val_t* tmp; hawk_val_t* tmp;
@ -327,6 +365,9 @@ static fnctab_t fnctab[] =
{ {
/* keep this table sorted for binary search in query(). */ /* keep this table sorted for binary search in query(). */
{ HAWK_T("array"), { { 0, A_MAX }, fnc_array, 0 } }, { 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("call"), { { 1, A_MAX, HAWK_T("vR") }, fnc_call, 0 } },
{ HAWK_T("function_exists"), { { 1, 1, HAWK_NULL }, fnc_function_exists, 0 } }, { HAWK_T("function_exists"), { { 1, 1, HAWK_NULL }, fnc_function_exists, 0 } },
{ HAWK_T("gc"), { { 0, 1, HAWK_NULL }, fnc_gc, 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); ensure (a[0][40], "bye", SCRIPTNAME);
call_by_ref_3(a[0][40]); call_by_ref_3(a[0][40]);
ensure (a[0][40], "hello world", SCRIPTNAME); 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]; 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][0], "farewell", SCRIPTNAME);
ensure (a[0][40], nil, SCRIPTNAME); ensure (a[0][40], nil, SCRIPTNAME);
#hawk::splice (a[0], 40, 1); #hawk::splice (a[0], 40, 1, SCRIPTNAME);
#ensure (length(a[0]), 40); #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" print "SUCCESS"