From e084b48fd381177d444727b811140f76f791cbbb Mon Sep 17 00:00:00 2001 From: lisyarus Date: Mon, 23 Mar 2026 00:11:33 +0300 Subject: [PATCH] Refactor IR compiler: get rid of useless scoping --- libs/ir/include/pslang/ir/compiler.hpp | 20 ++-- libs/ir/source/compiler.cpp | 130 +++++++------------------ 2 files changed, 44 insertions(+), 106 deletions(-) diff --git a/libs/ir/include/pslang/ir/compiler.hpp b/libs/ir/include/pslang/ir/compiler.hpp index 95bef71..35b3d0a 100644 --- a/libs/ir/include/pslang/ir/compiler.hpp +++ b/libs/ir/include/pslang/ir/compiler.hpp @@ -8,23 +8,23 @@ namespace pslang::ast { - struct function_definition; + struct function_definition; } namespace pslang::ir { - struct module_context - { - node_list nodes; + struct module_context + { + node_list nodes; - std::unordered_map labels; + std::unordered_map labels; - std::unordered_map symbols; - node_ref entry_point; - }; + std::unordered_map symbols; + node_ref entry_point; + }; - void compile(module_context & context, ast::statement_list_ptr const & statements); + void compile(module_context & context, ast::statement_list_ptr const & statements); -} \ No newline at end of file +} diff --git a/libs/ir/source/compiler.cpp b/libs/ir/source/compiler.cpp index 1e71eb2..9bb651c 100644 --- a/libs/ir/source/compiler.cpp +++ b/libs/ir/source/compiler.cpp @@ -11,18 +11,16 @@ namespace pslang::ir namespace { + struct local_context { std::unordered_map functions; + std::unordered_map foreign_functions; + std::unordered_map variables; struct scope { std::string label_prefix; - - std::unordered_map variables; - std::unordered_set foreign_functions; - std::unordered_map functions; - std::unordered_map structs; }; std::vector scopes; @@ -43,43 +41,6 @@ namespace pslang::ir std::vector resolve_call; }; - // Iterate over a single scope (i.e. not visiting subscopes recursively) - // and add all defined functions & foreign functions to the current scope - struct populate_symbols_visitor - : ast::const_statement_visitor - { - local_context & lcontext; - - using const_statement_visitor::apply; - - void apply(ast::expression_ptr const &) {} - - void apply(ast::assignment const &) {} - - void apply(ast::variable_declaration const &) {} - - void apply(ast::if_chain const &) {} - - void apply(ast::while_block const &) {} - - void apply(ast::function_definition const & node) - { - lcontext.scopes.back().functions[node.name] = &node; - } - - void apply(ast::foreign_function_declaration const & node) - { - lcontext.scopes.back().foreign_functions.insert(node.name); - } - - void apply(ast::return_statement const &) {} - - void apply(ast::struct_definition const & node) - { - lcontext.scopes.back().structs[node.name] = &node; - } - }; - // Compile a single function and store the entry point node_ref // in local_context struct compile_function_visitor @@ -109,26 +70,23 @@ namespace pslang::ir node_ref apply(ast::identifier const & node) { - for (auto it = lcontext.scopes.rbegin(); it != lcontext.scopes.rend(); ++it) + if (node.variable_node) { - if (auto jt = it->variables.find(node.name); jt != it->variables.end()) - return jt->second; - - if (auto jt = it->foreign_functions.find(node.name); jt != it->foreign_functions.end()) - { - mcontext.nodes.emplace_back(extern_symbol{node.name}, node.inferred_type); - return last(); - } - - if (auto jt = it->functions.find(node.name); jt != it->functions.end()) - { - mcontext.nodes.emplace_back(address{}, node.inferred_type); - lcontext.resolve_address.emplace_back(last(), jt->second); - return last(); - } + return lcontext.variables.at(node.variable_node); } - - throw std::runtime_error("Unknown identifier \"" + node.name + "\""); + else if (node.function_node) + { + mcontext.nodes.emplace_back(address{}, node.inferred_type); + lcontext.resolve_address.emplace_back(last(), node.function_node); + return last(); + } + else if (node.foreign_function_node) + { + mcontext.nodes.emplace_back(extern_symbol{node.name}, node.inferred_type); + return last(); + } + else + throw std::runtime_error("Unknown identifier \"" + node.name + "\""); } node_ref apply(ast::unary_operation const & node) @@ -188,17 +146,11 @@ namespace pslang::ir for (auto const & argument : node.arguments) arguments.push_back(apply(*argument)); - if (auto identifier = std::get_if(node.function.get())) + if (auto identifier = std::get_if(node.function.get()); identifier && identifier->function_node) { - for (auto it = lcontext.scopes.rbegin(); it != lcontext.scopes.rend(); ++it) - { - if (auto jt = it->functions.find(identifier->name); jt != it->functions.end()) - { - mcontext.nodes.emplace_back(call{{}, std::move(arguments)}, node.inferred_type); - lcontext.resolve_call.emplace_back(last(), jt->second); - return last(); - } - } + mcontext.nodes.emplace_back(call{{}, std::move(arguments)}, node.inferred_type); + lcontext.resolve_call.emplace_back(last(), identifier->function_node); + return last(); } auto function = apply(*node.function); @@ -240,7 +192,7 @@ namespace pslang::ir mcontext.nodes.emplace_back(copy{result}); result = last(); } - lcontext.scopes.back().variables[node.name] = result; + lcontext.variables[&node] = result; return result; } @@ -320,13 +272,6 @@ namespace pslang::ir // Statement list - void apply(ast::statement_list const & list) - { - populate_symbols_visitor{{}, lcontext}.apply(list); - for (auto const & statement : list.statements) - apply(*statement); - } - void do_apply(ast::function_definition const & node) { auto before = last(); @@ -335,7 +280,7 @@ namespace pslang::ir for (std::size_t i = 0; i < node.arguments.size(); ++i) { mcontext.nodes.emplace_back(argument{i}, ast::get_type(*node.arguments[i].type)); - lcontext.scopes.back().variables[node.arguments[i].name] = last(); + lcontext.variables[&node.arguments[i]] = last(); } apply(*node.statements); @@ -407,13 +352,6 @@ namespace pslang::ir void apply(ast::return_statement const &) {} void apply(ast::struct_definition const &) {} - - void apply(ast::statement_list const & list) - { - populate_symbols_visitor{{}, lcontext}.apply(list); - for (auto const & statement : list.statements) - apply(*statement); - } }; } @@ -422,15 +360,15 @@ namespace pslang::ir { // Add a fake AST node for the entry point auto root = std::make_shared(ast::function_definition{ - { - {}, - {}, - std::make_shared(types::unit_type{}), - {}, - }, - statements, + { {}, - }); + {}, + std::make_shared(types::unit_type{}), + {}, + }, + statements, + {}, + }); mcontext.nodes.emplace_back(nop{}); auto extra_nop = std::prev(mcontext.nodes.end()); @@ -445,8 +383,8 @@ namespace pslang::ir for (auto const & resolve : lcontext.resolve_call) std::get(resolve.call->instruction).target = lcontext.functions.at(resolve.target); - for (auto const & symbol : lcontext.scopes.front().functions) - mcontext.symbols[symbol.second] = lcontext.functions.at(symbol.second); + for (auto const & symbol : lcontext.functions) + mcontext.symbols[symbol.first] = symbol.second; mcontext.entry_point = lcontext.functions.at(std::get_if(root.get())); }