From 99af8891f6672493939bf3b43084082884e28d04 Mon Sep 17 00:00:00 2001 From: Carson Fleming Date: Fri, 17 Jul 2026 04:37:37 -0400 Subject: fix scope thing --- codegen.c | 7 +++++++ parser.c | 15 ++++++++++----- scope.h | 1 + test/fibonacci.c | 8 ++++++++ type_checker.c | 3 +++ 5 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 test/fibonacci.c diff --git a/codegen.c b/codegen.c index ae94d9f..bdc3cbf 100644 --- a/codegen.c +++ b/codegen.c @@ -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) { diff --git a/parser.c b/parser.c index 42a7f49..e078ae9 100644 --- a/parser.c +++ b/parser.c @@ -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) { diff --git a/scope.h b/scope.h index 2dfa110..dfbb2c1 100644 --- a/scope.h +++ b/scope.h @@ -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) { -- cgit v1.2.3