diff --git a/Makefile b/Makefile index ba421de..144a6f2 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ -larpcc: main.c lex.c preproc.c collection.c parse.c syms.c ast_print.c resolve.c +larpcc: main.c lex.c preproc.c collection.c parse.c ast_print.c resolve.c gcc $^ -o $@ -std=c23 -pedantic -Wall -Wextra -g -fsanitize=address -Werror=switch diff --git a/main.c b/main.c index eae82f3..7065576 100644 --- a/main.c +++ b/main.c @@ -78,7 +78,9 @@ int main(int argc, char* argv[]) Parser* parser = parser_new(&tokstream, &ast_arena); - Resolver* resolver = resolver_new(); + Arena sym_arena; + arena_init(&sym_arena, 4096); + Resolver* resolver = resolver_new(&sym_arena); AstStmt* stmt; while (!parser_done(parser)) { @@ -95,7 +97,7 @@ int main(int argc, char* argv[]) preproc_free(preproc); arena_deinit(&tok_arena); - arena_deinit(&ast_arena); + arena_deinit(&sym_arena); } } diff --git a/parse.c b/parse.c index bb7519e..e04e379 100644 --- a/parse.c +++ b/parse.c @@ -1,7 +1,7 @@ #include "parse.h" #include "ast.h" #include "collection.h" -#include "syms.h" +#include "resolve.h" #include #include #include diff --git a/parse.h b/parse.h index 8a5ac31..8b0d529 100644 --- a/parse.h +++ b/parse.h @@ -3,7 +3,6 @@ #include "ast.h" #include "collection.h" -#include "syms.h" #include char* read_textfile(const char* filename); diff --git a/resolve.c b/resolve.c index cc4849a..b6d9189 100644 --- a/resolve.c +++ b/resolve.c @@ -1,18 +1,75 @@ #include "resolve.h" #include "ast.h" -#include "syms.h" +#include "collection.h" +#include #include #include +struct Syms { + ARRAY_FIELD(Hashmap, maps); +}; + +Syms* syms_new() +{ + Syms* s = malloc(sizeof(Syms)); + *s = (Syms) { + ARRAY_FIELD_INIT(maps), + }; + + ARRAY_FIELD_PUSH(s, maps, &(Hashmap) { }); + hashmap_init(&s->maps[0], sizeof(Sym*)); + + return s; +} + +void syms_free(Syms* s) +{ + free(s->maps); + free(s); +} + +void syms_push_scope(Syms* s) +{ + ARRAY_FIELD_PUSH(s, maps, &(Hashmap) { }); + hashmap_init(&s->maps[s->maps_size - 1], sizeof(Sym*)); +} + +void syms_pop_scope(Syms* s) +{ + assert(s->maps_size > 0); + hashmap_deinit(&s->maps[s->maps_size - 1]); + s->maps_size -= 1; +} + +void syms_define(Syms* s, const char* ident, Sym* sym) +{ + Hashmap* m = &s->maps[s->maps_size - 1]; + hashmap_set(m, ident, &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; +} + +typedef enum : unsigned int { + ResolverFlags_InTypedef, +} ResolverFlags; + struct Resolver { Syms* ord_syms; Syms* tag_syms; Syms* label_syms; - bool in_typedef; + Arena* arena; + + AstStmt* current_decl_stmt; + ResolverFlags flags; }; -Resolver* resolver_new() +Resolver* resolver_new(Arena* arena) { Resolver* r = malloc(sizeof(Resolver)); *r = (Resolver) { @@ -20,7 +77,10 @@ Resolver* resolver_new() .tag_syms = syms_new(), .label_syms = syms_new(), - .in_typedef = false, + .arena = arena, + + .current_decl_stmt = nullptr, + .flags = 0, }; return r; } @@ -46,16 +106,39 @@ static AstVisitorResult visit_stmt_block(AstVisitor* v, AstStmtBlock* node) static AstVisitorResult visit_stmt(AstVisitor* v, AstStmt* node) { + Resolver* r = v->op; + + if (node->ty == AstStmt_Decl) { + r->current_decl_stmt = node; + + ast_stmt_visit_body(v, node); + + return AstVisitor_Break; + } + + return AstVisitor_Continue; } static AstVisitorResult visit_decl(AstVisitor* v, AstDecl* node) { Resolver* r = v->op; + + if (node->spec & AstSpec_Typedef) { + r->flags |= ResolverFlags_InTypedef; + + ast_decl_visit_body(v, node); + + r->flags &= ~ResolverFlags_InTypedef; + return AstVisitor_Break; + } + + return AstVisitor_Continue; } static AstVisitorResult visit_declar(AstVisitor* v, AstDeclar* node) { Resolver* r = v->op; + if (node->ty == AstDeclar_Function) { syms_push_scope(r->ord_syms); @@ -65,11 +148,31 @@ static AstVisitorResult visit_declar(AstVisitor* v, AstDeclar* node) return AstVisitor_Break; } - if (node->ty == AstDeclar_Ident) { } + if (node->ty == AstDeclar_Ident) { + assert(r->current_decl_stmt); + + Sym* sym = arena_alloc(r->arena, sizeof(Sym)); + *sym = (Sym) { + .ty = Sym_Declarator, + .declarator = { + .stmt = r->current_decl_stmt, + .declar = node, + }, + }; + syms_define(r->ord_syms, node->ident, sym); + return AstVisitor_Break; + } + + return AstVisitor_Continue; } static AstVisitorResult visit_expr(AstVisitor* v, AstExpr* node) { + Resolver* r = v->op; + + if (node->ty == AstExpr_Ident) { } + + return AstVisitor_Continue; } void resolver_resolve_top_stmt(Resolver* r, AstStmt* stmt) diff --git a/resolve.h b/resolve.h index be606ef..aadb17a 100644 --- a/resolve.h +++ b/resolve.h @@ -2,10 +2,37 @@ #define RES_H #include "ast.h" +#include "collection.h" + +typedef enum { + Sym_Typedef, + Sym_Declarator, +} SymTy; + +typedef struct { + SymTy ty; + union { + struct { + AstStmt* stmt; + AstDeclar* declar; + } declarator; + }; +} Sym; + +typedef struct Syms Syms; + +Syms* syms_new(); +void syms_free(Syms* s); + +void syms_push_scope(Syms* s); +void syms_pop_scope(Syms* s); + +void syms_define(Syms* s, const char* ident, Sym* sym); +Sym* syms_get(Syms* s, const char* ident); typedef struct Resolver Resolver; -Resolver* resolver_new(); +Resolver* resolver_new(Arena* arena); void resolver_free(Resolver* r); void resolver_resolve_top_stmt(Resolver* r, AstStmt* stmt); diff --git a/syms.c b/syms.c deleted file mode 100644 index 5596f20..0000000 --- a/syms.c +++ /dev/null @@ -1,53 +0,0 @@ -#include "syms.h" -#include "collection.h" -#include -#include - -struct Syms { - ARRAY_FIELD(Hashmap, maps); -}; - -Syms* syms_new() -{ - Syms* s = malloc(sizeof(Syms)); - *s = (Syms) { - ARRAY_FIELD_INIT(maps), - }; - - ARRAY_FIELD_PUSH(s, maps, &(Hashmap) { }); - hashmap_init(&s->maps[0], sizeof(Sym*)); - - return s; -} - -void syms_free(Syms* s) -{ - free(s->maps); - free(s); -} - -void syms_push_scope(Syms* s) -{ - ARRAY_FIELD_PUSH(s, maps, &(Hashmap) { }); - hashmap_init(&s->maps[s->maps_size - 1], sizeof(Sym*)); -} - -void syms_pop_scope(Syms* s) -{ - assert(s->maps_size > 0); - hashmap_deinit(&s->maps[s->maps_size - 1]); - s->maps_size -= 1; -} - -void syms_define(Syms* s, const char* ident, Sym* sym) -{ - Hashmap* m = &s->maps[s->maps_size - 1]; - hashmap_set(m, ident, &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; -} diff --git a/syms.h b/syms.h deleted file mode 100644 index 97d34c3..0000000 --- a/syms.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef SYMS_H -#define SYMS_H - -typedef enum { - Sym_Typedef, -} SymTy; - -typedef struct { - SymTy ty; -} Sym; - -typedef struct Syms Syms; - -Syms* syms_new(); -void syms_free(Syms* s); - -void syms_push_scope(Syms* s); -void syms_pop_scope(Syms* s); - -void syms_define(Syms* s, const char* ident, Sym* sym); -Sym* syms_get(Syms* s, const char* ident); - -#endif