diff --git a/libs/ir/include/pslang/ir/compiler.hpp b/libs/ir/include/pslang/ir/compiler.hpp index 35b3d0a..2eb98b6 100644 --- a/libs/ir/include/pslang/ir/compiler.hpp +++ b/libs/ir/include/pslang/ir/compiler.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include @@ -17,7 +17,7 @@ namespace pslang::ir struct module_context { - node_list nodes; + node_list_ptr nodes; std::unordered_map labels; diff --git a/libs/ir/include/pslang/ir/node_fwd.hpp b/libs/ir/include/pslang/ir/node_fwd.hpp index cfa9788..d2e919f 100644 --- a/libs/ir/include/pslang/ir/node_fwd.hpp +++ b/libs/ir/include/pslang/ir/node_fwd.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include namespace pslang::ir { @@ -8,5 +9,6 @@ namespace pslang::ir struct node; using node_list = std::list; using node_ref = node_list::iterator; + using node_list_ptr = std::shared_ptr; -} \ No newline at end of file +} diff --git a/libs/ir/source/compiler.cpp b/libs/ir/source/compiler.cpp index 999fdda..5cd3572 100644 --- a/libs/ir/source/compiler.cpp +++ b/libs/ir/source/compiler.cpp @@ -63,7 +63,7 @@ namespace pslang::ir template node_ref apply(ast::primitive_literal_base const & node) { - mcontext.nodes.emplace_back(literal{node}, ast::get_type(node)); + mcontext.nodes->emplace_back(literal{node}, ast::get_type(node)); return last(); } @@ -75,13 +75,13 @@ namespace pslang::ir } else if (node.function_node) { - mcontext.nodes.emplace_back(instruction_address{}, node.inferred_type); + mcontext.nodes->emplace_back(instruction_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); + mcontext.nodes->emplace_back(extern_symbol{node.name}, node.inferred_type); return last(); } else @@ -94,11 +94,11 @@ namespace pslang::ir if (node.type == ast::unary_operation_type::dereference) { - mcontext.nodes.emplace_back(load{arg1}, node.inferred_type); + mcontext.nodes->emplace_back(load{arg1}, node.inferred_type); return last(); } - mcontext.nodes.emplace_back(unary_operation{node.type, arg1}, node.inferred_type); + mcontext.nodes->emplace_back(unary_operation{node.type, arg1}, node.inferred_type); return last(); } @@ -108,38 +108,38 @@ namespace pslang::ir if (node.type == ast::binary_operation_type::logical_and) { - mcontext.nodes.emplace_back(jump_if_zero{arg1}); + mcontext.nodes->emplace_back(jump_if_zero{arg1}); auto jump = last(); auto arg2 = apply(*node.arg2); - mcontext.nodes.emplace_back(binary_operation{ast::binary_operation_type::binary_and, arg1, arg2}, node.inferred_type); - mcontext.nodes.emplace_back(assignment{arg1, last()}); - mcontext.nodes.emplace_back(nop{}); + mcontext.nodes->emplace_back(binary_operation{ast::binary_operation_type::binary_and, arg1, arg2}, node.inferred_type); + mcontext.nodes->emplace_back(assignment{arg1, last()}); + mcontext.nodes->emplace_back(nop{}); std::get(jump->instruction).target = last(); return arg1; } if (node.type == ast::binary_operation_type::logical_or) { - mcontext.nodes.emplace_back(unary_operation{ast::unary_operation_type::logical_not, arg1}, node.inferred_type); - mcontext.nodes.emplace_back(jump_if_zero{last()}); + mcontext.nodes->emplace_back(unary_operation{ast::unary_operation_type::logical_not, arg1}, node.inferred_type); + mcontext.nodes->emplace_back(jump_if_zero{last()}); auto jump = last(); auto arg2 = apply(*node.arg2); - mcontext.nodes.emplace_back(binary_operation{ast::binary_operation_type::binary_or, arg1, arg2}, node.inferred_type); - mcontext.nodes.emplace_back(assignment{arg1, last()}); - mcontext.nodes.emplace_back(nop{}); + mcontext.nodes->emplace_back(binary_operation{ast::binary_operation_type::binary_or, arg1, arg2}, node.inferred_type); + mcontext.nodes->emplace_back(assignment{arg1, last()}); + mcontext.nodes->emplace_back(nop{}); std::get(jump->instruction).target = last(); return arg1; } auto arg2 = apply(*node.arg2); - mcontext.nodes.emplace_back(binary_operation{node.type, arg1, arg2}, node.inferred_type); + mcontext.nodes->emplace_back(binary_operation{node.type, arg1, arg2}, node.inferred_type); return last(); } node_ref apply(ast::cast_operation const & node) { auto arg = apply(*node.expression); - mcontext.nodes.emplace_back(cast_operation{arg, node.inferred_type}, node.inferred_type); + mcontext.nodes->emplace_back(cast_operation{arg, node.inferred_type}, node.inferred_type); return last(); } @@ -154,13 +154,13 @@ namespace pslang::ir if (auto identifier = std::get_if(node.function.get()); identifier && identifier->function_node) { - mcontext.nodes.emplace_back(call{{}, std::move(arguments)}, node.inferred_type); + 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); - mcontext.nodes.emplace_back(call_pointer{function, std::move(arguments)}, node.inferred_type); + mcontext.nodes->emplace_back(call_pointer{function, std::move(arguments)}, node.inferred_type); return last(); } else // if (node.type) @@ -176,8 +176,8 @@ namespace pslang::ir auto array_type = ast::get_type(*node.array); if (std::get_if(array_type.get())) { - mcontext.nodes.emplace_back(binary_operation{ast::binary_operation_type::addition, array, index}, array_type); - mcontext.nodes.emplace_back(load{last()}, node.inferred_type); + mcontext.nodes->emplace_back(binary_operation{ast::binary_operation_type::addition, array, index}, array_type); + mcontext.nodes->emplace_back(load{last()}, node.inferred_type); return last(); } throw std::runtime_error("Unknown array access left-hand side"); @@ -199,7 +199,7 @@ namespace pslang::ir if (std::holds_alternative(*node.lhs)) { auto lhs = apply(*node.lhs); - mcontext.nodes.emplace_back(assignment{lhs, rhs}, ast::get_type(*node.rhs)); + mcontext.nodes->emplace_back(assignment{lhs, rhs}, ast::get_type(*node.rhs)); return last(); } @@ -210,8 +210,8 @@ namespace pslang::ir { auto base_ptr = apply(*array_access->array); auto index = apply(*array_access->index); - mcontext.nodes.emplace_back(binary_operation{ast::binary_operation_type::addition, base_ptr, index}, array_type); - mcontext.nodes.emplace_back(store{last(), rhs}, ast::get_type(*node.rhs)); + mcontext.nodes->emplace_back(binary_operation{ast::binary_operation_type::addition, base_ptr, index}, array_type); + mcontext.nodes->emplace_back(store{last(), rhs}, ast::get_type(*node.rhs)); return last(); } } @@ -221,7 +221,7 @@ namespace pslang::ir if (unary_operation->type == ast::unary_operation_type::dereference) { auto lhs = apply(*unary_operation->arg1); - mcontext.nodes.emplace_back(store{lhs, rhs}, ast::get_type(*node.rhs)); + mcontext.nodes->emplace_back(store{lhs, rhs}, ast::get_type(*node.rhs)); return last(); } } @@ -238,7 +238,7 @@ namespace pslang::ir // Evaluating variable initializer didn't produce any nodes // It must have been just a reference to another variable or smth like that // Introduce a copy node to prevent accidental variable coalescing - mcontext.nodes.emplace_back(copy{result}); + mcontext.nodes->emplace_back(copy{result}); result = last(); } lcontext.variables[&node] = result; @@ -255,7 +255,7 @@ namespace pslang::ir if (block.condition) { auto condition = apply(*block.condition); - mcontext.nodes.emplace_back(jump_if_zero{condition, {}}); + mcontext.nodes->emplace_back(jump_if_zero{condition, {}}); jump_to_next = last(); } @@ -263,10 +263,10 @@ namespace pslang::ir apply(*block.statements); lcontext.scopes.pop_back(); - mcontext.nodes.emplace_back(jump{}); + mcontext.nodes->emplace_back(jump{}); jumps_to_end.push_back(last()); - mcontext.nodes.emplace_back(nop{}); + mcontext.nodes->emplace_back(nop{}); if (jump_to_next) std::get((*jump_to_next)->instruction).target = last(); } @@ -282,15 +282,15 @@ namespace pslang::ir { auto before = last(); auto condition = apply(*node.condition); - mcontext.nodes.emplace_back(jump_if_zero{condition, {}}); + mcontext.nodes->emplace_back(jump_if_zero{condition, {}}); auto jump1 = last(); lcontext.scopes.emplace_back(); apply(*node.statements); lcontext.scopes.pop_back(); - mcontext.nodes.emplace_back(jump{std::next(before)}); - mcontext.nodes.emplace_back(nop{}); + mcontext.nodes->emplace_back(jump{std::next(before)}); + mcontext.nodes->emplace_back(nop{}); std::get(jump1->instruction).target = last(); return last(); } @@ -310,10 +310,10 @@ namespace pslang::ir if (node.value) { auto value = apply(*node.value); - mcontext.nodes.emplace_back(return_value{value}, value->inferred_type); + mcontext.nodes->emplace_back(return_value{value}, value->inferred_type); } else - mcontext.nodes.emplace_back(return_value{}, std::make_shared(types::unit_type{})); + mcontext.nodes->emplace_back(return_value{}, std::make_shared(types::unit_type{})); return last(); } @@ -331,13 +331,13 @@ namespace pslang::ir lcontext.scopes.emplace_back(); for (std::size_t i = 0; i < node.arguments.size(); ++i) { - mcontext.nodes.emplace_back(argument{i}, ast::get_type(*node.arguments[i].type)); + mcontext.nodes->emplace_back(argument{i}, ast::get_type(*node.arguments[i].type)); lcontext.variables[&node.arguments[i]] = last(); } apply(*node.statements); if (types::equal(*ast::get_type(*node.return_type), types::unit_type{})) - mcontext.nodes.emplace_back(return_value{}, std::make_shared(types::unit_type{})); + mcontext.nodes->emplace_back(return_value{}, std::make_shared(types::unit_type{})); lcontext.scopes.pop_back(); @@ -349,7 +349,7 @@ namespace pslang::ir private: node_ref last() { - return std::prev(mcontext.nodes.end()); + return std::prev(mcontext.nodes->end()); } }; @@ -410,6 +410,9 @@ namespace pslang::ir void compile(module_context & mcontext, ast::statement_list_ptr const & statements) { + if (!mcontext.nodes) + mcontext.nodes = std::make_shared(); + // Add a fake AST node for the entry point auto root = std::make_shared(ast::function_definition{ { @@ -422,12 +425,12 @@ namespace pslang::ir {}, }); - mcontext.nodes.emplace_back(nop{}); - auto extra_nop = std::prev(mcontext.nodes.end()); + mcontext.nodes->emplace_back(nop{}); + auto extra_nop = std::prev(mcontext.nodes->end()); local_context lcontext; compile_visitor{{}, mcontext, lcontext}.apply(*root); mcontext.labels[&(*std::next(extra_nop))] = "[entry point]"; - mcontext.nodes.erase(extra_nop); + mcontext.nodes->erase(extra_nop); for (auto const & resolve : lcontext.resolve_address) std::get(resolve.address->instruction).target = lcontext.functions.at(resolve.target); diff --git a/libs/ir/source/print.cpp b/libs/ir/source/print.cpp index 9170463..a33cd3f 100644 --- a/libs/ir/source/print.cpp +++ b/libs/ir/source/print.cpp @@ -320,7 +320,7 @@ namespace pslang::ir void print(std::ostream & out, module_context const & context) { - print_impl(out, context.nodes, &context); + print_impl(out, *context.nodes, &context); } }