From 59a0cdabe9a67d5c3f296f85d29f43dcadace363 Mon Sep 17 00:00:00 2001 From: Carson Fleming Date: Thu, 26 Mar 2026 20:13:49 -0700 Subject: impl simply with no rehash --- scope.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 93 insertions(+), 6 deletions(-) (limited to 'scope.c') diff --git a/scope.c b/scope.c index 076f1a6..2fe62e1 100644 --- a/scope.c +++ b/scope.c @@ -1,9 +1,27 @@ #include "scope.h" #include +#include +#include +#define DEFAULT_SIZE 16 -static void scope_init(struct scope* scope) {} +static void scope_init(struct scope* scope) { + scope->types = calloc(DEFAULT_SIZE, sizeof(struct type_def*)); + scope->type_cap = DEFAULT_SIZE; + scope->vars = calloc(DEFAULT_SIZE, sizeof(struct var_def*)); + scope->var_cap = DEFAULT_SIZE; +} + +static void scope_destroy(struct scope* scope) { + for (unsigned long long i = 0; i < scope->type_cap; i++) { + if (scope->types[i] != NULL) free(scope->types[i]); + } + free(scope->types); -static void scope_destroy(struct scope* scope) {} + for (unsigned long long i = 0; i < scope->var_cap; i++) { + if (scope->vars[i] != NULL) free(scope->vars[i]); + } + free(scope->vars); +} unsigned long long hash_name(const char* name) { unsigned long long hash = 0, i = 0; @@ -11,6 +29,42 @@ unsigned long long hash_name(const char* name) { return hash; } +static struct type_def** type_cell( + const struct scope* scope, + const char* name +) { + unsigned long long orig_idx = hash_name(name) % scope->type_cap; + unsigned long long idx = orig_idx; + + do { + if (scope->types[idx] == NULL + || strcmp(name, scope->types[idx]->name) == 0) + return &scope->types[idx]; + } while ((idx = (idx + 1) % scope->type_cap) != orig_idx); + + /* TODO: rehashing :'( */ + fprintf(stderr, "ccc: would have to rehash and I don't wanna\n"); + exit(1); +} + +static struct var_def** var_cell( + const struct scope* scope, + const char* name +) { + unsigned long long orig_idx = hash_name(name) % scope->var_cap; + unsigned long long idx = orig_idx; + + do { + if (scope->vars[idx] == NULL + || strcmp(name, scope->vars[idx]->name) == 0) + return &scope->vars[idx]; + } while ((idx = (idx + 1) % scope->var_cap) != orig_idx); + + /* TODO: rehashing :'( */ + fprintf(stderr, "ccc: would have to rehash and I don't wanna\n"); + exit(1); +} + void scope_push(struct scope** p_scope) { struct scope* inner_scope = calloc(1, sizeof(struct scope)); scope_init(inner_scope); @@ -29,14 +83,47 @@ bool scope_get_type( const struct scope* scope, struct type_def* p_entry, const char* name -) {} +) { + struct type_def* type_def = *type_cell(scope, name); + if (type_def == NULL) return false; + *p_entry = *type_def; + return true; +} -void scope_define_type(struct scope* scope, struct type_def type) {} +void scope_define_type(struct scope* scope, struct type_def type) { + struct type_def** cell = type_cell(scope, type.name); + if (*cell != NULL) { + fprintf(stderr, "ccc: error: redefined type %s\n", type.name); + exit(1); + } + *cell = calloc(1, sizeof(struct type_def)); + if (*cell == NULL) { + fprintf(stderr, "ccc: out of memory\n"); + exit(1); + } + **cell = type; +} bool scope_get_var( const struct scope* scope, struct var_def* p_entry, const char* name -) {} +) { + struct var_def* var_def = *var_cell(scope, name); + if (var_def == NULL) return false; + *p_entry = *var_def; + return true; +} -void scope_define_var(struct scope* scope, struct var_def var) {} +void scope_define_var(struct scope* scope, struct var_def var) { + struct var_def** cell = var_cell(scope, var.name); + if (*cell == NULL) { + *cell = calloc(1, sizeof(struct var_def)); + if (*cell == NULL) { + fprintf(stderr, "ccc: out of memory\n"); + exit(1); + } + } + /* technically C allows redefinition :/ */ + **cell = var; +} -- cgit v1.2.3