From 03a7d5f44dfd8c455706b2c5c23217fd140f18c2 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Tue, 17 Sep 2024 16:20:30 -0400 Subject: Overhaul of header logic so it now uses topological ordering and deduplication for libraries with multiple files. --- ast.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'ast.c') diff --git a/ast.c b/ast.c index b4a75277..0d2d6e5b 100644 --- a/ast.c +++ b/ast.c @@ -1,8 +1,8 @@ // Some basic operations defined on AST nodes, mainly converting to // strings for debugging. #include -#include #include +#include #include "ast.h" #include "stdlib/datatypes.h" @@ -264,9 +264,11 @@ void _visit_topologically(ast_t *ast, Table_t definitions, Table_t *visited, Clo void visit_topologically(ast_list_t *asts, Closure_t fn) { - // Visit each top-level statement in topological order, where typedefs are - // visited first, and each typedef's referenced types are visited before it - // is, when applicable. + // Visit each top-level statement in topological order: + // - 'use' statements first + // - then typedefs + // - visiting typedefs' dependencies first + // - then function/variable declarations Table_t definitions = {}; for (ast_list_t *stmt = asts; stmt; stmt = stmt->next) { @@ -282,14 +284,24 @@ void visit_topologically(ast_list_t *asts, Closure_t fn) } } + void (*visit)(void*, ast_t*) = (void*)fn.fn; Table_t visited = {}; + // First: 'use' statements in order: + for (ast_list_t *stmt = asts; stmt; stmt = stmt->next) { + if (stmt->ast->tag == Use || (stmt->ast->tag == Declare && Match(stmt->ast, Declare)->value->tag == Use)) + visit(fn.userdata, stmt->ast); + } + // Then typedefs in topological order: for (ast_list_t *stmt = asts; stmt; stmt = stmt->next) { if (stmt->ast->tag == StructDef || stmt->ast->tag == EnumDef || stmt->ast->tag == LangDef) _visit_topologically(stmt->ast, definitions, &visited, fn); } + // Then everything else in order: for (ast_list_t *stmt = asts; stmt; stmt = stmt->next) { - if (!(stmt->ast->tag == StructDef || stmt->ast->tag == EnumDef || stmt->ast->tag == LangDef)) - _visit_topologically(stmt->ast, definitions, &visited, fn); + if (!(stmt->ast->tag == StructDef || stmt->ast->tag == EnumDef || stmt->ast->tag == LangDef + || stmt->ast->tag == Use || (stmt->ast->tag == Declare && Match(stmt->ast, Declare)->value->tag == Use))) { + visit(fn.userdata, stmt->ast); + } } } -- cgit v1.2.3