diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2024-08-15 02:17:53 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2024-08-15 02:17:53 -0400 |
| commit | ed1667cb377dd8da51583e703c6677969addc993 (patch) | |
| tree | 531424aa9647ef49549000bb145e2b798c868154 | |
| parent | 7a472752e5be47816f756d854a1b0756594fef98 (diff) | |
Add array:shuffled() and checks for array insertion
| -rw-r--r-- | builtins/array.c | 13 | ||||
| -rw-r--r-- | builtins/array.h | 1 | ||||
| -rw-r--r-- | compile.c | 4 | ||||
| -rw-r--r-- | typecheck.c | 1 |
4 files changed, 17 insertions, 2 deletions
diff --git a/builtins/array.c b/builtins/array.c index d749778d..84a0b7a0 100644 --- a/builtins/array.c +++ b/builtins/array.c @@ -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) diff --git a/builtins/array.h b/builtins/array.h index 88184f8a..7d779677 100644 --- a/builtins/array.h +++ b/builtins/array.h @@ -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); @@ -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; diff --git a/typecheck.c b/typecheck.c index 2814bd03..52df81f3 100644 --- a/typecheck.c +++ b/typecheck.c @@ -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); |
