diff options
Diffstat (limited to 'scope.c')
| -rw-r--r-- | scope.c | 38 |
1 files changed, 25 insertions, 13 deletions
@@ -29,6 +29,12 @@ unsigned long long hash_name(const char* name) { return hash; } +static void rehash_types(struct scope* scope) { + /* TODO: rehashing :'( */ + fprintf(stderr, "ccc: would have to rehash and I don't wanna\n"); + exit(1); +} + static struct type_def** type_cell( const struct scope* scope, const char* name @@ -41,7 +47,10 @@ static struct type_def** type_cell( || strcmp(name, scope->types[idx]->name) == 0) return &scope->types[idx]; } while ((idx = (idx + 1) % scope->type_cap) != orig_idx); + return NULL; +} +static void rehash_vars(struct scope* scope) { /* TODO: rehashing :'( */ fprintf(stderr, "ccc: would have to rehash and I don't wanna\n"); exit(1); @@ -59,10 +68,7 @@ static struct var_def** var_cell( || 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); + return NULL; } void scope_push(struct scope** p_scope) { @@ -120,9 +126,9 @@ bool scope_get_type( const char* name ) { for (; scope != NULL; scope = scope->next_out) { - struct type_def* type_def = *type_cell(scope, name); - if (type_def == NULL) continue; - if (p_entry != NULL) *p_entry = *type_def; + struct type_def** cell = type_cell(scope, name); + if (cell == NULL || *cell == NULL) continue; + if (p_entry != NULL) *p_entry = **cell; return true; } return false; @@ -130,10 +136,11 @@ bool scope_get_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); + while (cell == NULL) { + rehash_types(scope); + cell = type_cell(scope, type.name); } + *cell = calloc(1, sizeof(struct type_def)); if (*cell == NULL) { fprintf(stderr, "ccc: out of memory\n"); @@ -148,9 +155,9 @@ bool scope_get_var( const char* name ) { for (; scope != NULL; scope = scope->next_out) { - struct var_def* var_def = *var_cell(scope, name); - if (var_def == NULL) continue; - if (p_entry != NULL) *p_entry = *var_def; + struct var_def** cell = var_cell(scope, name); + if (cell == NULL || *cell == NULL) continue; + if (p_entry != NULL) *p_entry = **cell; return true; } return false; @@ -158,6 +165,11 @@ bool scope_get_var( void scope_define_var(struct scope* scope, struct var_def var) { struct var_def** cell = var_cell(scope, var.name); + while (cell == NULL) { + rehash_vars(scope); + cell = var_cell(scope, var.name); + } + if (*cell == NULL) { *cell = calloc(1, sizeof(struct var_def)); if (*cell == NULL) { |
