commit 495539655c0eea80c7f26080277d316f4f55610c
parent 4c589689bdb1818a767f87fa51727916a1c90008
Author: Drew DeVault <sir@cmpwn.com>
Date: Sat, 12 Dec 2020 08:33:10 -0500
Initial riggings for type graph
Diffstat:
7 files changed, 272 insertions(+), 3 deletions(-)
diff --git a/configure b/configure
@@ -9,8 +9,10 @@ harec() {
src/main.c \
src/parse.c \
src/trace.c \
+ src/type_store.c \
src/types.c \
- src/utf8.c
+ src/utf8.c \
+ src/util.c
}
all="harec"
diff --git a/include/type_store.h b/include/type_store.h
@@ -0,0 +1,20 @@
+#ifndef HARE_TYPESTORE_H
+#define HARE_TYPESTORE_H
+#include "ast.h"
+#include "types.h"
+
+#define TYPE_STORE_BUCKETS 256
+
+struct types {
+ struct type type;
+ struct types *next;
+};
+
+struct type_store {
+ struct type 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);
+
+#endif
diff --git a/include/types.h b/include/types.h
@@ -9,17 +9,17 @@ enum type_storage {
TYPE_STORAGE_CHAR,
TYPE_STORAGE_F32,
TYPE_STORAGE_F64,
+ TYPE_STORAGE_I8,
TYPE_STORAGE_I16,
TYPE_STORAGE_I32,
TYPE_STORAGE_I64,
- TYPE_STORAGE_I8,
TYPE_STORAGE_INT,
TYPE_STORAGE_RUNE,
TYPE_STORAGE_SIZE,
+ TYPE_STORAGE_U8,
TYPE_STORAGE_U16,
TYPE_STORAGE_U32,
TYPE_STORAGE_U64,
- TYPE_STORAGE_U8,
TYPE_STORAGE_UINT,
TYPE_STORAGE_UINTPTR,
TYPE_STORAGE_VOID,
@@ -35,5 +35,47 @@ enum type_storage {
TYPE_STORAGE_UNION,
};
+#define SIZE_UNDEFINED ((size_t)-1)
+
+struct type;
+
+struct type_pointer {
+ bool nullable;
+ const struct type *referent;
+};
+
+struct type {
+ enum type_storage storage;
+ bool constant;
+ size_t size, align;
+ union {
+ struct type_pointer pointer;
+ };
+};
+
const char *type_storage_unparse(enum type_storage storage);
+
+// Built-in type singletons
+extern const struct type
+ // Primitive
+ builtin_type_bool,
+ builtin_type_char,
+ builtin_type_f32,
+ builtin_type_f64,
+ builtin_type_i8,
+ builtin_type_i16,
+ builtin_type_i32,
+ builtin_type_i64,
+ builtin_type_int,
+ builtin_type_u8,
+ builtin_type_u16,
+ builtin_type_u32,
+ builtin_type_u64,
+ builtin_type_uint,
+ builtin_type_uintptr,
+ builtin_type_size,
+ builtin_type_void,
+ // Aggregate
+ builtin_type_charptr;
+
#endif
diff --git a/include/util.h b/include/util.h
@@ -0,0 +1,9 @@
+#ifndef HARE_UTIL_H
+#define HARE_UTIL_H
+
+#define DJB2_INIT 5381
+
+unsigned long djb2(unsigned long hash, char c);
+unsigned long djb2_s(unsigned long hash, const char *str);
+
+#endif
diff --git a/src/type_store.c b/src/type_store.c
@@ -0,0 +1,81 @@
+#include <assert.h>
+#include "type_store.h"
+#include "util.h"
+
+unsigned long
+atype_hash(struct type_store *store, const struct ast_type *type)
+{
+ unsigned long hash = DJB2_INIT;
+ hash = djb2(hash, type->storage);
+ 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:
+ break; // built-ins
+ 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
+ }
+ return hash;
+}
+
+unsigned long
+type_hash(struct type_store *store, const struct type *type)
+{
+ unsigned long hash = DJB2_INIT;
+ hash = djb2(hash, type->storage);
+ 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:
+ break; // built-ins
+ 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
+ }
+ return hash;
+}
diff --git a/src/types.c b/src/types.c
@@ -1,4 +1,5 @@
#include <assert.h>
+#include <stdbool.h>
#include "types.h"
const char *
@@ -62,3 +63,100 @@ type_storage_unparse(enum type_storage storage)
}
assert(0);
}
+
+// Built-in type singletons
+const struct type builtin_type_bool = {
+ .storage = TYPE_STORAGE_BOOL,
+ .size = 4, // XXX: ARCH
+ .align = 4,
+},
+builtin_type_char = {
+ .storage = TYPE_STORAGE_CHAR,
+ .size = 1,
+ .align = 1,
+},
+builtin_type_f32 = {
+ .storage = TYPE_STORAGE_F32,
+ .size = 4,
+ .align = 4,
+},
+builtin_type_f64 = {
+ .storage = TYPE_STORAGE_F64,
+ .size = 8,
+ .align = 8,
+},
+builtin_type_i8 = {
+ .storage = TYPE_STORAGE_I8,
+ .size = 1,
+ .align = 1,
+},
+builtin_type_i16 = {
+ .storage = TYPE_STORAGE_I16,
+ .size = 2,
+ .align = 2,
+},
+builtin_type_i32 = {
+ .storage = TYPE_STORAGE_I32,
+ .size = 4,
+ .align = 4,
+},
+builtin_type_i64 = {
+ .storage = TYPE_STORAGE_I64,
+ .size = 8,
+ .align = 8,
+},
+builtin_type_int = {
+ .storage = TYPE_STORAGE_INT,
+ .size = 4, // XXX: ARCH
+ .align = 4,
+},
+builtin_type_u8 = {
+ .storage = TYPE_STORAGE_U8,
+ .size = 1,
+ .align = 1,
+},
+builtin_type_u16 = {
+ .storage = TYPE_STORAGE_U16,
+ .size = 2,
+ .align = 2,
+},
+builtin_type_u32 = {
+ .storage = TYPE_STORAGE_U32,
+ .size = 4,
+ .align = 4,
+},
+builtin_type_u64 = {
+ .storage = TYPE_STORAGE_U64,
+ .size = 8,
+ .align = 8,
+},
+builtin_type_uint = {
+ .storage = TYPE_STORAGE_UINT,
+ .size = 4,
+ .align = 4,
+},
+builtin_type_uintptr = {
+ .storage = TYPE_STORAGE_UINTPTR,
+ .size = 8, // XXX: ARCH
+ .align = 8,
+},
+builtin_type_size = {
+ .storage = TYPE_STORAGE_SIZE,
+ .size = 8, // XXX: ARCH
+ .align = 8,
+},
+builtin_type_void = {
+ .storage = TYPE_STORAGE_VOID,
+ .size = 0,
+ .align = 0,
+};
+
+// Selected aggregate type singletons
+const struct type builtin_type_charptr = {
+ .storage = TYPE_STORAGE_POINTER,
+ .size = 8, // XXX: ARCH
+ .align = 8,
+ .pointer = {
+ .referent = &builtin_type_char,
+ },
+};
diff --git a/src/util.c b/src/util.c
@@ -0,0 +1,17 @@
+#include "util.h"
+
+unsigned long
+djb2(unsigned long hash, char c)
+{
+ return ((hash << 5) + hash) + c;
+}
+
+unsigned long
+djb2_s(unsigned long hash, const char *str)
+{
+ char c;
+ while ((c = *str++)) {
+ hash = djb2(hash, c);
+ }
+ return hash;
+}