aboutsummaryrefslogtreecommitdiff
path: root/builtins/array.h
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-02-04 21:13:50 -0500
committerBruce Hill <bruce@bruce-hill.com>2024-02-04 21:13:50 -0500
commitadde91636f04ae7544dba1ca5c6c1a40c074edb9 (patch)
treedfeb8c0c16fda6a87ef30b048b070ee4cb175a78 /builtins/array.h
parentb08a0d3e2bf45bae11c982dd24d0292d6436b993 (diff)
Builtins
Diffstat (limited to 'builtins/array.h')
-rw-r--r--builtins/array.h46
1 files changed, 46 insertions, 0 deletions
diff --git a/builtins/array.h b/builtins/array.h
new file mode 100644
index 00000000..5d0a2ee4
--- /dev/null
+++ b/builtins/array.h
@@ -0,0 +1,46 @@
+#pragma once
+#include <stdbool.h>
+#include <gc/cord.h>
+
+#include "../util.h"
+#include "datatypes.h"
+#include "functions.h"
+#include "types.h"
+
+void Array_insert(array_t *arr, const void *item, int64_t index, int64_t item_size);
+void Array_insert_all(array_t *arr, array_t to_insert, int64_t index, int64_t item_size);
+void Array_remove(array_t *arr, int64_t index, int64_t count, int64_t item_size);
+void Array_sort(array_t *arr, const TypeInfo *type);
+void Array_shuffle(array_t *arr, int64_t item_size);
+void Array_clear(array_t *array);
+void Array_compact(array_t *arr, int64_t item_size);
+bool Array_contains(array_t array, void *item, const TypeInfo *type);
+array_t Array_slice(array_t *array, int64_t first, int64_t stride, int64_t length, bool readonly, const TypeInfo *type);
+uint32_t Array_hash(const array_t *arr, const TypeInfo *type);
+int32_t Array_compare(const array_t *x, const array_t *y, const TypeInfo *type);
+bool Array_equal(const array_t *x, const array_t *y, const TypeInfo *type);
+CORD Array_cord(const array_t *arr, bool colorize, const TypeInfo *type);
+
+// Due to some C language weirdness, the type of "foo" is inferred to be `char[3]` instead of `const char*`
+// This is a hacky workaround to ensure that __typeof("foo") => `const char *`
+#define FIX_STR_LITERAL(s) _Generic(((void)0, s), char*: (const char*)s, default: s)
+
+#define ARRAY_OF(t) t**
+#define EMPTY_ARRAY(t) (t**)new(array_t)
+#define LENGTH(arr) (((array_t*)(arr))->length)
+#define ARRAY(x, ...) (__typeof(FIX_STR_LITERAL(x))**)new(array_t, \
+ .data=memcpy(GC_MALLOC(sizeof((__typeof(FIX_STR_LITERAL(x))[]){x, __VA_ARGS__})), (__typeof(FIX_STR_LITERAL(x))[]){x, __VA_ARGS__}, \
+ sizeof((__typeof(FIX_STR_LITERAL(x))[]){x, __VA_ARGS__})), \
+ .length=(sizeof((__typeof(FIX_STR_LITERAL(x))[]){x, __VA_ARGS__})) / sizeof(FIX_STR_LITERAL(x)), \
+ .stride=sizeof(FIX_STR_LITERAL(x)))
+#define STATIC_ARRAY(x, ...) ((array_t){ \
+ .data=(__typeof(FIX_STR_LITERAL(x))[]){x, __VA_ARGS__}, \
+ .length=(sizeof((__typeof(FIX_STR_LITERAL(x))[]){x, __VA_ARGS__})) / sizeof(FIX_STR_LITERAL(x)), \
+ .stride=sizeof(FIX_STR_LITERAL(x))})
+#define foreach(arr, var, last) for (__typeof(arr[0]) var = arr[0], last = ith_addr(arr, LENGTH(arr)-1); var && var <= last; var = ((void*)var) + ((array_t*)(arr))->stride)
+#define ith_addr(arr, i) ((__typeof(arr[0]))(((array_t*)(arr))->data + (i)*((array_t*)(arr))->stride))
+#define ith(arr, i) (*ith_addr(arr,i))
+#define append(arr, obj) Array_insert((array_t*)(arr), (__typeof((arr)[0][0])[]){obj}, 0, sizeof((arr)[0][0]))
+#define remove(arr, i) Array_remove((array_t*)(arr), (i)+1, 1, sizeof(arr[0][0]))
+
+// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0