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