Add array:shuffled() and checks for array insertion

This commit is contained in:
Bruce Hill 2024-08-15 02:17:53 -04:00
parent 7a472752e5
commit ed1667cb37
4 changed files with 17 additions and 2 deletions

View File

@ -54,7 +54,8 @@ public void Array$insert(array_t *arr, const void *item, Int_t int_index, int64_
if (index <= 0) index = arr->length + index + 1;
if (index < 1) index = 1;
else if (index > (int64_t)arr->length + 1) index = (int64_t)arr->length + 1;
else if (index > (int64_t)arr->length + 1)
fail("Invalid insertion index %ld for an array with length %ld", index, arr->length);
if (!arr->data) {
arr->free = 4;
@ -98,7 +99,8 @@ public void Array$insert_all(array_t *arr, array_t to_insert, Int_t int_index, i
if (index < 1) index = arr->length + index + 1;
if (index < 1) index = 1;
else if (index > (int64_t)arr->length + 1) index = (int64_t)arr->length + 1;
else if (index > (int64_t)arr->length + 1)
fail("Invalid insertion index %ld for an array with length %ld", index, arr->length);
if ((int64_t)arr->free >= (int64_t)to_insert.length // Adequate free space
&& arr->data_refcount == 0 // Not aliased memory
@ -219,6 +221,13 @@ public void Array$shuffle(array_t *arr, int64_t padded_item_size)
}
}
public array_t Array$shuffled(array_t arr, int64_t padded_item_size)
{
Array$compact(&arr, padded_item_size);
Array$shuffle(&arr, padded_item_size);
return arr;
}
public void *Array$random(array_t arr)
{
if (arr.length == 0)

View File

@ -62,6 +62,7 @@ void Array$remove(array_t *arr, Int_t index, Int_t count, int64_t padded_item_si
void Array$sort(array_t *arr, closure_t comparison, int64_t padded_item_size);
array_t Array$sorted(array_t arr, closure_t comparison, int64_t padded_item_size);
void Array$shuffle(array_t *arr, int64_t padded_item_size);
array_t Array$shuffled(array_t arr, int64_t padded_item_size);
void *Array$random(array_t arr);
#define Array$random_value(arr, t) ({ array_t _arr = arr; if (_arr.length == 0) fail("Cannot get a random value from an empty array!"); *(t*)Array$random(_arr); })
array_t Array$sample(array_t arr, Int_t n, array_t weights, int64_t padded_item_size);

View File

@ -2122,6 +2122,10 @@ CORD compile(env_t *env, ast_t *ast)
CORD self = compile_to_pointer_depth(env, call->self, 1, false);
(void)compile_arguments(env, ast, NULL, call->args);
return CORD_all("Array$shuffle(", self, ", ", padded_item_size, ")");
} else if (streq(call->name, "shuffled")) {
CORD self = compile_to_pointer_depth(env, call->self, 0, false);
(void)compile_arguments(env, ast, NULL, call->args);
return CORD_all("Array$shuffled(", self, ", ", padded_item_size, ")");
} else if (streq(call->name, "sort") || streq(call->name, "sorted")) {
CORD self = compile_to_pointer_depth(env, call->self, streq(call->name, "sort") ? 1 : 0, false);
CORD comparison;

View File

@ -716,6 +716,7 @@ type_t *get_type(env_t *env, ast_t *ast)
else if (streq(call->name, "sort")) return Type(VoidType);
else if (streq(call->name, "sorted")) return self_value_t;
else if (streq(call->name, "shuffle")) return Type(VoidType);
else if (streq(call->name, "shuffled")) return self_value_t;
else if (streq(call->name, "random")) return Match(self_value_t, ArrayType)->item_type;
else if (streq(call->name, "sample")) return self_value_t;
else if (streq(call->name, "clear")) return Type(VoidType);