aboutsummaryrefslogtreecommitdiff
path: root/builtins
diff options
context:
space:
mode:
Diffstat (limited to 'builtins')
-rw-r--r--builtins/array.c51
-rw-r--r--builtins/array.h48
-rw-r--r--builtins/functions.c15
-rw-r--r--builtins/table.c69
-rw-r--r--builtins/types.c4
-rw-r--r--builtins/types.h8
6 files changed, 105 insertions, 90 deletions
diff --git a/builtins/array.c b/builtins/array.c
index e91b9809..447650fc 100644
--- a/builtins/array.c
+++ b/builtins/array.c
@@ -17,11 +17,17 @@
extern const void *SSS_HASH_VECTOR;
+static inline size_t get_item_size(const TypeInfo *info)
+{
+ return info->ArrayInfo.item->size;
+}
+
// 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 `item_size`
-public void Array_compact(array_t *arr, int64_t item_size)
+public void Array__compact(array_t *arr, const TypeInfo *type)
{
void *copy = NULL;
+ int64_t item_size = get_item_size(type);
if (arr->length > 0) {
copy = arr->atomic ? GC_MALLOC_ATOMIC(arr->length * item_size) : GC_MALLOC(arr->length * item_size);
if ((int64_t)arr->stride == item_size) {
@@ -41,13 +47,14 @@ public void Array_compact(array_t *arr, int64_t item_size)
};
}
-public void Array_insert(array_t *arr, const void *item, int64_t index, int64_t item_size)
+public void Array__insert(array_t *arr, const void *item, int64_t index, const TypeInfo *type)
{
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;
+ int64_t item_size = get_item_size(type);
if (!arr->data) {
arr->free = 4;
arr->data = arr->atomic ? GC_MALLOC_ATOMIC(arr->free * item_size) : GC_MALLOC(arr->free * item_size);
@@ -64,7 +71,7 @@ public void Array_insert(array_t *arr, const void *item, int64_t index, int64_t
arr->stride = item_size;
} else {
if (arr->copy_on_write)
- Array_compact(arr, item_size);
+ Array__compact(arr, type);
if (index != arr->length+1)
memmove((void*)arr->data + index*item_size, arr->data + (index-1)*item_size, (arr->length - index)*item_size);
@@ -75,13 +82,14 @@ public void Array_insert(array_t *arr, const void *item, int64_t index, int64_t
memcpy((void*)arr->data + (index-1)*item_size, item, item_size);
}
-public void Array_insert_all(array_t *arr, array_t to_insert, int64_t index, int64_t item_size)
+public void Array__insert_all(array_t *arr, array_t to_insert, int64_t index, const TypeInfo *type)
{
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;
+ int64_t item_size = get_item_size(type);
if (!arr->data) {
arr->free = to_insert.length;
arr->data = arr->atomic ? GC_MALLOC_ATOMIC(item_size*arr->free) : GC_MALLOC(item_size*arr->free);
@@ -96,7 +104,7 @@ public void Array_insert_all(array_t *arr, array_t to_insert, int64_t index, int
arr->copy_on_write = 0;
} else {
if (arr->copy_on_write)
- Array_compact(arr, item_size);
+ Array__compact(arr, type);
if (index != arr->length+1)
memmove((void*)arr->data + index*item_size, arr->data + (index-1)*item_size, (arr->length - index + to_insert.length-1)*item_size);
@@ -107,7 +115,7 @@ public void Array_insert_all(array_t *arr, array_t to_insert, int64_t index, int
memcpy((void*)arr->data + (index-1 + i)*item_size, to_insert.data + i*to_insert.stride, item_size);
}
-public void Array_remove(array_t *arr, int64_t index, int64_t count, int64_t item_size)
+public void Array__remove(array_t *arr, int64_t index, int64_t count, const TypeInfo *type)
{
if (index < 1) index = arr->length - index + 1;
@@ -118,6 +126,7 @@ public void Array_remove(array_t *arr, int64_t index, int64_t count, int64_t ite
// TODO: optimize arr.remove(1) by just updating the .data and .length values
+ int64_t item_size = get_item_size(type);
if (index + count > arr->length) {
if (arr->free >= 0)
arr->free += count;
@@ -139,7 +148,7 @@ public void Array_remove(array_t *arr, int64_t index, int64_t count, int64_t ite
arr->length -= count;
}
-public void Array_sort(array_t *arr, const TypeInfo *type)
+public void Array__sort(array_t *arr, const TypeInfo *type)
{
const TypeInfo *item_type = type->ArrayInfo.item;
int64_t item_size = item_type->size;
@@ -147,15 +156,16 @@ public void Array_sort(array_t *arr, const TypeInfo *type)
item_size += item_type->align - (item_size % item_type->align); // padding
if (arr->copy_on_write || (int64_t)arr->stride != item_size)
- Array_compact(arr, item_size);
+ Array__compact(arr, type);
qsort_r(arr->data, arr->length, item_size, (void*)generic_compare, (void*)item_type);
}
-public void Array_shuffle(array_t *arr, int64_t item_size)
+public void Array__shuffle(array_t *arr, const TypeInfo *type)
{
+ int64_t item_size = get_item_size(type);
if (arr->copy_on_write || (int64_t)arr->stride != item_size)
- Array_compact(arr, item_size);
+ Array__compact(arr, type);
char tmp[item_size];
for (int64_t i = arr->length-1; i > 1; i--) {
@@ -166,11 +176,8 @@ public void Array_shuffle(array_t *arr, int64_t item_size)
}
}
-public array_t Array_slice(array_t *array, int64_t first, int64_t stride, int64_t length, bool readonly, const TypeInfo *type)
+public array_t Array__slice(array_t *array, int64_t first, int64_t stride, int64_t length, bool readonly, const TypeInfo *type)
{
- TypeInfo *item = type->ArrayInfo.item;
- int64_t item_size = item->size;
-
if (stride > INT16_MAX)
stride = INT16_MAX;
else if (stride < INT16_MIN)
@@ -214,6 +221,7 @@ public array_t Array_slice(array_t *array, int64_t first, int64_t stride, int64_
// never do modifictions
array->copy_on_write = !readonly;
+ int64_t item_size = get_item_size(type);
return (array_t){
.atomic=array->atomic,
.data=array->data + item_size*(first-1),
@@ -223,7 +231,7 @@ public array_t Array_slice(array_t *array, int64_t first, int64_t stride, int64_
};
}
-public bool Array_contains(array_t array, void *item, const TypeInfo *type)
+public bool Array__contains(array_t array, void *item, const TypeInfo *type)
{
TypeInfo *item_type = type->ArrayInfo.item;
for (int64_t i = 0; i < array.length; i++)
@@ -232,12 +240,13 @@ public bool Array_contains(array_t array, void *item, const TypeInfo *type)
return false;
}
-public void Array_clear(array_t *array)
+public void Array__clear(array_t *array, const TypeInfo *type)
{
+ (void)type;
*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)
@@ -264,12 +273,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);
+ return (Array__compare(x, y, type) == 0);
}
-public CORD Array_cord(const array_t *arr, bool colorize, const TypeInfo *type)
+public CORD Array__cord(const array_t *arr, bool colorize, const TypeInfo *type)
{
if (!arr)
return CORD_all("[", generic_as_str(NULL, false, type->ArrayInfo.item), "]");
@@ -286,7 +295,7 @@ public CORD Array_cord(const array_t *arr, bool colorize, const TypeInfo *type)
return c;
}
-public uint32_t Array_hash(const array_t *arr, const TypeInfo *type)
+public uint32_t Array__hash(const array_t *arr, const TypeInfo *type)
{
// Array hash is calculated as a rolling, compacting hash of the length of the array, followed by
// the hashes of its items (or the items themselves if they're small plain data)
diff --git a/builtins/array.h b/builtins/array.h
index 9815ddff..ff62db33 100644
--- a/builtins/array.h
+++ b/builtins/array.h
@@ -7,40 +7,18 @@
#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_as_str(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]))
+void Array__insert(array_t *arr, const void *item, int64_t index, const TypeInfo *type);
+void Array__insert_all(array_t *arr, array_t to_insert, int64_t index, const TypeInfo *type);
+void Array__remove(array_t *arr, int64_t index, int64_t count, const TypeInfo *type);
+void Array__sort(array_t *arr, const TypeInfo *type);
+void Array__shuffle(array_t *arr, const TypeInfo *type);
+void Array__clear(array_t *array, const TypeInfo *type);
+void Array__compact(array_t *arr, const TypeInfo *type);
+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__as_str(const array_t *arr, bool colorize, const TypeInfo *type);
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
diff --git a/builtins/functions.c b/builtins/functions.c
index 1b22efdf..93453a3d 100644
--- a/builtins/functions.c
+++ b/builtins/functions.c
@@ -31,8 +31,8 @@ public void fail(const char *fmt, ...)
public uint32_t generic_hash(const void *obj, const TypeInfo *type)
{
switch (type->tag) {
- case PointerInfo: return Pointer__hash(obj, type);
- case ArrayInfo: return Array_hash(obj, type);
+ case PointerInfo: case FunctionInfo: return Pointer__hash(obj, type);
+ case ArrayInfo: return Array__hash(obj, type);
case TableInfo: return Table_hash(obj, type);
case CustomInfo:
if (!type->CustomInfo.hash)
@@ -50,8 +50,8 @@ public uint32_t generic_hash(const void *obj, const TypeInfo *type)
public int32_t generic_compare(const void *x, const void *y, const TypeInfo *type)
{
switch (type->tag) {
- case PointerInfo: return Pointer__compare(x, y, type);
- case ArrayInfo: return Array_compare(x, y, type);
+ case PointerInfo: case FunctionInfo: return Pointer__compare(x, y, type);
+ case ArrayInfo: return Array__compare(x, y, type);
case TableInfo: return Table_compare(x, y, type);
case CustomInfo:
if (!type->CustomInfo.compare)
@@ -66,8 +66,8 @@ public int32_t generic_compare(const void *x, const void *y, const TypeInfo *typ
public bool generic_equal(const void *x, const void *y, const TypeInfo *type)
{
switch (type->tag) {
- case PointerInfo: return Pointer__equal(x, y, type);
- case ArrayInfo: return Array_equal(x, y, type);
+ case PointerInfo: case FunctionInfo: return Pointer__equal(x, y, type);
+ case ArrayInfo: return Array__equal(x, y, type);
case TableInfo: return Table_equal(x, y, type);
case CustomInfo:
if (!type->CustomInfo.equal)
@@ -83,7 +83,8 @@ public CORD generic_as_str(const void *obj, bool colorize, const TypeInfo *type)
{
switch (type->tag) {
case PointerInfo: return Pointer__cord(obj, colorize, type);
- case ArrayInfo: return Array_as_str(obj, colorize, type);
+ case FunctionInfo: return Func__as_str(obj, colorize, type);
+ case ArrayInfo: return Array__as_str(obj, colorize, type);
case TableInfo: return Table_as_str(obj, colorize, type);
case TypeInfoInfo: return Type__as_str(obj, colorize, type);
case CustomInfo:
diff --git a/builtins/table.c b/builtins/table.c
index 32e6bb83..ad8c6e4c 100644
--- a/builtins/table.c
+++ b/builtins/table.c
@@ -37,11 +37,10 @@
// Helper accessors for type functions/values:
#define HASH_KEY(t, k) (generic_hash((k), type->TableInfo.key) % ((t)->bucket_info->count))
#define EQUAL_KEYS(x, y) (generic_equal((x), (y), type->TableInfo.key))
-#define ENTRY_SIZE (type->TableInfo.entry_size)
-#define VALUE_OFFSET (type->TableInfo.value_offset)
#define END_OF_CHAIN UINT32_MAX
#define GET_ENTRY(t, i) ((t)->entries.data + (t)->entries.stride*(i))
+#define ENTRY_TYPE(type) (&(TypeInfo){.size=entry_size(type), .align=entry_align(type), .tag=OpaqueInfo})
extern const void *SSS_HASH_VECTOR;
@@ -59,10 +58,34 @@ TypeInfo StrToVoidStarTable_type = {
.size=sizeof(table_t),
.align=alignof(table_t),
.tag=TableInfo,
- .TableInfo={.key=&Str_type.type, .value=&MemoryPointer_typeinfo,
- .entry_size=16, .value_offset=8},
+ .TableInfo={.key=&Str_type.type, .value=&MemoryPointer_typeinfo},
};
+static inline size_t entry_size(const TypeInfo *info)
+{
+ size_t size = info->TableInfo.key->size;
+ if (info->TableInfo.value->align > 1 && size % info->TableInfo.value->align)
+ size += info->TableInfo.value->align - (size % info->TableInfo.value->align); // padding
+ size += info->TableInfo.value->size;
+ if (info->TableInfo.key->align > 1 && size % info->TableInfo.key->align)
+ size += info->TableInfo.key->align - (size % info->TableInfo.key->align); // padding
+ return size;
+}
+
+static inline size_t entry_align(const TypeInfo *info)
+{
+ return MAX(info->TableInfo.key->align, info->TableInfo.value->align);
+}
+
+static inline size_t value_offset(const TypeInfo *info)
+{
+ size_t offset = info->TableInfo.key->size;
+ if (info->TableInfo.value->align > 1 && offset % info->TableInfo.value->align)
+ offset += info->TableInfo.value->align - (offset % info->TableInfo.value->align); // padding
+ return offset;
+}
+
+
static inline void hshow(const table_t *t)
{
hdebug("{");
@@ -79,7 +102,7 @@ static inline void hshow(const table_t *t)
static void maybe_copy_on_write(table_t *t, const TypeInfo *type)
{
if (t->entries.copy_on_write) {
- Array_compact(&t->entries, type->TableInfo.entry_size);
+ Array__compact(&t->entries, ENTRY_TYPE(type));
}
if (t->bucket_info && t->bucket_info->copy_on_write) {
@@ -110,7 +133,7 @@ public void *Table_get_raw(const table_t *t, const void *key, const TypeInfo *ty
void *entry = GET_ENTRY(t, buckets[i].index);
if (EQUAL_KEYS(entry, key)) {
hdebug("Found key!\n");
- return entry + VALUE_OFFSET;
+ return entry + value_offset(type);
}
if (buckets[i].next_bucket == END_OF_CHAIN)
break;
@@ -250,18 +273,18 @@ public void *Table_reserve(table_t *t, const void *key, const void *value, const
maybe_copy_on_write(t, type);
- char buf[ENTRY_SIZE] = {};
+ char buf[entry_size(type)] = {};
memcpy(buf, key, key_size);
if (value && value_size > 0)
- memcpy(buf + VALUE_OFFSET, value, value_size);
+ memcpy(buf + value_offset(type), value, value_size);
else
- memset(buf + VALUE_OFFSET, 0, value_size);
- Array_insert(&t->entries, buf, 0, ENTRY_SIZE);
+ memset(buf + value_offset(type), 0, value_size);
+ Array__insert(&t->entries, buf, 0, ENTRY_TYPE(type));
int64_t entry_index = t->entries.length-1;
void *entry = GET_ENTRY(t, entry_index);
Table_set_bucket(t, entry, entry_index, type);
- return entry + VALUE_OFFSET;
+ return entry + value_offset(type);
}
public void Table_set(table_t *t, const void *key, const void *value, const TypeInfo *type)
@@ -336,13 +359,13 @@ public void Table_remove(table_t *t, const void *key, const TypeInfo *type)
// Clobber the entry being removed (in the middle of the array) with
// the last entry:
- memcpy(GET_ENTRY(t, bucket->index), GET_ENTRY(t, last_entry), ENTRY_SIZE);
+ memcpy(GET_ENTRY(t, bucket->index), GET_ENTRY(t, last_entry), entry_size(type));
}
// Last entry is being removed, so clear it out to be safe:
- memset(GET_ENTRY(t, last_entry), 0, ENTRY_SIZE);
+ memset(GET_ENTRY(t, last_entry), 0, entry_size(type));
- Array_remove(&t->entries, t->entries.length, 1, ENTRY_SIZE);
+ Array__remove(&t->entries, t->entries.length, 1, ENTRY_TYPE(type));
int64_t bucket_to_clear;
if (prev) { // Middle (or end) of a chain
@@ -392,7 +415,7 @@ public bool Table_equal(const table_t *x, const table_t *y, const TypeInfo *type
const TypeInfo *value_type = type->TableInfo.value;
for (int64_t i = 0, length = Table_length(x); i < length; i++) {
void *x_key = GET_ENTRY(x, i);
- void *x_value = x_key + VALUE_OFFSET;
+ void *x_value = x_key + value_offset(type);
void *y_value = Table_get_raw(y, x_key, type);
if (!y_value)
return false;
@@ -421,15 +444,15 @@ public int32_t Table_compare(const table_t *x, const table_t *y, const TypeInfo
return (x->entries.length > y->entries.length) - (x->entries.length < y->entries.length);
array_t x_entries = x->entries, y_entries = y->entries;
- Array_sort(&x_entries, table.key);
- Array_sort(&y_entries, table.key);
+ Array__sort(&x_entries, table.key);
+ Array__sort(&y_entries, table.key);
for (int64_t i = 0; i < x_entries.length; i++) {
void *x_key = x_entries.data + x_entries.stride * i;
void *y_key = y_entries.data + y_entries.stride * i;
int32_t diff = generic_compare(x_key, y_key, table.key);
if (diff != 0) return diff;
- void *x_value = x_key + table.value_offset;
- void *y_value = y_key + table.value_offset;
+ void *x_value = x_key + value_offset(type);
+ void *y_value = y_key + value_offset(type);
diff = generic_compare(x_value, y_value, table.value);
if (diff != 0) return diff;
}
@@ -457,13 +480,13 @@ public uint32_t Table_hash(const table_t *t, const TypeInfo *type)
// hash(#t, xor(hash(k) for k in t.keys), xor(hash(v) for v in t.values), hash(t.fallback), hash(t.default))
// Where fallback and default hash to zero if absent
auto table = type->TableInfo;
- int64_t value_offset = table.value_offset;
+ int64_t val_off = value_offset(type);
uint32_t key_hashes = 0, value_hashes = 0, fallback_hash = 0, default_hash = 0;
for (int64_t i = 0, length = Table_length(t); i < length; i++) {
void *entry = GET_ENTRY(t, i);
key_hashes ^= generic_hash(entry, table.key);
- value_hashes ^= generic_hash(entry + value_offset, table.value);
+ value_hashes ^= generic_hash(entry + val_off, table.value);
}
if (t->fallback)
@@ -492,7 +515,7 @@ public CORD Table_as_str(const table_t *t, bool colorize, const TypeInfo *type)
if (!t)
return CORD_all("{", generic_as_str(NULL, false, table.key), "=>", generic_as_str(NULL, false, table.value), "}");
- int64_t value_offset = table.value_offset;
+ int64_t val_off = value_offset(type);
CORD c = "{";
for (int64_t i = 0, length = Table_length(t); i < length; i++) {
if (i > 0)
@@ -500,7 +523,7 @@ public CORD Table_as_str(const table_t *t, bool colorize, const TypeInfo *type)
void *entry = GET_ENTRY(t, i);
c = CORD_cat(c, generic_as_str(entry, colorize, table.key));
c = CORD_cat(c, "=>");
- c = CORD_cat(c, generic_as_str(entry + value_offset, colorize, table.value));
+ c = CORD_cat(c, generic_as_str(entry + val_off, colorize, table.value));
}
if (t->fallback) {
diff --git a/builtins/types.c b/builtins/types.c
index b5527c63..f77a36f9 100644
--- a/builtins/types.c
+++ b/builtins/types.c
@@ -47,8 +47,8 @@ public struct {
public CORD Func__as_str(const void *fn, bool colorize, const TypeInfo *type)
{
(void)fn;
- CORD c = type->TypeInfoInfo.type_str;
- if (colorize)
+ CORD c = type->FunctionInfo.type_str;
+ if (fn && colorize)
CORD_sprintf(&c, "\x1b[32;1m%r\x1b[m", c);
return c;
}
diff --git a/builtins/types.h b/builtins/types.h
index eac34dee..0430fbe5 100644
--- a/builtins/types.h
+++ b/builtins/types.h
@@ -15,7 +15,7 @@ typedef CORD (*str_fn_t)(const void*, bool, const struct TypeInfo*);
typedef struct TypeInfo {
int64_t size, align;
struct { // Anonymous tagged union for convenience
- enum { CustomInfo, PointerInfo, ArrayInfo, TableInfo, TypeInfoInfo, } tag;
+ enum { CustomInfo, PointerInfo, ArrayInfo, TableInfo, FunctionInfo, TypeInfoInfo, OpaqueInfo, } tag;
union {
struct {
equal_fn_t equal;
@@ -32,15 +32,19 @@ typedef struct TypeInfo {
} ArrayInfo;
struct {
struct TypeInfo *key, *value;
- int64_t entry_size, value_offset;
} TableInfo;
struct {
const char *type_str;
+ } FunctionInfo;
+ struct {
+ const char *type_str;
} TypeInfoInfo;
+ struct {} OpaqueInfo;
};
};
} TypeInfo;
CORD Type__as_str(const void *typeinfo, bool colorize, const TypeInfo *type);
+CORD Func__as_str(const void *fn, bool colorize, const TypeInfo *type);
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0