harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 64c8f388a55382122fd60a67fd5dce2c30640133
parent 437a3ca788a8dccc495e79bb88d0449951e969cc
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sat, 12 Dec 2020 11:16:03 -0500

Build initial riggings for type store

Diffstat:
Minclude/type_store.h | 9++++++---
Minclude/types.h | 26+++++++++++++++++++++++---
Msrc/type_store.c | 172+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/types.c | 116++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 316 insertions(+), 7 deletions(-)

diff --git a/include/type_store.h b/include/type_store.h @@ -5,16 +5,19 @@ #define TYPE_STORE_BUCKETS 256 -struct types { +struct type_bucket { struct type type; - struct types *next; + struct type_bucket *next; }; struct type_store { - struct type buckets[TYPE_STORE_BUCKETS]; + struct type_bucket *buckets[TYPE_STORE_BUCKETS]; }; unsigned long atype_hash(struct type_store *store, const struct ast_type *type); unsigned long type_hash(struct type_store *store, const struct type *type); +const struct type *type_store_lookup_atype( + struct type_store *store, const struct ast_type *atype); + #endif diff --git a/include/types.h b/include/types.h @@ -41,7 +41,7 @@ enum type_storage { struct type; enum pointer_flags { - POINTER_NULLABLE = 1 << 0, + POINTER_FLAGS_NULLABLE = 1 << 0, }; struct type_pointer { @@ -50,7 +50,7 @@ struct type_pointer { }; enum type_flags { - TYPE_CONST = 1 << 0, + TYPE_FLAGS_CONST = 1 << 0, }; struct type { @@ -82,9 +82,29 @@ extern const struct type builtin_type_u64, builtin_type_uint, builtin_type_uintptr, + builtin_type_rune, builtin_type_size, builtin_type_void, + // Const primitives + builtin_type_const_bool, + builtin_type_const_char, + builtin_type_const_f32, + builtin_type_const_f64, + builtin_type_const_i8, + builtin_type_const_i16, + builtin_type_const_i32, + builtin_type_const_i64, + builtin_type_const_int, + builtin_type_const_u8, + builtin_type_const_u16, + builtin_type_const_u32, + builtin_type_const_u64, + builtin_type_const_uint, + builtin_type_const_uintptr, + builtin_type_const_rune, + builtin_type_const_size, + builtin_type_const_void, // Aggregate - builtin_type_charptr; + builtin_type_const_ptr_char; #endif diff --git a/src/type_store.c b/src/type_store.c @@ -1,4 +1,5 @@ #include <assert.h> +#include <stdlib.h> #include "type_store.h" #include "util.h" @@ -81,3 +82,174 @@ type_hash(struct type_store *store, const struct type *type) } return hash; } + +static const struct type * +builtin_for_atype(const struct ast_type *atype) +{ + bool is_const = (atype->flags & TYPE_FLAGS_CONST) != 0; + switch (atype->storage) { + case TYPE_STORAGE_BOOL: + return is_const ? &builtin_type_bool : &builtin_type_const_bool; + case TYPE_STORAGE_CHAR: + return is_const ? &builtin_type_char : &builtin_type_const_char; + case TYPE_STORAGE_F32: + return is_const ? &builtin_type_f32 : &builtin_type_const_f32; + case TYPE_STORAGE_F64: + return is_const ? &builtin_type_f64 : &builtin_type_const_f64; + case TYPE_STORAGE_I8: + return is_const ? &builtin_type_i8 : &builtin_type_const_i8; + case TYPE_STORAGE_I16: + return is_const ? &builtin_type_i16 : &builtin_type_const_i16; + case TYPE_STORAGE_I32: + return is_const ? &builtin_type_i32 : &builtin_type_const_i32; + case TYPE_STORAGE_I64: + return is_const ? &builtin_type_i64 : &builtin_type_const_i64; + case TYPE_STORAGE_INT: + return is_const ? &builtin_type_int : &builtin_type_const_int; + case TYPE_STORAGE_RUNE: + return is_const ? &builtin_type_rune : &builtin_type_const_rune; + case TYPE_STORAGE_SIZE: + return is_const ? &builtin_type_size : &builtin_type_const_size; + case TYPE_STORAGE_U8: + return is_const ? &builtin_type_u8 : &builtin_type_const_u8; + case TYPE_STORAGE_U16: + return is_const ? &builtin_type_u16 : &builtin_type_const_u16; + case TYPE_STORAGE_U32: + return is_const ? &builtin_type_u32 : &builtin_type_const_u32; + case TYPE_STORAGE_U64: + return is_const ? &builtin_type_u64 : &builtin_type_const_u64; + case TYPE_STORAGE_UINT: + return is_const ? &builtin_type_uint : &builtin_type_const_uint; + case TYPE_STORAGE_UINTPTR: + return is_const ? &builtin_type_uintptr : &builtin_type_const_uintptr; + case TYPE_STORAGE_VOID: + return is_const ? &builtin_type_void : &builtin_type_const_void; + case TYPE_STORAGE_POINTER: + if (atype->pointer.referent->storage == TYPE_STORAGE_CHAR + && atype->pointer.referent->flags == TYPE_FLAGS_CONST) { + return &builtin_type_const_ptr_char; + } + return NULL; + case TYPE_STORAGE_ALIAS: + case TYPE_STORAGE_ARRAY: + case TYPE_STORAGE_FUNCTION: + case TYPE_STORAGE_SLICE: + case TYPE_STORAGE_STRING: + case TYPE_STORAGE_STRUCT: + case TYPE_STORAGE_TAGGED_UNION: + case TYPE_STORAGE_UNION: + return NULL; + + } + assert(0); // Unreachable +} + +static bool +type_eq_atype(struct type_store *store, + const struct type *type, + const struct ast_type *atype) +{ + if (type->storage != atype->storage || type->flags != atype->flags) { + return false; + } + + switch (type->storage) { + case TYPE_STORAGE_BOOL: + case TYPE_STORAGE_CHAR: + case TYPE_STORAGE_F32: + case TYPE_STORAGE_F64: + case TYPE_STORAGE_I8: + case TYPE_STORAGE_I16: + case TYPE_STORAGE_I32: + case TYPE_STORAGE_I64: + case TYPE_STORAGE_INT: + case TYPE_STORAGE_RUNE: + case TYPE_STORAGE_SIZE: + case TYPE_STORAGE_U8: + case TYPE_STORAGE_U16: + case TYPE_STORAGE_U32: + case TYPE_STORAGE_U64: + case TYPE_STORAGE_UINT: + case TYPE_STORAGE_UINTPTR: + case TYPE_STORAGE_VOID: + return true; + case TYPE_STORAGE_ALIAS: + case TYPE_STORAGE_ARRAY: + case TYPE_STORAGE_FUNCTION: + case TYPE_STORAGE_POINTER: + case TYPE_STORAGE_SLICE: + case TYPE_STORAGE_STRING: + case TYPE_STORAGE_STRUCT: + case TYPE_STORAGE_TAGGED_UNION: + case TYPE_STORAGE_UNION: + assert(0); // TODO + } + + assert(0); // Unreachable +} + +static void +type_init_from_atype(struct type_store *store, + struct type *type, + const struct ast_type *atype) +{ + type->storage = atype->storage; + type->flags = atype->flags; + + switch (type->storage) { + case TYPE_STORAGE_BOOL: + case TYPE_STORAGE_CHAR: + case TYPE_STORAGE_F32: + case TYPE_STORAGE_F64: + case TYPE_STORAGE_I8: + case TYPE_STORAGE_I16: + case TYPE_STORAGE_I32: + case TYPE_STORAGE_I64: + case TYPE_STORAGE_INT: + case TYPE_STORAGE_RUNE: + case TYPE_STORAGE_SIZE: + case TYPE_STORAGE_U8: + case TYPE_STORAGE_U16: + case TYPE_STORAGE_U32: + case TYPE_STORAGE_U64: + case TYPE_STORAGE_UINT: + case TYPE_STORAGE_UINTPTR: + case TYPE_STORAGE_VOID: + assert(0); // Invariant + case TYPE_STORAGE_ALIAS: + case TYPE_STORAGE_ARRAY: + case TYPE_STORAGE_FUNCTION: + case TYPE_STORAGE_POINTER: + case TYPE_STORAGE_SLICE: + case TYPE_STORAGE_STRING: + case TYPE_STORAGE_STRUCT: + case TYPE_STORAGE_TAGGED_UNION: + case TYPE_STORAGE_UNION: + assert(0); // TODO + } +} + +const struct type * +type_store_lookup_atype(struct type_store *store, const struct ast_type *atype) +{ + const struct type *builtin = builtin_for_atype(atype); + if (builtin) { + return builtin; + } + + unsigned long hash = atype_hash(store, atype); + struct type_bucket **next = &store->buckets[hash % TYPE_STORE_BUCKETS]; + + struct type_bucket *bucket; + while (*next) { + bucket = *next; + if (type_eq_atype(store, &bucket->type, atype)) { + return &bucket->type; + } + next = &bucket->next; + } + + bucket = *next = calloc(1, sizeof(struct type_bucket)); + type_init_from_atype(store, &bucket->type, atype); + return &bucket->type; +} diff --git a/src/types.c b/src/types.c @@ -140,6 +140,11 @@ builtin_type_uintptr = { .size = 8, // XXX: ARCH .align = 8, }, +builtin_type_rune = { + .storage = TYPE_STORAGE_RUNE, + .size = 4, + .align = 4, +}, builtin_type_size = { .storage = TYPE_STORAGE_SIZE, .size = 8, // XXX: ARCH @@ -149,11 +154,120 @@ builtin_type_void = { .storage = TYPE_STORAGE_VOID, .size = 0, .align = 0, +}, +builtin_type_const_bool = { + .storage = TYPE_STORAGE_BOOL, + .flags = TYPE_FLAGS_CONST, + .size = 4, // XXX: ARCH + .align = 4, +}, +builtin_type_const_char = { + .storage = TYPE_STORAGE_CHAR, + .flags = TYPE_FLAGS_CONST, + .size = 1, + .align = 1, +}, +builtin_type_const_f32 = { + .storage = TYPE_STORAGE_F32, + .flags = TYPE_FLAGS_CONST, + .size = 4, + .align = 4, +}, +builtin_type_const_f64 = { + .storage = TYPE_STORAGE_F64, + .flags = TYPE_FLAGS_CONST, + .size = 8, + .align = 8, +}, +builtin_type_const_i8 = { + .storage = TYPE_STORAGE_I8, + .flags = TYPE_FLAGS_CONST, + .size = 1, + .align = 1, +}, +builtin_type_const_i16 = { + .storage = TYPE_STORAGE_I16, + .flags = TYPE_FLAGS_CONST, + .size = 2, + .align = 2, +}, +builtin_type_const_i32 = { + .storage = TYPE_STORAGE_I32, + .flags = TYPE_FLAGS_CONST, + .size = 4, + .align = 4, +}, +builtin_type_const_i64 = { + .storage = TYPE_STORAGE_I64, + .flags = TYPE_FLAGS_CONST, + .size = 8, + .align = 8, +}, +builtin_type_const_int = { + .storage = TYPE_STORAGE_INT, + .flags = TYPE_FLAGS_CONST, + .size = 4, // XXX: ARCH + .align = 4, +}, +builtin_type_const_u8 = { + .storage = TYPE_STORAGE_U8, + .flags = TYPE_FLAGS_CONST, + .size = 1, + .align = 1, +}, +builtin_type_const_u16 = { + .storage = TYPE_STORAGE_U16, + .flags = TYPE_FLAGS_CONST, + .size = 2, + .align = 2, +}, +builtin_type_const_u32 = { + .storage = TYPE_STORAGE_U32, + .flags = TYPE_FLAGS_CONST, + .size = 4, + .align = 4, +}, +builtin_type_const_u64 = { + .storage = TYPE_STORAGE_U64, + .flags = TYPE_FLAGS_CONST, + .size = 8, + .align = 8, +}, +builtin_type_const_uint = { + .storage = TYPE_STORAGE_UINT, + .flags = TYPE_FLAGS_CONST, + .size = 4, + .align = 4, +}, +builtin_type_const_uintptr = { + .storage = TYPE_STORAGE_UINTPTR, + .flags = TYPE_FLAGS_CONST, + .size = 8, // XXX: ARCH + .align = 8, +}, +builtin_type_const_rune = { + .storage = TYPE_STORAGE_RUNE, + .flags = TYPE_FLAGS_CONST, + .size = 4, + .align = 4, +}, +builtin_type_const_size = { + .storage = TYPE_STORAGE_SIZE, + .flags = TYPE_FLAGS_CONST, + .size = 8, // XXX: ARCH + .align = 8, +}, +builtin_type_const_void = { + .storage = TYPE_STORAGE_VOID, + .flags = TYPE_FLAGS_CONST, + .size = 0, + .align = 0, }; // Selected aggregate type singletons -const struct type builtin_type_charptr = { +const struct type builtin_type_const_ptr_char = { .storage = TYPE_STORAGE_POINTER, + .flags = TYPE_FLAGS_CONST, .size = 8, // XXX: ARCH .align = 8, .pointer = {