Rename array_t -> Array_t
This commit is contained in:
parent
c82b664db9
commit
abe45a3c25
@ -30,7 +30,7 @@ static inline int64_t get_padded_item_size(const TypeInfo *info)
|
||||
|
||||
// Replace the array's .data pointer with a new pointer to a copy of the
|
||||
// data that is compacted and has a stride of exactly `padded_item_size`
|
||||
public void Array$compact(array_t *arr, int64_t padded_item_size)
|
||||
public void Array$compact(Array_t *arr, int64_t padded_item_size)
|
||||
{
|
||||
void *copy = NULL;
|
||||
if (arr->length > 0) {
|
||||
@ -42,7 +42,7 @@ public void Array$compact(array_t *arr, int64_t padded_item_size)
|
||||
memcpy(copy + i*padded_item_size, arr->data + arr->stride*i, padded_item_size);
|
||||
}
|
||||
}
|
||||
*arr = (array_t){
|
||||
*arr = (Array_t){
|
||||
.data=copy,
|
||||
.length=arr->length,
|
||||
.stride=padded_item_size,
|
||||
@ -50,7 +50,7 @@ public void Array$compact(array_t *arr, int64_t padded_item_size)
|
||||
};
|
||||
}
|
||||
|
||||
public void Array$insert(array_t *arr, const void *item, Int_t int_index, int64_t padded_item_size)
|
||||
public void Array$insert(Array_t *arr, const void *item, Int_t int_index, int64_t padded_item_size)
|
||||
{
|
||||
int64_t index = Int_to_Int64(int_index, false);
|
||||
if (index <= 0) index = arr->length + index + 1;
|
||||
@ -86,7 +86,7 @@ public void Array$insert(array_t *arr, const void *item, Int_t int_index, int64_
|
||||
memcpy((void*)arr->data + (index-1)*padded_item_size, item, padded_item_size);
|
||||
}
|
||||
|
||||
public void Array$insert_all(array_t *arr, array_t to_insert, Int_t int_index, int64_t padded_item_size)
|
||||
public void Array$insert_all(Array_t *arr, Array_t to_insert, Int_t int_index, int64_t padded_item_size)
|
||||
{
|
||||
int64_t index = Int_to_Int64(int_index, false);
|
||||
if (to_insert.length == 0)
|
||||
@ -159,7 +159,7 @@ public void Array$insert_all(array_t *arr, array_t to_insert, Int_t int_index, i
|
||||
}
|
||||
}
|
||||
|
||||
public void Array$remove_at(array_t *arr, Int_t int_index, Int_t int_count, int64_t padded_item_size)
|
||||
public void Array$remove_at(Array_t *arr, Int_t int_index, Int_t int_count, int64_t padded_item_size)
|
||||
{
|
||||
int64_t index = Int_to_Int64(int_index, false);
|
||||
if (index < 1) index = arr->length + index + 1;
|
||||
@ -194,7 +194,7 @@ public void Array$remove_at(array_t *arr, Int_t int_index, Int_t int_count, int6
|
||||
if (arr->length == 0) arr->data = NULL;
|
||||
}
|
||||
|
||||
public void Array$remove_item(array_t *arr, void *item, Int_t max_removals, const TypeInfo *type)
|
||||
public void Array$remove_item(Array_t *arr, void *item, Int_t max_removals, const TypeInfo *type)
|
||||
{
|
||||
int64_t padded_item_size = get_padded_item_size(type);
|
||||
const Int_t ZERO = (Int_t){.small=(0<<2)|1};
|
||||
@ -213,7 +213,7 @@ public void Array$remove_item(array_t *arr, void *item, Int_t max_removals, cons
|
||||
}
|
||||
}
|
||||
|
||||
public Int_t Array$find(array_t arr, void *item, const TypeInfo *type)
|
||||
public Int_t Array$find(Array_t arr, void *item, const TypeInfo *type)
|
||||
{
|
||||
const TypeInfo *item_type = type->ArrayInfo.item;
|
||||
for (int64_t i = 0; i < arr.length; i++) {
|
||||
@ -223,7 +223,7 @@ public Int_t Array$find(array_t arr, void *item, const TypeInfo *type)
|
||||
return I(0);
|
||||
}
|
||||
|
||||
public void *Array$first(array_t arr, closure_t predicate)
|
||||
public void *Array$first(Array_t arr, closure_t predicate)
|
||||
{
|
||||
bool (*is_good)(void*, void*) = (void*)predicate.fn;
|
||||
for (int64_t i = 0; i < arr.length; i++) {
|
||||
@ -234,7 +234,7 @@ public void *Array$first(array_t arr, closure_t predicate)
|
||||
}
|
||||
|
||||
|
||||
public void Array$sort(array_t *arr, closure_t comparison, int64_t padded_item_size)
|
||||
public void Array$sort(Array_t *arr, closure_t comparison, int64_t padded_item_size)
|
||||
{
|
||||
if (arr->data_refcount != 0 || (int64_t)arr->stride != padded_item_size)
|
||||
Array$compact(arr, padded_item_size);
|
||||
@ -242,14 +242,14 @@ public void Array$sort(array_t *arr, closure_t comparison, int64_t padded_item_s
|
||||
qsort_r(arr->data, arr->length, padded_item_size, comparison.fn, comparison.userdata);
|
||||
}
|
||||
|
||||
public array_t Array$sorted(array_t arr, closure_t comparison, int64_t padded_item_size)
|
||||
public Array_t Array$sorted(Array_t arr, closure_t comparison, int64_t padded_item_size)
|
||||
{
|
||||
Array$compact(&arr, padded_item_size);
|
||||
qsort_r(arr.data, arr.length, padded_item_size, comparison.fn, comparison.userdata);
|
||||
return arr;
|
||||
}
|
||||
|
||||
public void Array$shuffle(array_t *arr, int64_t padded_item_size)
|
||||
public void Array$shuffle(Array_t *arr, int64_t padded_item_size)
|
||||
{
|
||||
if (arr->data_refcount != 0 || (int64_t)arr->stride != padded_item_size)
|
||||
Array$compact(arr, padded_item_size);
|
||||
@ -263,14 +263,14 @@ 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)
|
||||
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)
|
||||
public void *Array$random(Array_t arr)
|
||||
{
|
||||
if (arr.length == 0)
|
||||
return NULL; // fail("Cannot get a random item from an empty array!");
|
||||
@ -278,7 +278,7 @@ public void *Array$random(array_t arr)
|
||||
return arr.data + arr.stride*index;
|
||||
}
|
||||
|
||||
public table_t Array$counts(array_t arr, const TypeInfo *type)
|
||||
public table_t Array$counts(Array_t arr, const TypeInfo *type)
|
||||
{
|
||||
table_t counts = {};
|
||||
const TypeInfo count_type = {.size=sizeof(table_t), .align=__alignof__(table_t),
|
||||
@ -292,13 +292,13 @@ public table_t Array$counts(array_t arr, const TypeInfo *type)
|
||||
return counts;
|
||||
}
|
||||
|
||||
public array_t Array$sample(array_t arr, Int_t int_n, array_t weights, int64_t padded_item_size)
|
||||
public Array_t Array$sample(Array_t arr, Int_t int_n, Array_t weights, int64_t padded_item_size)
|
||||
{
|
||||
int64_t n = Int_to_Int64(int_n, false);
|
||||
if (arr.length == 0 || n <= 0)
|
||||
return (array_t){};
|
||||
return (Array_t){};
|
||||
|
||||
array_t selected = {
|
||||
Array_t selected = {
|
||||
.data=arr.atomic ? GC_MALLOC_ATOMIC(n * padded_item_size) : GC_MALLOC(n * padded_item_size),
|
||||
.length=n,
|
||||
.stride=padded_item_size, .atomic=arr.atomic};
|
||||
@ -371,16 +371,16 @@ public array_t Array$sample(array_t arr, Int_t int_n, array_t weights, int64_t p
|
||||
return selected;
|
||||
}
|
||||
|
||||
public array_t Array$from(array_t array, Int_t int_first)
|
||||
public Array_t Array$from(Array_t array, Int_t int_first)
|
||||
{
|
||||
int64_t first = Int_to_Int64(int_first, false);
|
||||
if (first < 0)
|
||||
first = array.length + first + 1;
|
||||
|
||||
if (first < 1 || first > array.length)
|
||||
return (array_t){.atomic=array.atomic};
|
||||
return (Array_t){.atomic=array.atomic};
|
||||
|
||||
return (array_t){
|
||||
return (Array_t){
|
||||
.atomic=array.atomic,
|
||||
.data=array.data + array.stride*(first-1),
|
||||
.length=array.length - first + 1,
|
||||
@ -389,7 +389,7 @@ public array_t Array$from(array_t array, Int_t int_first)
|
||||
};
|
||||
}
|
||||
|
||||
public array_t Array$to(array_t array, Int_t int_last)
|
||||
public Array_t Array$to(Array_t array, Int_t int_last)
|
||||
{
|
||||
int64_t last = Int_to_Int64(int_last, false);
|
||||
if (last < 0)
|
||||
@ -399,9 +399,9 @@ public array_t Array$to(array_t array, Int_t int_last)
|
||||
last = array.length;
|
||||
|
||||
if (last == 0)
|
||||
return (array_t){.atomic=array.atomic};
|
||||
return (Array_t){.atomic=array.atomic};
|
||||
|
||||
return (array_t){
|
||||
return (Array_t){
|
||||
.atomic=array.atomic,
|
||||
.data=array.data,
|
||||
.length=last,
|
||||
@ -410,7 +410,7 @@ public array_t Array$to(array_t array, Int_t int_last)
|
||||
};
|
||||
}
|
||||
|
||||
public array_t Array$by(array_t array, Int_t int_stride, int64_t padded_item_size)
|
||||
public Array_t Array$by(Array_t array, Int_t int_stride, int64_t padded_item_size)
|
||||
{
|
||||
int64_t stride = Int_to_Int64(int_stride, false);
|
||||
// In the unlikely event that the stride value would be too large to fit in
|
||||
@ -424,7 +424,7 @@ public array_t Array$by(array_t array, Int_t int_stride, int64_t padded_item_siz
|
||||
for (int64_t i = 0; i < len; i++)
|
||||
memcpy(copy + i*padded_item_size, start + array.stride*stride*i, padded_item_size);
|
||||
}
|
||||
return (array_t){
|
||||
return (Array_t){
|
||||
.data=copy,
|
||||
.length=len,
|
||||
.stride=padded_item_size,
|
||||
@ -433,9 +433,9 @@ public array_t Array$by(array_t array, Int_t int_stride, int64_t padded_item_siz
|
||||
}
|
||||
|
||||
if (stride == 0)
|
||||
return (array_t){.atomic=array.atomic};
|
||||
return (Array_t){.atomic=array.atomic};
|
||||
|
||||
return (array_t){
|
||||
return (Array_t){
|
||||
.atomic=array.atomic,
|
||||
.data=(stride < 0 ? array.data + (array.stride * (array.length - 1)) : array.data),
|
||||
.length=(stride < 0 ? array.length / -stride : array.length / stride) + ((array.length % stride) != 0),
|
||||
@ -444,7 +444,7 @@ public array_t Array$by(array_t array, Int_t int_stride, int64_t padded_item_siz
|
||||
};
|
||||
}
|
||||
|
||||
public array_t Array$reversed(array_t array, int64_t padded_item_size)
|
||||
public Array_t Array$reversed(Array_t array, int64_t padded_item_size)
|
||||
{
|
||||
// Just in case negating the stride gives a value that doesn't fit into a
|
||||
// 15-bit integer, fall back to Array$by()'s more general method of copying
|
||||
@ -453,13 +453,13 @@ public array_t Array$reversed(array_t array, int64_t padded_item_size)
|
||||
if (__builtin_expect(-array.stride < ARRAY_MIN_STRIDE || -array.stride > ARRAY_MAX_STRIDE, 0))
|
||||
return Array$by(array, I(-1), padded_item_size);
|
||||
|
||||
array_t reversed = array;
|
||||
Array_t reversed = array;
|
||||
reversed.stride = -array.stride;
|
||||
reversed.data = array.data + (array.length-1)*array.stride;
|
||||
return reversed;
|
||||
}
|
||||
|
||||
public array_t Array$concat(array_t x, array_t y, int64_t padded_item_size)
|
||||
public Array_t Array$concat(Array_t x, Array_t y, int64_t padded_item_size)
|
||||
{
|
||||
void *data = x.atomic ? GC_MALLOC_ATOMIC(padded_item_size*(x.length + y.length)) : GC_MALLOC(padded_item_size*(x.length + y.length));
|
||||
if (x.stride == padded_item_size) {
|
||||
@ -476,7 +476,7 @@ public array_t Array$concat(array_t x, array_t y, int64_t padded_item_size)
|
||||
memcpy(data + (x.length + i)*padded_item_size, y.data + i*padded_item_size, padded_item_size);
|
||||
}
|
||||
|
||||
return (array_t){
|
||||
return (Array_t){
|
||||
.data=data,
|
||||
.length=x.length + y.length,
|
||||
.stride=padded_item_size,
|
||||
@ -484,7 +484,7 @@ public array_t Array$concat(array_t x, array_t y, int64_t padded_item_size)
|
||||
};
|
||||
}
|
||||
|
||||
public bool Array$has(array_t array, void *item, const TypeInfo *type)
|
||||
public bool Array$has(Array_t array, void *item, const TypeInfo *type)
|
||||
{
|
||||
const TypeInfo *item_type = type->ArrayInfo.item;
|
||||
for (int64_t i = 0; i < array.length; i++) {
|
||||
@ -494,12 +494,12 @@ public bool Array$has(array_t array, void *item, const TypeInfo *type)
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Array$clear(array_t *array)
|
||||
public void Array$clear(Array_t *array)
|
||||
{
|
||||
*array = (array_t){.data=0, .length=0};
|
||||
*array = (Array_t){.data=0, .length=0};
|
||||
}
|
||||
|
||||
public int32_t Array$compare(const array_t *x, const array_t *y, const TypeInfo *type)
|
||||
public int32_t Array$compare(const Array_t *x, const Array_t *y, const TypeInfo *type)
|
||||
{
|
||||
// Early out for arrays with the same data, e.g. two copies of the same array:
|
||||
if (x->data == y->data && x->stride == y->stride)
|
||||
@ -529,12 +529,12 @@ public int32_t Array$compare(const array_t *x, const array_t *y, const TypeInfo
|
||||
return (x->length > y->length) - (x->length < y->length);
|
||||
}
|
||||
|
||||
public bool Array$equal(const array_t *x, const array_t *y, const TypeInfo *type)
|
||||
public bool Array$equal(const Array_t *x, const Array_t *y, const TypeInfo *type)
|
||||
{
|
||||
return (Array$compare(x, y, type) == 0);
|
||||
}
|
||||
|
||||
public Text_t Array$as_text(const array_t *arr, bool colorize, const TypeInfo *type)
|
||||
public Text_t Array$as_text(const Array_t *arr, bool colorize, const TypeInfo *type)
|
||||
{
|
||||
if (!arr)
|
||||
return Text$concat(Text("["), generic_as_text(NULL, false, type->ArrayInfo.item), Text("]"));
|
||||
@ -551,7 +551,7 @@ public Text_t Array$as_text(const array_t *arr, bool colorize, const TypeInfo *t
|
||||
return text;
|
||||
}
|
||||
|
||||
public uint64_t Array$hash(const array_t *arr, const TypeInfo *type)
|
||||
public uint64_t Array$hash(const Array_t *arr, const TypeInfo *type)
|
||||
{
|
||||
const TypeInfo *item = type->ArrayInfo.item;
|
||||
siphash sh;
|
||||
@ -568,7 +568,7 @@ public uint64_t Array$hash(const array_t *arr, const TypeInfo *type)
|
||||
return siphashfinish_last_part(&sh, 0);
|
||||
}
|
||||
|
||||
static void siftdown(array_t *heap, int64_t startpos, int64_t pos, closure_t comparison, int64_t padded_item_size)
|
||||
static void siftdown(Array_t *heap, int64_t startpos, int64_t pos, closure_t comparison, int64_t padded_item_size)
|
||||
{
|
||||
assert(pos > 0 && pos < heap->length);
|
||||
char newitem[padded_item_size];
|
||||
@ -586,7 +586,7 @@ static void siftdown(array_t *heap, int64_t startpos, int64_t pos, closure_t com
|
||||
memcpy(heap->data + heap->stride*pos, newitem, padded_item_size);
|
||||
}
|
||||
|
||||
static void siftup(array_t *heap, int64_t pos, closure_t comparison, int64_t padded_item_size)
|
||||
static void siftup(Array_t *heap, int64_t pos, closure_t comparison, int64_t padded_item_size)
|
||||
{
|
||||
int64_t endpos = heap->length;
|
||||
int64_t startpos = pos;
|
||||
@ -616,7 +616,7 @@ static void siftup(array_t *heap, int64_t pos, closure_t comparison, int64_t pad
|
||||
siftdown(heap, startpos, pos, comparison, padded_item_size);
|
||||
}
|
||||
|
||||
public void Array$heap_push(array_t *heap, const void *item, closure_t comparison, int64_t padded_item_size)
|
||||
public void Array$heap_push(Array_t *heap, const void *item, closure_t comparison, int64_t padded_item_size)
|
||||
{
|
||||
Array$insert(heap, item, I(0), padded_item_size);
|
||||
|
||||
@ -627,13 +627,13 @@ public void Array$heap_push(array_t *heap, const void *item, closure_t compariso
|
||||
}
|
||||
}
|
||||
|
||||
public void Array$heap_pop(array_t *heap, closure_t comparison, int64_t padded_item_size)
|
||||
public void Array$heap_pop(Array_t *heap, closure_t comparison, int64_t padded_item_size)
|
||||
{
|
||||
if (heap->length == 0)
|
||||
fail("Attempt to pop from an empty array");
|
||||
|
||||
if (heap->length == 1) {
|
||||
*heap = (array_t){};
|
||||
*heap = (Array_t){};
|
||||
} else if (heap->length == 2) {
|
||||
heap->data += heap->stride;
|
||||
--heap->length;
|
||||
@ -646,7 +646,7 @@ public void Array$heap_pop(array_t *heap, closure_t comparison, int64_t padded_i
|
||||
}
|
||||
}
|
||||
|
||||
public void Array$heapify(array_t *heap, closure_t comparison, int64_t padded_item_size)
|
||||
public void Array$heapify(Array_t *heap, closure_t comparison, int64_t padded_item_size)
|
||||
{
|
||||
if (heap->data_refcount != 0)
|
||||
Array$compact(heap, padded_item_size);
|
||||
@ -660,7 +660,7 @@ public void Array$heapify(array_t *heap, closure_t comparison, int64_t padded_it
|
||||
ARRAY_DECREF(*heap);
|
||||
}
|
||||
|
||||
public Int_t Array$binary_search(array_t array, void *target, closure_t comparison)
|
||||
public Int_t Array$binary_search(Array_t array, void *target, closure_t comparison)
|
||||
{
|
||||
typedef int32_t (*cmp_fn_t)(void*, void*, void*);
|
||||
int64_t lo = 0, hi = array.length-1;
|
||||
|
@ -13,16 +13,16 @@
|
||||
|
||||
// Convert negative indices to back-indexed without branching: index0 = index + (index < 0)*(len+1)) - 1
|
||||
#define Array_get(item_type, arr_expr, index_expr, start, end) *({ \
|
||||
const array_t arr = arr_expr; int64_t index = index_expr; \
|
||||
const Array_t arr = arr_expr; int64_t index = index_expr; \
|
||||
int64_t off = index + (index < 0) * (arr.length + 1) - 1; \
|
||||
if (__builtin_expect(off < 0 || off >= arr.length, 0)) \
|
||||
fail_source(__SOURCE_FILE__, start, end, "Invalid array index: %s (array has length %ld)\n", Text$as_c_string(Int64$as_text(&index, no, NULL)), arr.length); \
|
||||
(item_type*)(arr.data + arr.stride * off);})
|
||||
#define Array_get_unchecked(type, x, i) *({ const array_t arr = x; int64_t index = i; \
|
||||
#define Array_get_unchecked(type, x, i) *({ const Array_t arr = x; int64_t index = i; \
|
||||
int64_t off = index + (index < 0) * (arr.length + 1) - 1; \
|
||||
(type*)(arr.data + arr.stride * off);})
|
||||
#define Array_lvalue(item_type, arr_expr, index_expr, padded_item_size, start, end) *({ \
|
||||
array_t *arr = arr_expr; int64_t index = index_expr; \
|
||||
Array_t *arr = arr_expr; int64_t index = index_expr; \
|
||||
int64_t off = index + (index < 0) * (arr->length + 1) - 1; \
|
||||
if (__builtin_expect(off < 0 || off >= arr->length, 0)) \
|
||||
fail_source(__SOURCE_FILE__, start, end, "Invalid array index: %s (array has length %ld)\n", Text$as_c_string(Int64$as_text(&index, no, NULL)), arr->length); \
|
||||
@ -30,7 +30,7 @@
|
||||
Array$compact(arr, padded_item_size); \
|
||||
(item_type*)(arr->data + arr->stride * off); })
|
||||
#define Array_lvalue_unchecked(item_type, arr_expr, index_expr, padded_item_size) *({ \
|
||||
array_t *arr = arr_expr; int64_t index = index_expr; \
|
||||
Array_t *arr = arr_expr; int64_t index = index_expr; \
|
||||
int64_t off = index + (index < 0) * (arr->length + 1) - 1; \
|
||||
if (arr->data_refcount > 0) \
|
||||
Array$compact(arr, padded_item_size); \
|
||||
@ -39,19 +39,19 @@
|
||||
Array_lvalue(item_type, arr_expr, index, padded_item_size, start, end) = value
|
||||
#define is_atomic(x) _Generic(x, bool: true, int8_t: true, int16_t: true, int32_t: true, int64_t: true, float: true, double: true, default: false)
|
||||
#define TypedArray(t, ...) ({ t items[] = {__VA_ARGS__}; \
|
||||
(array_t){.length=sizeof(items)/sizeof(items[0]), \
|
||||
(Array_t){.length=sizeof(items)/sizeof(items[0]), \
|
||||
.stride=(int64_t)&items[1] - (int64_t)&items[0], \
|
||||
.data=memcpy(GC_MALLOC(sizeof(items)), items, sizeof(items)), \
|
||||
.atomic=0, \
|
||||
.data_refcount=0}; })
|
||||
#define TypedArrayN(t, N, ...) ({ t items[N] = {__VA_ARGS__}; \
|
||||
(array_t){.length=N, \
|
||||
(Array_t){.length=N, \
|
||||
.stride=(int64_t)&items[1] - (int64_t)&items[0], \
|
||||
.data=memcpy(GC_MALLOC(sizeof(items)), items, sizeof(items)), \
|
||||
.atomic=0, \
|
||||
.data_refcount=0}; })
|
||||
#define Array(x, ...) ({ __typeof(x) items[] = {x, __VA_ARGS__}; \
|
||||
(array_t){.length=sizeof(items)/sizeof(items[0]), \
|
||||
(Array_t){.length=sizeof(items)/sizeof(items[0]), \
|
||||
.stride=(int64_t)&items[1] - (int64_t)&items[0], \
|
||||
.data=memcpy(is_atomic(x) ? GC_MALLOC_ATOMIC(sizeof(items)) : GC_MALLOC(sizeof(items)), items, sizeof(items)), \
|
||||
.atomic=is_atomic(x), \
|
||||
@ -62,43 +62,43 @@
|
||||
#define ARRAY_COPY(arr) ({ ARRAY_INCREF(arr); arr; })
|
||||
|
||||
#define Array$insert_value(arr, item_expr, index, padded_item_size) ({ __typeof(item_expr) item = item_expr; Array$insert(arr, &item, index, padded_item_size); })
|
||||
void Array$insert(array_t *arr, const void *item, Int_t index, int64_t padded_item_size);
|
||||
void Array$insert_all(array_t *arr, array_t to_insert, Int_t index, int64_t padded_item_size);
|
||||
void Array$remove_at(array_t *arr, Int_t index, Int_t count, int64_t padded_item_size);
|
||||
void Array$remove_item(array_t *arr, void *item, Int_t max_removals, const TypeInfo *type);
|
||||
void Array$insert(Array_t *arr, const void *item, Int_t index, int64_t padded_item_size);
|
||||
void Array$insert_all(Array_t *arr, Array_t to_insert, Int_t index, int64_t padded_item_size);
|
||||
void Array$remove_at(Array_t *arr, Int_t index, Int_t count, int64_t padded_item_size);
|
||||
void Array$remove_item(Array_t *arr, void *item, Int_t max_removals, const TypeInfo *type);
|
||||
#define Array$remove_item_value(arr, item_expr, max, type) ({ __typeof(item_expr) item = item_expr; Array$remove_item(arr, &item, max, type); })
|
||||
Int_t Array$find(array_t arr, void *item, const TypeInfo *type);
|
||||
Int_t Array$find(Array_t arr, void *item, const TypeInfo *type);
|
||||
#define Array$find_value(arr, item_expr, type) ({ __typeof(item_expr) item = item_expr; Array$find(arr, &item, type); })
|
||||
void *Array$first(array_t arr, closure_t predicate);
|
||||
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);
|
||||
table_t Array$counts(array_t arr, const TypeInfo *type);
|
||||
void Array$clear(array_t *array);
|
||||
void Array$compact(array_t *arr, int64_t padded_item_size);
|
||||
bool Array$has(array_t array, void *item, const TypeInfo *type);
|
||||
void *Array$first(Array_t arr, closure_t predicate);
|
||||
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);
|
||||
table_t Array$counts(Array_t arr, const TypeInfo *type);
|
||||
void Array$clear(Array_t *array);
|
||||
void Array$compact(Array_t *arr, int64_t padded_item_size);
|
||||
bool Array$has(Array_t array, void *item, const TypeInfo *type);
|
||||
#define Array$has_value(arr, item_expr, type) ({ __typeof(item_expr) item = item_expr; Array$has(arr, &item, type); })
|
||||
array_t Array$from(array_t array, Int_t first);
|
||||
array_t Array$to(array_t array, Int_t last);
|
||||
array_t Array$by(array_t array, Int_t stride, int64_t padded_item_size);
|
||||
array_t Array$reversed(array_t array, int64_t padded_item_size);
|
||||
array_t Array$concat(array_t x, array_t y, int64_t padded_item_size);
|
||||
uint64_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);
|
||||
Text_t Array$as_text(const array_t *arr, bool colorize, const TypeInfo *type);
|
||||
void Array$heapify(array_t *heap, closure_t comparison, int64_t padded_item_size);
|
||||
void Array$heap_push(array_t *heap, const void *item, closure_t comparison, int64_t padded_item_size);
|
||||
Array_t Array$from(Array_t array, Int_t first);
|
||||
Array_t Array$to(Array_t array, Int_t last);
|
||||
Array_t Array$by(Array_t array, Int_t stride, int64_t padded_item_size);
|
||||
Array_t Array$reversed(Array_t array, int64_t padded_item_size);
|
||||
Array_t Array$concat(Array_t x, Array_t y, int64_t padded_item_size);
|
||||
uint64_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);
|
||||
Text_t Array$as_text(const Array_t *arr, bool colorize, const TypeInfo *type);
|
||||
void Array$heapify(Array_t *heap, closure_t comparison, int64_t padded_item_size);
|
||||
void Array$heap_push(Array_t *heap, const void *item, closure_t comparison, int64_t padded_item_size);
|
||||
#define Array$heap_push_value(heap, _value, comparison, padded_item_size) ({ __typeof(_value) value = _value; Array$heap_push(heap, &value, comparison, padded_item_size); })
|
||||
void Array$heap_pop(array_t *heap, closure_t comparison, int64_t padded_item_size);
|
||||
void Array$heap_pop(Array_t *heap, closure_t comparison, int64_t padded_item_size);
|
||||
#define Array$heap_pop_value(heap, comparison, padded_item_size, type) \
|
||||
({ array_t *_heap = heap; if (_heap->length == 0) fail("Attempt to pop from an empty array"); \
|
||||
({ Array_t *_heap = heap; if (_heap->length == 0) fail("Attempt to pop from an empty array"); \
|
||||
type value = *(type*)_heap->data; Array$heap_pop(_heap, comparison, padded_item_size); value; })
|
||||
Int_t Array$binary_search(array_t array, void *target, closure_t comparison);
|
||||
Int_t Array$binary_search(Array_t array, void *target, closure_t comparison);
|
||||
#define Array$binary_search_value(array, target, comparison) \
|
||||
({ __typeof(target) _target = target; Array$binary_search(array, &_target, comparison); })
|
||||
|
||||
|
@ -24,7 +24,7 @@ public channel_t *Channel$new(Int_t max_size)
|
||||
if (Int$compare_value(max_size, I_small(0)) <= 0)
|
||||
fail("Cannot create a channel with a size less than one: %ld", max_size);
|
||||
channel_t *channel = new(channel_t);
|
||||
channel->items = (array_t){};
|
||||
channel->items = (Array_t){};
|
||||
channel->mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;
|
||||
channel->cond = (pthread_cond_t)PTHREAD_COND_INITIALIZER;
|
||||
channel->max_size = Int_to_Int64(max_size, false);
|
||||
@ -42,7 +42,7 @@ public void Channel$give(channel_t *channel, const void *item, bool front, int64
|
||||
(void)pthread_cond_signal(&channel->cond);
|
||||
}
|
||||
|
||||
public void Channel$give_all(channel_t *channel, array_t to_give, bool front, int64_t padded_item_size)
|
||||
public void Channel$give_all(channel_t *channel, Array_t to_give, bool front, int64_t padded_item_size)
|
||||
{
|
||||
if (to_give.length == 0) return;
|
||||
(void)pthread_mutex_lock(&channel->mutex);
|
||||
@ -83,11 +83,11 @@ public void Channel$peek(channel_t *channel, void *out, bool front, int64_t item
|
||||
(void)pthread_cond_signal(&channel->cond);
|
||||
}
|
||||
|
||||
public array_t Channel$view(channel_t *channel)
|
||||
public Array_t Channel$view(channel_t *channel)
|
||||
{
|
||||
(void)pthread_mutex_lock(&channel->mutex);
|
||||
ARRAY_INCREF(channel->items);
|
||||
array_t ret = channel->items;
|
||||
Array_t ret = channel->items;
|
||||
(void)pthread_mutex_unlock(&channel->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
@ -13,14 +13,14 @@ channel_t *Channel$new(Int_t max_size);
|
||||
void Channel$give(channel_t *channel, const void *item, bool front, int64_t padded_item_size);
|
||||
#define Channel$give_value(channel, item, front, padded_item_size) \
|
||||
({ __typeof(item) _item = item; Channel$give(channel, &_item, front, padded_item_size); })
|
||||
void Channel$give_all(channel_t *channel, array_t to_give, bool front, int64_t padded_item_size);
|
||||
void Channel$give_all(channel_t *channel, Array_t to_give, bool front, int64_t padded_item_size);
|
||||
void Channel$get(channel_t *channel, void *out, bool front, int64_t item_size, int64_t padded_item_size);
|
||||
#define Channel$get_value(channel, front, t, padded_item_size) \
|
||||
({ t _val; Channel$get(channel, &_val, front, sizeof(t), padded_item_size); _val; })
|
||||
void Channel$peek(channel_t *channel, void *out, bool front, int64_t item_size);
|
||||
#define Channel$peek_value(channel, front, t) ({ t _val; Channel$peek(channel, &_val, front, sizeof(t)); _val; })
|
||||
void Channel$clear(channel_t *channel);
|
||||
array_t Channel$view(channel_t *channel);
|
||||
Array_t Channel$view(channel_t *channel);
|
||||
uint64_t Channel$hash(const channel_t **channel, const TypeInfo *type);
|
||||
int32_t Channel$compare(const channel_t **x, const channel_t **y, const TypeInfo *type);
|
||||
bool Channel$equal(const channel_t **x, const channel_t **y, const TypeInfo *type);
|
||||
|
@ -34,7 +34,7 @@ typedef struct {
|
||||
bool atomic:1;
|
||||
uint8_t data_refcount:ARRAY_REFCOUNT_BITS;
|
||||
int16_t stride:ARRAY_STRIDE_BITS;
|
||||
} array_t;
|
||||
} Array_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t occupied:1, index:31;
|
||||
@ -51,7 +51,7 @@ typedef struct {
|
||||
} bucket_info_t;
|
||||
|
||||
typedef struct table_s {
|
||||
array_t entries;
|
||||
Array_t entries;
|
||||
bucket_info_t *bucket_info;
|
||||
struct table_s *fallback;
|
||||
} table_t;
|
||||
@ -65,7 +65,7 @@ typedef struct Range_s {
|
||||
} Range_t;
|
||||
|
||||
typedef struct {
|
||||
array_t items;
|
||||
Array_t items;
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
int64_t max_size;
|
||||
|
@ -430,8 +430,8 @@ public const TypeInfo $Int = {
|
||||
Int_t as_int = KindOfInt##_to_Int(i); \
|
||||
return Int$octal(as_int, digits_int, prefix); \
|
||||
} \
|
||||
public array_t KindOfInt ## $bits(c_type x) { \
|
||||
array_t bit_array = (array_t){.data=GC_MALLOC_ATOMIC(sizeof(bool[8*sizeof(c_type)])), .atomic=1, .stride=sizeof(bool), .length=8*sizeof(c_type)}; \
|
||||
public Array_t KindOfInt ## $bits(c_type x) { \
|
||||
Array_t bit_array = (Array_t){.data=GC_MALLOC_ATOMIC(sizeof(bool[8*sizeof(c_type)])), .atomic=1, .stride=sizeof(bool), .length=8*sizeof(c_type)}; \
|
||||
bool *bits = bit_array.data + sizeof(c_type)*8; \
|
||||
for (size_t i = 0; i < 8*sizeof(c_type); i++) { \
|
||||
*(bits--) = x & 1; \
|
||||
|
@ -30,7 +30,7 @@
|
||||
Text_t type_name ## $format(c_type i, Int_t digits); \
|
||||
Text_t type_name ## $hex(c_type i, Int_t digits, bool uppercase, bool prefix); \
|
||||
Text_t type_name ## $octal(c_type i, Int_t digits, bool prefix); \
|
||||
array_t type_name ## $bits(c_type x); \
|
||||
Array_t type_name ## $bits(c_type x); \
|
||||
c_type type_name ## $random(c_type min, c_type max); \
|
||||
Range_t type_name ## $to(c_type from, c_type to); \
|
||||
c_type type_name ## $from_text(Text_t text, bool *success); \
|
||||
|
@ -40,7 +40,7 @@
|
||||
#define END_OF_CHAIN UINT32_MAX
|
||||
|
||||
#define GET_ENTRY(t, i) ((t).entries.data + (t).entries.stride*(i))
|
||||
#define ENTRIES_TYPE(type) (&(TypeInfo){.size=sizeof(array_t), .align=__alignof__(array_t), .tag=ArrayInfo, .ArrayInfo.item=(&(TypeInfo){.size=entry_size(type), .align=entry_align(type), .tag=OpaqueInfo})})
|
||||
#define ENTRIES_TYPE(type) (&(TypeInfo){.size=sizeof(Array_t), .align=__alignof__(Array_t), .tag=ArrayInfo, .ArrayInfo.item=(&(TypeInfo){.size=entry_size(type), .align=entry_align(type), .tag=OpaqueInfo})})
|
||||
|
||||
static const TypeInfo MemoryPointer = {
|
||||
.size=sizeof(void*),
|
||||
@ -389,7 +389,7 @@ public void Table$clear(table_t *t)
|
||||
public table_t Table$sorted(table_t t, const TypeInfo *type)
|
||||
{
|
||||
closure_t cmp = (closure_t){.fn=generic_compare, .userdata=(void*)type->TableInfo.key};
|
||||
array_t entries = Array$sorted(t.entries, cmp, entry_size(type));
|
||||
Array_t entries = Array$sorted(t.entries, cmp, entry_size(type));
|
||||
return Table$from_entries(entries, type);
|
||||
}
|
||||
|
||||
@ -494,7 +494,7 @@ public Text_t Table$as_text(const table_t *t, bool colorize, const TypeInfo *typ
|
||||
return text;
|
||||
}
|
||||
|
||||
public table_t Table$from_entries(array_t entries, const TypeInfo *type)
|
||||
public table_t Table$from_entries(Array_t entries, const TypeInfo *type)
|
||||
{
|
||||
assert(type->tag == TableInfo);
|
||||
if (entries.length == 0)
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
#define Table(key_t, val_t, key_info, value_info, fb, N, ...) ({ \
|
||||
struct { key_t k; val_t v; } ents[N] = {__VA_ARGS__}; \
|
||||
table_t table = Table$from_entries((array_t){ \
|
||||
table_t table = Table$from_entries((Array_t){ \
|
||||
.data=memcpy(GC_MALLOC(sizeof(ents)), ents, sizeof(ents)), \
|
||||
.length=sizeof(ents)/sizeof(ents[0]), \
|
||||
.stride=(void*)&ents[1] - (void*)&ents[0], \
|
||||
@ -22,14 +22,14 @@
|
||||
table; })
|
||||
#define Set(item_t, item_info, N, ...) ({ \
|
||||
item_t ents[N] = {__VA_ARGS__}; \
|
||||
table_t set = Table$from_entries((array_t){ \
|
||||
table_t set = Table$from_entries((Array_t){ \
|
||||
.data=memcpy(GC_MALLOC(sizeof(ents)), ents, sizeof(ents)), \
|
||||
.length=sizeof(ents)/sizeof(ents[0]), \
|
||||
.stride=(void*)&ents[1] - (void*)&ents[0], \
|
||||
}, $SetInfo(item_info)); \
|
||||
set; })
|
||||
|
||||
table_t Table$from_entries(array_t entries, const TypeInfo *type);
|
||||
table_t Table$from_entries(Array_t entries, const TypeInfo *type);
|
||||
void *Table$get(table_t t, const void *key, const TypeInfo *type);
|
||||
#define Table$get_value_or_fail(table_expr, key_t, val_t, key_expr, info_expr, start, end) ({ \
|
||||
const table_t t = table_expr; key_t k = key_expr; const TypeInfo* info = info_expr; \
|
||||
|
@ -941,7 +941,7 @@ public bool Text$equal_ignoring_case(Text_t a, Text_t b)
|
||||
|
||||
public Text_t Text$upper(Text_t text)
|
||||
{
|
||||
array_t codepoints = Text$utf32_codepoints(text);
|
||||
Array_t codepoints = Text$utf32_codepoints(text);
|
||||
const char *language = uc_locale_language();
|
||||
uint32_t buf[128];
|
||||
size_t out_len;
|
||||
@ -953,7 +953,7 @@ public Text_t Text$upper(Text_t text)
|
||||
|
||||
public Text_t Text$lower(Text_t text)
|
||||
{
|
||||
array_t codepoints = Text$utf32_codepoints(text);
|
||||
Array_t codepoints = Text$utf32_codepoints(text);
|
||||
const char *language = uc_locale_language();
|
||||
uint32_t buf[128];
|
||||
size_t out_len;
|
||||
@ -965,7 +965,7 @@ public Text_t Text$lower(Text_t text)
|
||||
|
||||
public Text_t Text$title(Text_t text)
|
||||
{
|
||||
array_t codepoints = Text$utf32_codepoints(text);
|
||||
Array_t codepoints = Text$utf32_codepoints(text);
|
||||
const char *language = uc_locale_language();
|
||||
uint32_t buf[128];
|
||||
size_t out_len;
|
||||
@ -1703,7 +1703,7 @@ public int printf_text(FILE *stream, const struct printf_info *info, const void
|
||||
static inline Text_t _quoted(Text_t text, bool colorize, char quote_char)
|
||||
{
|
||||
// TODO: optimize for ASCII and short strings
|
||||
array_t graphemes = {.atomic=1};
|
||||
Array_t graphemes = {.atomic=1};
|
||||
#define add_char(c) Array$insert_value(&graphemes, (uint32_t)c, I_small(0), sizeof(uint32_t))
|
||||
#define add_str(s) ({ for (char *_c = s; *_c; ++_c) Array$insert_value(&graphemes, (uint32_t)*_c, I_small(0), sizeof(uint32_t)); })
|
||||
if (colorize)
|
||||
@ -1777,12 +1777,12 @@ public Text_t Text$quoted(Text_t text, bool colorize)
|
||||
return _quoted(text, colorize, '"');
|
||||
}
|
||||
|
||||
public array_t Text$find_all(Text_t text, Pattern_t pattern)
|
||||
public Array_t Text$find_all(Text_t text, Pattern_t pattern)
|
||||
{
|
||||
if (pattern.length == 0) // special case
|
||||
return (array_t){.length=0};
|
||||
return (Array_t){.length=0};
|
||||
|
||||
array_t matches = {};
|
||||
Array_t matches = {};
|
||||
|
||||
for (int64_t i = 0; ; ) {
|
||||
int64_t len;
|
||||
@ -1986,15 +1986,15 @@ public Text_t Text$replace_all(Text_t text, table_t replacements, Text_t backref
|
||||
return ret;
|
||||
}
|
||||
|
||||
public array_t Text$split(Text_t text, Pattern_t pattern)
|
||||
public Array_t Text$split(Text_t text, Pattern_t pattern)
|
||||
{
|
||||
if (text.length == 0) // special case
|
||||
return (array_t){.length=0};
|
||||
return (Array_t){.length=0};
|
||||
|
||||
if (pattern.length == 0) // special case
|
||||
return Text$clusters(text);
|
||||
|
||||
array_t chunks = {};
|
||||
Array_t chunks = {};
|
||||
|
||||
Int_t i = I_small(1);
|
||||
for (;;) {
|
||||
@ -2012,7 +2012,7 @@ public array_t Text$split(Text_t text, Pattern_t pattern)
|
||||
return chunks;
|
||||
}
|
||||
|
||||
public Text_t Text$join(Text_t glue, array_t pieces)
|
||||
public Text_t Text$join(Text_t glue, Array_t pieces)
|
||||
{
|
||||
if (pieces.length == 0) return (Text_t){.length=0};
|
||||
|
||||
@ -2047,9 +2047,9 @@ public Text_t Text$format(const char *fmt, ...)
|
||||
return ret;
|
||||
}
|
||||
|
||||
public array_t Text$clusters(Text_t text)
|
||||
public Array_t Text$clusters(Text_t text)
|
||||
{
|
||||
array_t clusters = {.atomic=1};
|
||||
Array_t clusters = {.atomic=1};
|
||||
for (int64_t i = 1; i <= text.length; i++) {
|
||||
Text_t cluster = Text$slice(text, I(i), I(i));
|
||||
Array$insert(&clusters, &cluster, I_small(0), sizeof(Text_t));
|
||||
@ -2057,9 +2057,9 @@ public array_t Text$clusters(Text_t text)
|
||||
return clusters;
|
||||
}
|
||||
|
||||
public array_t Text$utf32_codepoints(Text_t text)
|
||||
public Array_t Text$utf32_codepoints(Text_t text)
|
||||
{
|
||||
array_t codepoints = {.atomic=1};
|
||||
Array_t codepoints = {.atomic=1};
|
||||
iteration_state_t state = {0, 0};
|
||||
for (int64_t i = 0; i < text.length; i++) {
|
||||
int32_t grapheme = _next_grapheme(text, &state, i);
|
||||
@ -2073,10 +2073,10 @@ public array_t Text$utf32_codepoints(Text_t text)
|
||||
return codepoints;
|
||||
}
|
||||
|
||||
public array_t Text$utf8_bytes(Text_t text)
|
||||
public Array_t Text$utf8_bytes(Text_t text)
|
||||
{
|
||||
const char *str = Text$as_c_string(text);
|
||||
return (array_t){.length=strlen(str), .stride=1, .atomic=1, .data=(void*)str};
|
||||
return (Array_t){.length=strlen(str), .stride=1, .atomic=1, .data=(void*)str};
|
||||
}
|
||||
|
||||
static inline const char *codepoint_name(uint32_t c)
|
||||
@ -2090,9 +2090,9 @@ static inline const char *codepoint_name(uint32_t c)
|
||||
return name;
|
||||
}
|
||||
|
||||
public array_t Text$codepoint_names(Text_t text)
|
||||
public Array_t Text$codepoint_names(Text_t text)
|
||||
{
|
||||
array_t names = {};
|
||||
Array_t names = {};
|
||||
iteration_state_t state = {0, 0};
|
||||
for (int64_t i = 0; i < text.length; i++) {
|
||||
int32_t grapheme = _next_grapheme(text, &state, i);
|
||||
@ -2111,7 +2111,7 @@ public array_t Text$codepoint_names(Text_t text)
|
||||
return names;
|
||||
}
|
||||
|
||||
public Text_t Text$from_codepoints(array_t codepoints)
|
||||
public Text_t Text$from_codepoints(Array_t codepoints)
|
||||
{
|
||||
if (codepoints.stride != sizeof(int32_t))
|
||||
Array$compact(&codepoints, sizeof(int32_t));
|
||||
@ -2119,9 +2119,9 @@ public Text_t Text$from_codepoints(array_t codepoints)
|
||||
return text_from_u32(codepoints.data, codepoints.length, true);
|
||||
}
|
||||
|
||||
public Text_t Text$from_codepoint_names(array_t codepoint_names)
|
||||
public Text_t Text$from_codepoint_names(Array_t codepoint_names)
|
||||
{
|
||||
array_t codepoints = {};
|
||||
Array_t codepoints = {};
|
||||
for (int64_t i = 0; i < codepoint_names.length; i++) {
|
||||
Text_t *name = ((Text_t*)(codepoint_names.data + i*codepoint_names.stride));
|
||||
const char *name_str = Text$as_c_string(*name);
|
||||
@ -2132,7 +2132,7 @@ public Text_t Text$from_codepoint_names(array_t codepoint_names)
|
||||
return Text$from_codepoints(codepoints);
|
||||
}
|
||||
|
||||
public Text_t Text$from_bytes(array_t bytes)
|
||||
public Text_t Text$from_bytes(Array_t bytes)
|
||||
{
|
||||
if (bytes.stride != sizeof(int8_t))
|
||||
Array$compact(&bytes, sizeof(int8_t));
|
||||
@ -2142,9 +2142,9 @@ public Text_t Text$from_bytes(array_t bytes)
|
||||
return Text$from_str(bytes.data);
|
||||
}
|
||||
|
||||
public array_t Text$lines(Text_t text)
|
||||
public Array_t Text$lines(Text_t text)
|
||||
{
|
||||
array_t lines = {};
|
||||
Array_t lines = {};
|
||||
iteration_state_t state = {0, 0};
|
||||
for (int64_t i = 0, line_start = 0; i < text.length; i++) {
|
||||
int32_t grapheme = _next_grapheme(text, &state, i);
|
||||
@ -2175,7 +2175,7 @@ public const TypeInfo $Text = {
|
||||
public Pattern_t Pattern$escape_text(Text_t text)
|
||||
{
|
||||
// TODO: optimize for ASCII and short strings
|
||||
array_t graphemes = {.atomic=1};
|
||||
Array_t graphemes = {.atomic=1};
|
||||
#define add_char(c) Array$insert_value(&graphemes, (uint32_t)c, I_small(0), sizeof(uint32_t))
|
||||
#define add_str(s) ({ for (char *_c = s; *_c; ++_c) Array$insert_value(&graphemes, (uint32_t)*_c, I_small(0), sizeof(uint32_t)); })
|
||||
iteration_state_t state = {0, 0};
|
||||
|
@ -35,22 +35,22 @@ Text_t Text$as_text(const void *text, bool colorize, const TypeInfo *info);
|
||||
Text_t Text$quoted(Text_t str, bool colorize);
|
||||
Text_t Text$replace(Text_t str, Pattern_t pat, Text_t replacement, Pattern_t backref_pat, bool recursive);
|
||||
Text_t Text$replace_all(Text_t text, table_t replacements, Pattern_t backref_pat, bool recursive);
|
||||
array_t Text$split(Text_t text, Pattern_t pattern);
|
||||
Array_t Text$split(Text_t text, Pattern_t pattern);
|
||||
Int_t Text$find(Text_t text, Pattern_t pattern, Int_t i, int64_t *match_length);
|
||||
array_t Text$find_all(Text_t text, Pattern_t pattern);
|
||||
Array_t Text$find_all(Text_t text, Pattern_t pattern);
|
||||
bool Text$has(Text_t text, Pattern_t pattern);
|
||||
bool Text$matches(Text_t text, Pattern_t pattern);
|
||||
const char *Text$as_c_string(Text_t text);
|
||||
public Text_t Text$format(const char *fmt, ...);
|
||||
array_t Text$clusters(Text_t text);
|
||||
array_t Text$utf32_codepoints(Text_t text);
|
||||
array_t Text$utf8_bytes(Text_t text);
|
||||
array_t Text$codepoint_names(Text_t text);
|
||||
Text_t Text$from_codepoints(array_t codepoints);
|
||||
Text_t Text$from_codepoint_names(array_t codepoint_names);
|
||||
Text_t Text$from_bytes(array_t bytes);
|
||||
array_t Text$lines(Text_t text);
|
||||
Text_t Text$join(Text_t glue, array_t pieces);
|
||||
Array_t Text$clusters(Text_t text);
|
||||
Array_t Text$utf32_codepoints(Text_t text);
|
||||
Array_t Text$utf8_bytes(Text_t text);
|
||||
Array_t Text$codepoint_names(Text_t text);
|
||||
Text_t Text$from_codepoints(Array_t codepoints);
|
||||
Text_t Text$from_codepoint_names(Array_t codepoint_names);
|
||||
Text_t Text$from_bytes(Array_t bytes);
|
||||
Array_t Text$lines(Text_t text);
|
||||
Text_t Text$join(Text_t glue, Array_t pieces);
|
||||
Text_t Text$map(Text_t text, Pattern_t pattern, closure_t fn);
|
||||
Text_t Text$repeat(Text_t text, Int_t count);
|
||||
|
||||
|
@ -55,7 +55,7 @@ typedef struct TypeInfo {
|
||||
|
||||
#define $PointerInfo(sigil_expr, pointed_info, opt) &((TypeInfo){.size=sizeof(void*), .align=__alignof__(void*), \
|
||||
.tag=PointerInfo, .PointerInfo={.sigil=sigil_expr, .pointed=pointed_info, .is_optional=opt}})
|
||||
#define $ArrayInfo(item_info) &((TypeInfo){.size=sizeof(array_t), .align=__alignof__(array_t), \
|
||||
#define $ArrayInfo(item_info) &((TypeInfo){.size=sizeof(Array_t), .align=__alignof__(Array_t), \
|
||||
.tag=ArrayInfo, .ArrayInfo.item=item_info})
|
||||
#define $SetInfo(item_info) &((TypeInfo){.size=sizeof(table_t), .align=__alignof__(table_t), \
|
||||
.tag=TableInfo, .TableInfo.key=item_info, .TableInfo.value=&$Void})
|
||||
|
26
compile.c
26
compile.c
@ -169,7 +169,7 @@ CORD compile_type(type_t *t)
|
||||
auto text = Match(t, TextType);
|
||||
return text->lang ? CORD_all(namespace_prefix(text->env->libname, text->env->namespace->parent), text->lang, "_t") : "Text_t";
|
||||
}
|
||||
case ArrayType: return "array_t";
|
||||
case ArrayType: return "Array_t";
|
||||
case SetType: return "table_t";
|
||||
case ChannelType: return "channel_t*";
|
||||
case TableType: return "table_t";
|
||||
@ -1009,7 +1009,7 @@ CORD compile_statement(env_t *env, ast_t *ast)
|
||||
if (can_be_mutated(env, array) && is_idempotent(array)) {
|
||||
CORD array_code = compile(env, array);
|
||||
loop = CORD_all("{\n"
|
||||
"array_t iterating = ARRAY_COPY(", array_code, ");\n",
|
||||
"Array_t iterating = ARRAY_COPY(", array_code, ");\n",
|
||||
loop,
|
||||
stop,
|
||||
"\nARRAY_DECREF(", array_code, ");\n"
|
||||
@ -1019,7 +1019,7 @@ CORD compile_statement(env_t *env, ast_t *ast)
|
||||
loop = CORD_all("if (", array_code, ".length > 0) {\n", loop, "\n} else ", compile_statement(env, for_->empty));
|
||||
} else {
|
||||
loop = CORD_all("{\n"
|
||||
"array_t iterating = ", compile(env, array), ";\n",
|
||||
"Array_t iterating = ", compile(env, array), ";\n",
|
||||
for_->empty ? "if (iterating.length > 0) {\n" : CORD_EMPTY,
|
||||
loop,
|
||||
for_->empty ? CORD_all("\n} else ", compile_statement(env, for_->empty)) : CORD_EMPTY,
|
||||
@ -1068,14 +1068,14 @@ CORD compile_statement(env_t *env, ast_t *ast)
|
||||
if (can_be_mutated(env, for_->iter) && is_idempotent(for_->iter)) {
|
||||
loop = CORD_all(
|
||||
"{\n",
|
||||
"array_t iterating = ARRAY_COPY((", compile(env, for_->iter), ").entries);\n",
|
||||
"Array_t iterating = ARRAY_COPY((", compile(env, for_->iter), ").entries);\n",
|
||||
loop,
|
||||
"ARRAY_DECREF((", compile(env, for_->iter), ").entries);\n"
|
||||
"}\n");
|
||||
} else {
|
||||
loop = CORD_all(
|
||||
"{\n",
|
||||
"array_t iterating = (", compile(env, for_->iter), ").entries;\n",
|
||||
"Array_t iterating = (", compile(env, for_->iter), ").entries;\n",
|
||||
loop,
|
||||
"}\n");
|
||||
}
|
||||
@ -1982,7 +1982,7 @@ CORD compile(env_t *env, ast_t *ast)
|
||||
|
||||
auto array = Match(ast, Array);
|
||||
if (!array->items)
|
||||
return "(array_t){.length=0}";
|
||||
return "(Array_t){.length=0}";
|
||||
|
||||
int64_t n = 0;
|
||||
for (ast_list_t *item = array->items; item; item = item->next) {
|
||||
@ -2004,7 +2004,7 @@ CORD compile(env_t *env, ast_t *ast)
|
||||
env_t *scope = fresh_scope(env);
|
||||
static int64_t comp_num = 1;
|
||||
scope->comprehension_var = heap_strf("arr$%ld", comp_num++);
|
||||
CORD code = CORD_all("({ array_t ", scope->comprehension_var, " = {};");
|
||||
CORD code = CORD_all("({ Array_t ", scope->comprehension_var, " = {};");
|
||||
set_binding(scope, scope->comprehension_var, new(binding_t, .type=array_type, .code=scope->comprehension_var));
|
||||
for (ast_list_t *item = array->items; item; item = item->next) {
|
||||
if (item->ast->tag == Comprehension) {
|
||||
@ -2420,7 +2420,7 @@ CORD compile(env_t *env, ast_t *ast)
|
||||
} else if (streq(call->name, "add_all")) {
|
||||
arg_t *arg_spec = new(arg_t, .name="items", .type=Type(ArrayType, .item_type=Match(self_value_t, SetType)->item_type));
|
||||
return CORD_all("({ table_t *set = ", compile_to_pointer_depth(env, call->self, 1, false), "; ",
|
||||
"array_t to_add = ", compile_arguments(env, ast, arg_spec, call->args), "; ",
|
||||
"Array_t to_add = ", compile_arguments(env, ast, arg_spec, call->args), "; ",
|
||||
"for (int64_t i = 0; i < to_add.length; i++)\n"
|
||||
"Table$set(set, to_add.data + i*to_add.stride, NULL, ", compile_type_info(env, self_value_t), ");\n",
|
||||
"(void)0; })");
|
||||
@ -2432,7 +2432,7 @@ CORD compile(env_t *env, ast_t *ast)
|
||||
} else if (streq(call->name, "remove_all")) {
|
||||
arg_t *arg_spec = new(arg_t, .name="items", .type=Type(ArrayType, .item_type=Match(self_value_t, SetType)->item_type));
|
||||
return CORD_all("({ table_t *set = ", compile_to_pointer_depth(env, call->self, 1, false), "; ",
|
||||
"array_t to_add = ", compile_arguments(env, ast, arg_spec, call->args), "; ",
|
||||
"Array_t to_add = ", compile_arguments(env, ast, arg_spec, call->args), "; ",
|
||||
"for (int64_t i = 0; i < to_add.length; i++)\n"
|
||||
"Table$remove(set, to_add.data + i*to_add.stride, ", compile_type_info(env, self_value_t), ");\n",
|
||||
"(void)0; })");
|
||||
@ -2819,9 +2819,9 @@ CORD compile(env_t *env, ast_t *ast)
|
||||
size_t align = type_align(table->value_type);
|
||||
if (align > 1 && offset % align > 0)
|
||||
offset += align - (offset % align);
|
||||
return CORD_all("({ array_t *entries = &(", compile_to_pointer_depth(env, f->fielded, 0, false), ").entries;\n"
|
||||
return CORD_all("({ Array_t *entries = &(", compile_to_pointer_depth(env, f->fielded, 0, false), ").entries;\n"
|
||||
"ARRAY_INCREF(*entries);\n"
|
||||
"array_t values = *entries;\n"
|
||||
"Array_t values = *entries;\n"
|
||||
"values.data += ", CORD_asprintf("%zu", offset), ";\n"
|
||||
"values; })");
|
||||
} else if (streq(f->field, "fallback")) {
|
||||
@ -2848,7 +2848,7 @@ CORD compile(env_t *env, ast_t *ast)
|
||||
if (ptr->is_optional)
|
||||
code_err(ast, "This pointer is potentially null, so it can't be safely dereferenced");
|
||||
if (ptr->pointed->tag == ArrayType) {
|
||||
return CORD_all("({ array_t *arr = ", compile(env, indexing->indexed), "; ARRAY_INCREF(*arr); *arr; })");
|
||||
return CORD_all("({ Array_t *arr = ", compile(env, indexing->indexed), "; ARRAY_INCREF(*arr); *arr; })");
|
||||
} else if (ptr->pointed->tag == TableType || ptr->pointed->tag == SetType) {
|
||||
return CORD_all("({ table_t *t = ", compile(env, indexing->indexed), "; TABLE_INCREF(*t); *t; })");
|
||||
} else {
|
||||
@ -3229,7 +3229,7 @@ CORD compile_cli_arg_call(env_t *env, CORD fn_name, type_t *fn_type)
|
||||
code = CORD_all(code, "if (!", arg->name, "$is_set) {\n");
|
||||
if (t->tag == ArrayType) {
|
||||
code = CORD_all(
|
||||
code, "$", arg->name, " = (array_t){};\n"
|
||||
code, "$", arg->name, " = (Array_t){};\n"
|
||||
"for (; i < argc; i++) {\n"
|
||||
"if (argv[i]) {\n"
|
||||
"Text_t arg = Text$from_str(argv[i]);\n"
|
||||
|
@ -75,7 +75,7 @@ env_t *new_compilation_unit(CORD *libname)
|
||||
type_t *type;
|
||||
CORD typename;
|
||||
CORD struct_val;
|
||||
array_t namespace;
|
||||
Array_t namespace;
|
||||
} global_types[] = {
|
||||
{"Void", Type(VoidType), "Void_t", "$Void", {}},
|
||||
{"Memory", Type(MemoryType), "Memory_t", "$Memory", {}},
|
||||
|
8
repl.c
8
repl.c
@ -121,7 +121,7 @@ const TypeInfo *type_to_type_info(type_t *t)
|
||||
case TextType: return &$Text;
|
||||
case ArrayType: {
|
||||
const TypeInfo *item_info = type_to_type_info(Match(t, ArrayType)->item_type);
|
||||
const TypeInfo array_info = {.size=sizeof(array_t), .align=__alignof__(array_t),
|
||||
const TypeInfo array_info = {.size=sizeof(Array_t), .align=__alignof__(Array_t),
|
||||
.tag=ArrayInfo, .ArrayInfo.item=item_info};
|
||||
return memcpy(GC_MALLOC(sizeof(TypeInfo)), &array_info, sizeof(TypeInfo));
|
||||
}
|
||||
@ -468,7 +468,7 @@ void eval(env_t *env, ast_t *ast, void *dest)
|
||||
// type_t *index_t = get_type(env, index->index);
|
||||
switch (indexed_t->tag) {
|
||||
case ArrayType: {
|
||||
array_t arr;
|
||||
Array_t arr;
|
||||
eval(env, index->indexed, &arr);
|
||||
int64_t raw_index = Int_to_Int64(ast_to_int(env, index->index), false);
|
||||
int64_t index_int = raw_index;
|
||||
@ -507,14 +507,14 @@ void eval(env_t *env, ast_t *ast, void *dest)
|
||||
}
|
||||
case Array: {
|
||||
assert(t->tag == ArrayType);
|
||||
array_t arr = {};
|
||||
Array_t arr = {};
|
||||
size_t item_size = type_size(Match(t, ArrayType)->item_type);
|
||||
char item_buf[item_size] = {};
|
||||
for (ast_list_t *item = Match(ast, Array)->items; item; item = item->next) {
|
||||
eval(env, item->ast, item_buf);
|
||||
Array$insert(&arr, item_buf, I(0), padded_type_size(Match(t, ArrayType)->item_type));
|
||||
}
|
||||
memcpy(dest, &arr, sizeof(array_t));
|
||||
memcpy(dest, &arr, sizeof(Array_t));
|
||||
break;
|
||||
}
|
||||
case Table: {
|
||||
|
4
types.c
4
types.c
@ -487,7 +487,7 @@ size_t type_size(type_t *t)
|
||||
}
|
||||
case NumType: return Match(t, NumType)->bits == TYPE_NBITS64 ? sizeof(double) : sizeof(float);
|
||||
case TextType: return sizeof(Text_t);
|
||||
case ArrayType: return sizeof(array_t);
|
||||
case ArrayType: return sizeof(Array_t);
|
||||
case SetType: return sizeof(table_t);
|
||||
case ChannelType: return sizeof(channel_t*);
|
||||
case TableType: return sizeof(table_t);
|
||||
@ -551,7 +551,7 @@ size_t type_align(type_t *t)
|
||||
case NumType: return Match(t, NumType)->bits == TYPE_NBITS64 ? __alignof__(double) : __alignof__(float);
|
||||
case TextType: return __alignof__(Text_t);
|
||||
case SetType: return __alignof__(table_t);
|
||||
case ArrayType: return __alignof__(array_t);
|
||||
case ArrayType: return __alignof__(Array_t);
|
||||
case ChannelType: return __alignof__(channel_t*);
|
||||
case TableType: return __alignof__(table_t);
|
||||
case FunctionType: return __alignof__(void*);
|
||||
|
Loading…
Reference in New Issue
Block a user