From 9911f9a73c7dc46069199e52f2bc54082d10366c Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Wed, 3 Jan 2018 23:10:59 +0100 Subject: Initial --- type.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 type.c (limited to 'type.c') diff --git a/type.c b/type.c new file mode 100644 index 0000000..6dd4dd0 --- /dev/null +++ b/type.c @@ -0,0 +1,79 @@ +#include +#include +#include +#include "type.h" + + +static struct { + int cap, num; + struct type **types; +} cache; + +static struct type *voidtype; + +static void init_cache(void) { + if (voidtype) return; + voidtype = malloc(sizeof(struct type)); + voidtype->tag = T_VOID; + cache.cap = 8; + cache.num = 0; + cache.types = malloc(cache.cap * sizeof(struct type*)); +} + +void type_cache_cleanup(void) { + for (int i = 0; i < cache.num; i++) { + free(cache.types[i]); + } + free(cache.types); + free(voidtype); +} + +static void cache_add(struct type *type) { + if (cache.num == cache.cap) { + cache.cap *= 2; + cache.types = realloc(cache.types, cache.cap * sizeof(struct type*)); + } + cache.types[cache.num++] = type; +} + + +struct type* type_int(int size) { + init_cache(); + for (int i = 0; i < cache.num; i++) { + if (cache.types[i]->tag == T_INT && cache.types[i]->size == size) { + return cache.types[i]; + } + } + struct type *type = malloc(sizeof(struct type)); + type->tag = T_INT; + type->size = size; + cache_add(type); + return type; +} + +struct type* type_void(void) { + return voidtype; +} + +struct type* type_ptr(struct type *target) { + init_cache(); + for (int i = 0; i < cache.num; i++) { + if (cache.types[i]->tag == T_PTR && cache.types[i]->target == target) { + return cache.types[i]; + } + } + struct type *type = malloc(sizeof(struct type)); + type->tag = T_PTR; + type->target = target; + cache_add(type); + return type; +} + +void type_print(struct type *type, FILE *f) { + switch (type->tag) { + case T_INT: fprintf(f, "i%d", type->size); break; + case T_VOID: fprintf(f, "void"); break; + case T_PTR: type_print(type->target, f); fprintf(f, "*"); break; + default: assert(false); + } +} -- cgit v1.2.3-54-g00ecf