summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarson Fleming <cflems@cflems.net>2026-03-28 10:42:09 -1000
committerCarson Fleming <cflems@cflems.net>2026-03-28 10:42:09 -1000
commit0dc409ab0967d9973f36c138825067462b9a216f (patch)
tree0704d9f0a669a731907f26fac22249c1a25e17a4
parent33d10c0a684eaacb59102e2e2c2494ef54113aa1 (diff)
downloadccc-0dc409ab0967d9973f36c138825067462b9a216f.tar.gz
one step toward rehashing
-rw-r--r--parser.c19
-rw-r--r--scope.c38
2 files changed, 36 insertions, 21 deletions
diff --git a/parser.c b/parser.c
index 8166ea5..d7dc3fb 100644
--- a/parser.c
+++ b/parser.c
@@ -90,21 +90,24 @@ static void parse_var_ref(struct var_ref_node* p_node) {
p_node->ident = tok.data.ident;
}
-static void parse_expr_assign(struct expr_node* p_node) {
- peek_or_panic();
- if (tok.type != TK_ASSIGN) return;
-
- switch (p_node->type) {
+static void expr_to_lval(struct lval_node* l_node, struct expr_node* e_node) {
+ switch (e_node->type) {
case EXPR_VAR_REF:
- p_node->as._assign.lval = (struct lval_node) {
+ *l_node = (struct lval_node) {
.type = LVAL_VAR_REF,
- .as._var_ref = p_node->as._var_ref,
+ .as._var_ref = e_node->as._var_ref,
};
- break;
+ return;
default:
PARSER_PANIC("expression is not assignable");
}
+}
+
+static void parse_expr_assign(struct expr_node* p_node) {
+ peek_or_panic();
+ if (tok.type != TK_ASSIGN) return;
+ expr_to_lval(&p_node->as._assign.lval, p_node);
p_node->type = EXPR_ASSIGN;
p_node->as._assign.rval = protected_alloc(sizeof(struct expr_node));
diff --git a/scope.c b/scope.c
index 3bd070b..310a111 100644
--- a/scope.c
+++ b/scope.c
@@ -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) {