harec

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

commit 22a14cc43200c82506973b148aea42eb333fa734
parent 770c3280c3f8fc7a1f6e8956831457679fada79a
Author: Eyal Sawady <ecs@d2evs.net>
Date:   Wed, 30 Dec 2020 03:03:44 -0500

type store: remove type_eq_atype and atype_hash

Replace them with a combination of type_eq_type, type_hash, and
type_init_from_atype.

Diffstat:
Minclude/type_store.h | 3---
Msrc/type_store.c | 196+++++++++++++++----------------------------------------------------------------
2 files changed, 37 insertions(+), 162 deletions(-)

diff --git a/include/type_store.h b/include/type_store.h @@ -20,9 +20,6 @@ struct type_store { bool type_is_assignable(struct type_store *store, const struct type *to, const struct type *from); -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); diff --git a/src/type_store.c b/src/type_store.c @@ -168,66 +168,7 @@ builtin_type_for_storage(enum type_storage storage, bool is_const) assert(0); // Unreachable } -unsigned long -atype_hash(struct type_store *store, const struct ast_type *type) -{ - unsigned long hash = DJB2_INIT; - hash = djb2(hash, type->storage); - hash = djb2(hash, type->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_NULL: - 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: - case TYPE_STORAGE_STRING: - break; // built-ins - case TYPE_STORAGE_ALIAS: - assert(0); // TODO - case TYPE_STORAGE_ARRAY: - hash = djb2(hash, atype_hash(store, type->array.members)); - hash = djb2(hash, ast_array_len(store, type)); - break; - case TYPE_STORAGE_FUNCTION: - hash = djb2(hash, atype_hash(store, type->func.result)); - hash = djb2(hash, type->func.variadism); - hash = djb2(hash, type->func.flags); - for (struct ast_function_parameters *param = type->func.params; - param; param = param->next) { - hash = djb2(hash, atype_hash(store, param->type)); - } - break; - case TYPE_STORAGE_ENUM: - assert(0); // TODO - case TYPE_STORAGE_POINTER: - hash = djb2(hash, type->pointer.flags); - hash = atype_hash(store, type->pointer.referent); - break; - case TYPE_STORAGE_SLICE: - case TYPE_STORAGE_STRUCT: - case TYPE_STORAGE_TAGGED_UNION: - case TYPE_STORAGE_UNION: - assert(0); // TODO - } - return hash; -} - -unsigned long +static unsigned long type_hash(struct type_store *store, const struct type *type) { unsigned long hash = DJB2_INIT; @@ -300,76 +241,6 @@ builtin_for_type(const struct type *type) } 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_NULL: - 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: - assert(0); // TODO - case TYPE_STORAGE_ARRAY: - return type->array.length == ast_array_len(store, atype) - && type_eq_atype(store, type->array.members, atype->array.members); - case TYPE_STORAGE_ENUM: - assert(0); // TODO - case TYPE_STORAGE_FUNCTION: - if (!type_eq_atype(store, type->func.result, atype->func.result) - || type->func.variadism != atype->func.variadism - || type->func.flags != atype->func.flags) { - return false; - } - struct ast_function_parameters *aparam; - struct type_func_param *param; - for (aparam = atype->func.params, param = type->func.params; - aparam && param; - aparam = aparam->next, param = param->next) { - if (!!aparam->next != !!param->next) { - return false; - } - if (!type_eq_atype(store, param->type, aparam->type)) { - return false; - } - } - return true; - case TYPE_STORAGE_POINTER: - return type->pointer.flags == atype->pointer.flags && - type_eq_atype(store, type->pointer.referent, atype->pointer.referent); - 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 bool type_eq_type(struct type_store *store, const struct type *a, const struct type *b) { @@ -549,7 +420,8 @@ type_init_from_type(struct type_store *store, case TYPE_STORAGE_ALIAS: assert(0); // TODO case TYPE_STORAGE_ARRAY: - new->array.members = old->array.members; + new->array.members = + type_store_lookup_type(store, old->array.members); new->array.length = old->array.length; new->array.expandable = old->array.expandable; new->align = new->array.members->align; @@ -560,8 +432,24 @@ type_init_from_type(struct type_store *store, } break; case TYPE_STORAGE_ENUM: - case TYPE_STORAGE_FUNCTION: assert(0); // TODO + case TYPE_STORAGE_FUNCTION: + new->size = SIZE_UNDEFINED; + new->align = SIZE_UNDEFINED; + new->func.result = + type_store_lookup_type(store, old->func.result); + new->func.variadism = old->func.variadism; + for (struct type_func_param *oparam = old->func.params, + *param, **next = &new->func.params; oparam; + oparam = oparam->next) { + param = *next = + xcalloc(1, sizeof(struct type_func_param)); + param->type = + type_store_lookup_type(store, oparam->type); + next = &param->next; + } + new->func.flags = old->func.flags; + break; case TYPE_STORAGE_POINTER: new->size = 8; // XXX: ARCH new->align = 8; @@ -578,55 +466,45 @@ type_init_from_type(struct type_store *store, } } -const struct type * -type_store_lookup_atype(struct type_store *store, const struct ast_type *atype) +// Used internally for looking up modified forms of other types and for +// inserting types into the type store +static const struct type * +type_store_lookup_type(struct type_store *store, const struct type *type) { - const struct type *builtin = builtin_for_atype(atype); + const struct type *builtin = builtin_for_type(type); if (builtin) { return builtin; } - unsigned long hash = atype_hash(store, atype); - struct type_bucket **next = &store->buckets[hash % TYPE_STORE_BUCKETS]; + unsigned long hash = type_hash(store, type); + struct type_bucket **next = &store->buckets[hash % TYPE_STORE_BUCKETS], + *bucket = NULL; - struct type_bucket *bucket; while (*next) { bucket = *next; - if (type_eq_atype(store, &bucket->type, atype)) { + if (type_eq_type(store, &bucket->type, type)) { return &bucket->type; } next = &bucket->next; } bucket = *next = xcalloc(1, sizeof(struct type_bucket)); - type_init_from_atype(store, &bucket->type, atype); + // XXX: can we replace this with memcpy? + type_init_from_type(store, &bucket->type, type); return &bucket->type; } -// Used internally for looking up modified forms of other types -static const struct type * -type_store_lookup_type(struct type_store *store, const struct type *type) +const struct type * +type_store_lookup_atype(struct type_store *store, const struct ast_type *atype) { - const struct type *builtin = builtin_for_type(type); + const struct type *builtin = builtin_for_atype(atype); if (builtin) { return builtin; } - unsigned long hash = type_hash(store, type); - struct type_bucket **next = &store->buckets[hash % TYPE_STORE_BUCKETS]; - - struct type_bucket *bucket; - while (*next) { - bucket = *next; - if (type_eq_type(store, &bucket->type, type)) { - return &bucket->type; - } - next = &bucket->next; - } - - bucket = *next = xcalloc(1, sizeof(struct type_bucket)); - type_init_from_type(store, &bucket->type, type); - return &bucket->type; + struct type type = {0}; + type_init_from_atype(store, &type, atype); + return type_store_lookup_type(store, &type); } const struct type *