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:
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 = ¶m->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 *