harec

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

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:
Mconfigure | 4+++-
Ainclude/type_store.h | 20++++++++++++++++++++
Minclude/types.h | 46++++++++++++++++++++++++++++++++++++++++++++--
Ainclude/util.h | 9+++++++++
Asrc/type_store.c | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/types.c | 98+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/util.c | 17+++++++++++++++++
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; +}