From 48587d47de4d21148f1c02c898e82935f81fcf93 Mon Sep 17 00:00:00 2001 From: sfja Date: Fri, 2 Oct 2026 22:22:28 +0200 Subject: [PATCH] resolve --- ast_print.c | 5 +-- collection.c | 21 +++-------- main.c | 13 ++----- resolve.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 104 insertions(+), 35 deletions(-) diff --git a/ast_print.c b/ast_print.c index af70782..76f5f16 100644 --- a/ast_print.c +++ b/ast_print.c @@ -315,6 +315,8 @@ void ast_decl_visit_body(AstVisitor* v, AstDecl* node) { for (size_t i = 0; i < node->declars_size; ++i) ast_declar_visit(v, node->declars[i]); + if (node->function_body) + ast_stmt_block_visit(v, node->function_body); } void ast_declar_visit(AstVisitor* v, AstDeclar* node) @@ -337,7 +339,7 @@ void ast_declar_visit_body(AstVisitor* v, AstDeclar* node) ast_expr_visit(v, node->array.expr); break; case AstDeclar_Function: - ast_declar_visit(v, node->pointer.declar); + ast_declar_visit(v, node->function.declar); for (size_t i = 0; i < node->function.params_size; ++i) ast_decl_visit(v, node->function.params[i]); break; @@ -353,7 +355,6 @@ void ast_expr_visit(AstVisitor* v, AstExpr* node) void ast_expr_visit_body(AstVisitor* v, AstExpr* node) { - switch (node->ty) { case AstExpr_Ident: break; diff --git a/collection.c b/collection.c index 022091c..9ff0618 100644 --- a/collection.c +++ b/collection.c @@ -292,16 +292,6 @@ void keymap_set(Keymap* m, KeymapKey key, void* value) return; } - printf("index = %ld\n", result.idx); - - if (m->entries_size) { - if (keymap_idx(m, result.idx)->key < key) { - printf("key is bigger\n"); - } else { - printf("key is smaller\n"); - } - } - KeymapEntry* entry = m->temp_entry; memset(entry, 0, m->entry_size); @@ -321,11 +311,10 @@ void keymap_set(Keymap* m, KeymapKey key, void* value) } memcpy(keymap_idx(m, result.idx), entry, m->entry_size); - - for (size_t i = 0; i < m->entries_size; ++i) { - KeymapEntry* entry = keymap_idx(m, i); - printf(" %ld -> %d\n", entry->key, *(int*)entry->value); - } } -void* keymap_get(Keymap* m, KeymapKey key); +void* keymap_get(Keymap* m, KeymapKey key) +{ + struct SearchResult result = keymap_search(m, 0, m->entries_size, key); + return result.entry ? &result.entry->value : nullptr; +} diff --git a/main.c b/main.c index cea8a8e..249ec30 100644 --- a/main.c +++ b/main.c @@ -89,6 +89,8 @@ int main(int argc, char* argv[]) ast_stmt_print(stdout, stmt, 0); printf("\n"); + + resolver_resolve_top_stmt(resolver, stmt); } resolver_free(resolver); @@ -100,15 +102,4 @@ int main(int argc, char* argv[]) arena_deinit(&ast_arena); arena_deinit(&sym_arena); } - - Keymap map; - keymap_init(&map, sizeof(int)); - - int a[] = { 3, 1, 4, 1 }; - keymap_set(&map, 4, &a[3]); - keymap_set(&map, 3, &a[2]); - keymap_set(&map, 2, &a[1]); - keymap_set(&map, 1, &a[0]); - - keymap_deinit(&map); } diff --git a/resolve.c b/resolve.c index b6d9189..60a21e0 100644 --- a/resolve.c +++ b/resolve.c @@ -24,6 +24,8 @@ Syms* syms_new() void syms_free(Syms* s) { + for (size_t i = 0; i < s->maps_size; ++i) + hashmap_deinit(&s->maps[i]); free(s->maps); free(s); } @@ -49,9 +51,50 @@ void syms_define(Syms* s, const char* ident, Sym* sym) Sym* syms_get(Syms* s, const char* ident) { - Hashmap* m = &s->maps[s->maps_size - 1]; - Sym** res = hashmap_get(m, ident); - return res ? *res : nullptr; + Sym** res; + for (size_t i = 0; i < s->maps_size; ++i) + if ((res = hashmap_get(&s->maps[s->maps_size - i - 1], ident))) + return *res; + return nullptr; +} + +static void print_sym(Sym* s) +{ + switch (s->ty) { + case Sym_Typedef: + printf("Typedef"); + break; + case Sym_Declarator: + printf("Declarator"); + break; + } +} + +struct SymPrinter { + int depth; +}; + +static void print_sym_hashmap(void* self, const char* key, void* val) +{ + struct SymPrinter* p = self; + Sym* sym = *(Sym**)val; + + printf(" "); + for (int i = 0; i < p->depth; ++i) + printf(" "); + printf("'%s' -> ", key); + print_sym(sym); + printf("\n"); +} + +void syms_print(Syms* s) +{ + for (size_t i = 0; i < s->maps_size; ++i) { + struct SymPrinter p = { + .depth = i, + }; + hashmap_for_each(&s->maps[i], print_sym_hashmap, &p); + } } typedef enum : unsigned int { @@ -65,6 +108,8 @@ struct Resolver { Arena* arena; + Keymap resol_map; + AstStmt* current_decl_stmt; ResolverFlags flags; }; @@ -79,14 +124,21 @@ Resolver* resolver_new(Arena* arena) .arena = arena, + .resol_map = { }, + .current_decl_stmt = nullptr, .flags = 0, }; + + keymap_init(&r->resol_map, sizeof(Sym*)); + return r; } void resolver_free(Resolver* r) { + keymap_deinit(&r->resol_map); + syms_free(r->ord_syms); syms_free(r->tag_syms); syms_free(r->label_syms); @@ -132,6 +184,26 @@ static AstVisitorResult visit_decl(AstVisitor* v, AstDecl* node) return AstVisitor_Break; } + if (node->function_body) { + + assert(node->declars_size == 1 + && node->declars[0]->ty == AstDeclar_Function); + + AstDeclar* d = node->declars[0]; + + ast_declar_visit(v, d->function.declar); + + syms_push_scope(r->ord_syms); + + for (size_t i = 0; i < d->function.params_size; ++i) + ast_decl_visit(v, d->function.params[i]); + + ast_stmt_block_visit(v, node->function_body); + + syms_pop_scope(r->ord_syms); + return AstVisitor_Break; + } + return AstVisitor_Continue; } @@ -140,9 +212,12 @@ static AstVisitorResult visit_declar(AstVisitor* v, AstDeclar* node) Resolver* r = v->op; if (node->ty == AstDeclar_Function) { + ast_declar_visit(v, node->function.declar); + syms_push_scope(r->ord_syms); - ast_declar_visit_body(v, node); + for (size_t i = 0; i < node->function.params_size; ++i) + ast_decl_visit(v, node->function.params[i]); syms_pop_scope(r->ord_syms); return AstVisitor_Break; @@ -170,7 +245,20 @@ static AstVisitorResult visit_expr(AstVisitor* v, AstExpr* node) { Resolver* r = v->op; - if (node->ty == AstExpr_Ident) { } + if (node->ty == AstExpr_Ident) { + + Sym* sym = syms_get(r->ord_syms, node->ident); + if (!sym) { + fprintf(stderr, + "error: use of undeclared '%s' on line %d\n", + node->ident, + node->loc.line); + + syms_print(r->ord_syms); + + exit(1); + } + } return AstVisitor_Continue; } @@ -192,5 +280,5 @@ void resolver_resolve_top_stmt(Resolver* r, AstStmt* stmt) .op = r, }; - visit_stmt(&v, stmt); + ast_stmt_visit(&v, stmt); }