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:
		| @ -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,12 +422,12 @@ 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--; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @ -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) | ||||
|  | ||||
| @ -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: | ||||
|  | ||||
| @ -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; | ||||
| }; | ||||
|  | ||||
| @ -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 } }, | ||||
|  | ||||
| @ -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" | ||||
|  | ||||
		Reference in New Issue
	
	Block a user