summaryrefslogtreecommitdiff
path: root/scope.c
diff options
context:
space:
mode:
Diffstat (limited to 'scope.c')
-rw-r--r--scope.c72
1 files changed, 53 insertions, 19 deletions
diff --git a/scope.c b/scope.c
index 310a111..17bc22b 100644
--- a/scope.c
+++ b/scope.c
@@ -2,7 +2,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#define DEFAULT_SIZE 16
+#define DEFAULT_SIZE 4
static void scope_init(struct scope* scope) {
scope->types = calloc(DEFAULT_SIZE, sizeof(struct type_def*));
@@ -29,12 +29,6 @@ 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
@@ -50,10 +44,27 @@ static struct type_def** type_cell(
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);
+static void rehash_types(struct scope* scope) {
+ struct type_def** old_types = scope->types;
+ unsigned long long old_cap = scope->type_cap;
+ scope->type_cap *= 2;
+ scope->types = calloc(scope->type_cap, sizeof(struct type_def*));
+ if (scope->types == NULL) {
+ fprintf(stderr, "ccc: out of memory\n");
+ exit(1);
+ }
+
+ for (unsigned long long i = 0; i < old_cap; i++) {
+ if (old_types[i] == NULL) continue;
+
+ struct type_def** cell = type_cell(scope, old_types[i]->name);
+ if (cell == NULL) {
+ fprintf(stderr, "ccc: types rehash failed, likely a bug\n");
+ exit(1);
+ }
+ *cell = old_types[i];
+ }
+ free(old_types);
}
static struct var_def** var_cell(
@@ -71,6 +82,29 @@ static struct var_def** var_cell(
return NULL;
}
+static void rehash_vars(struct scope* scope) {
+ struct var_def** old_vars = scope->vars;
+ unsigned long long old_cap = scope->var_cap;
+ scope->var_cap *= 2;
+ scope->vars = calloc(scope->var_cap, sizeof(struct var_def*));
+ if (scope->vars == NULL) {
+ fprintf(stderr, "ccc: out of memory\n");
+ exit(1);
+ }
+
+ for (unsigned long long i = 0; i < old_cap; i++) {
+ if (old_vars[i] == NULL) continue;
+
+ struct var_def** cell = var_cell(scope, old_vars[i]->name);
+ if (cell == NULL) {
+ fprintf(stderr, "ccc: vars rehash failed, likely a bug\n");
+ exit(1);
+ }
+ *cell = old_vars[i];
+ }
+ free(old_vars);
+}
+
void scope_push(struct scope** p_scope) {
struct scope* inner_scope = calloc(1, sizeof(struct scope));
scope_init(inner_scope);
@@ -88,35 +122,35 @@ void scope_pop(struct scope** p_scope) {
void scope_install_default_types(struct scope* scope) {
scope_define_type(scope, (struct type_def) {
.name = "void",
- .size = 0,
+ .sz = 0,
});
scope_define_type(scope, (struct type_def) {
.name = "bool",
- .size = 1,
+ .sz = 1,
});
scope_define_type(scope, (struct type_def) {
.name = "char",
- .size = 1,
+ .sz = 1,
});
scope_define_type(scope, (struct type_def) {
.name = "short",
- .size = 2,
+ .sz = 2,
});
scope_define_type(scope, (struct type_def) {
.name = "int",
- .size = 4,
+ .sz = 4,
});
scope_define_type(scope, (struct type_def) {
.name = "float",
- .size = 4,
+ .sz = 4,
});
scope_define_type(scope, (struct type_def) {
.name = "long",
- .size = 8,
+ .sz = 8,
});
scope_define_type(scope, (struct type_def) {
.name = "double",
- .size = 8,
+ .sz = 8,
});
}