diff options
| author | Carson Fleming <cflems@cflems.net> | 2026-07-17 04:37:37 -0400 |
|---|---|---|
| committer | Carson Fleming <cflems@cflems.net> | 2026-07-17 04:53:31 -0400 |
| commit | 99af8891f6672493939bf3b43084082884e28d04 (patch) | |
| tree | b1f94d8b78b96e0258bef9133ffa9c8faeb2e2b7 | |
| parent | 82cf7004e351c9003af3019b2f7434ed8eeabf3e (diff) | |
| download | ccc-99af8891f6672493939bf3b43084082884e28d04.tar.gz | |
fix scope thing
| -rw-r--r-- | codegen.c | 7 | ||||
| -rw-r--r-- | parser.c | 15 | ||||
| -rw-r--r-- | scope.h | 1 | ||||
| -rw-r--r-- | test/fibonacci.c | 8 | ||||
| -rw-r--r-- | type_checker.c | 3 |
5 files changed, 29 insertions, 5 deletions
@@ -100,6 +100,8 @@ static void emit_storage_loc( case STO_IMM: fprintf(outfile, "%llu", loc->value); break; + case STO_UNRESOLVED: + CGEN_PANIC("can't emit unresolved storage location"); } } @@ -120,6 +122,8 @@ static bool locs_equal( return strcmp(a->label, b->label) == 0; case STO_FN: return a->decl == b->decl; + case STO_UNRESOLVED: + return false; } CGEN_PANIC("unhandled storage type case"); } @@ -176,6 +180,8 @@ static void emit_mov( case STO_IMM: CGEN_PANIC( "can't move value into immediate value %lld", dst->loc.value); + case STO_UNRESOLVED: + CGEN_PANIC("can't move value into unresolved storage"); } fprintf(outfile, "\n"); } @@ -580,6 +586,7 @@ static void emit_fn_decl(FILE* outfile, const struct fn_decl_node* node) { while (arg_decl != NULL) { struct lval_def arg_dst = make_stack_lval(outfile, &arg_decl->decl->type); + /* TODO: type checker should define vars, we just set their loc */ scope_define_var( scope, (struct var_def) { @@ -268,7 +268,11 @@ static void parse_var_decl(struct var_decl_node* p_node) { parse_type(&p_node->type); expect(TK_IDENT); p_node->ident = tok.data.ident; - scope_define_var(scope, (struct var_def) { .name = p_node->ident }); + scope_define_var(scope, (struct var_def) { + .name = p_node->ident, + .loc.type = STO_UNRESOLVED, + .sz = 0, /* unknown */ + }); } static void parse_stmt(struct stmt_node* p_node); @@ -389,10 +393,7 @@ static void parse_fn_decl(struct fn_decl_node* p_node) { expect(TK_RPAREN); - parse_group(&p_node->body); - - scope_pop(&scope); - + /* defining here makes recursion possible */ scope_define_var(scope, (struct var_def) { .name = p_node->name, .loc = { @@ -400,6 +401,10 @@ static void parse_fn_decl(struct fn_decl_node* p_node) { .decl = p_node, }, }); + + parse_group(&p_node->body); + + scope_pop(&scope); } static bool parse_root(struct root_node* p_node) { @@ -8,6 +8,7 @@ struct storage_location { STO_STACK, STO_IMM, STO_FN, + STO_UNRESOLVED, } type; union { const struct reg* reg; diff --git a/test/fibonacci.c b/test/fibonacci.c new file mode 100644 index 0000000..c241be9 --- /dev/null +++ b/test/fibonacci.c @@ -0,0 +1,8 @@ +int fib (int n) { + if (n <= 1) return 1; + return n * fib(n - 1); +} + +int main (int argc, char** argv) { + return fib(argc); +} diff --git a/type_checker.c b/type_checker.c index f914c34..d1a6c32 100644 --- a/type_checker.c +++ b/type_checker.c @@ -48,11 +48,14 @@ static void type_check_group(struct group_node* node) { type_check_stmt(stmt); stmt = stmt->next; } + scope = scope->next_out; } static void type_check_fn_decl(struct fn_decl_node* node) { + if (node->scope->next_out != scope) TYPE_PANIC("scopes are borked"); scope = node->scope; type_check_group(&node->body); + scope = scope->next_out; } static void type_check_root(struct root_node* node) { |
