diff --git a/src/language/PugsParser.cpp b/src/language/PugsParser.cpp index 427e084e87ae89de498558fff98b7c246b1d4a68..0294206b792d18f6c244fe05cad2d3447899a009 100644 --- a/src/language/PugsParser.cpp +++ b/src/language/PugsParser.cpp @@ -14,6 +14,7 @@ #include <language/ast/ASTSymbolInitializationChecker.hpp> #include <language/ast/ASTSymbolTableBuilder.hpp> #include <language/utils/ASTDotPrinter.hpp> +#include <language/utils/ASTExecutionInfo.hpp> #include <language/utils/ASTPrinter.hpp> #include <language/utils/SymbolTable.hpp> #include <utils/PugsAssert.hpp> @@ -32,8 +33,6 @@ #include <unordered_map> #include <variant> -const std::unique_ptr<ASTNode>* p_root_node = nullptr; - void parser(const std::string& filename) { @@ -50,7 +49,6 @@ parser(const std::string& filename) auto parse_and_execute = [](auto& input) { std::unique_ptr<ASTNode> root_node = ASTBuilder::build(input); - p_root_node = &root_node; ASTModulesImporter{*root_node}; ASTNodeTypeCleaner<language::import_instruction>{*root_node}; @@ -77,11 +75,12 @@ parser(const std::string& filename) std::cout << "-------------------------------------------------------\n"; std::cout << rang::style::bold << "Executing AST..." << rang::style::reset << '\n'; + ASTExecutionInfo execution_info{*root_node}; + ExecutionPolicy exec_all; root_node->execute(exec_all); root_node->m_symbol_table->clearValues(); - p_root_node = nullptr; }; if (not SignalManager::pauseOnError()) { diff --git a/src/language/modules/UtilsModule.cpp b/src/language/modules/UtilsModule.cpp index 8c688e20768b5499549f88334deab4f2ac85a7a9..90845af9ad04d0d421af3a30b07325231c6384f1 100644 --- a/src/language/modules/UtilsModule.cpp +++ b/src/language/modules/UtilsModule.cpp @@ -1,13 +1,12 @@ #include <language/modules/UtilsModule.hpp> #include <language/utils/ASTDotPrinter.hpp> +#include <language/utils/ASTExecutionInfo.hpp> #include <language/utils/ASTPrinter.hpp> #include <language/utils/BuiltinFunctionEmbedder.hpp> #include <language/utils/SymbolTable.hpp> #include <utils/PugsUtils.hpp> -extern const std::unique_ptr<ASTNode>* p_root_node; - UtilsModule::UtilsModule() { this->_addBuiltinFunction("getPugsVersion", std::make_shared<BuiltinFunctionEmbedder<std::string(void)>>( @@ -25,11 +24,10 @@ UtilsModule::UtilsModule() this->_addBuiltinFunction("getAST", std::make_shared<BuiltinFunctionEmbedder<std::string(void)>>( []() -> std::string { - Assert(p_root_node != nullptr, "unable to find AST's root node"); + const auto& root_node = ASTExecutionInfo::current().rootNode(); - const auto& root_node = *p_root_node; std::ostringstream os; - os << ASTPrinter{*root_node}; + os << ASTPrinter{root_node}; return os.str(); } @@ -39,9 +37,7 @@ UtilsModule::UtilsModule() this->_addBuiltinFunction("saveASTDot", std::make_shared<BuiltinFunctionEmbedder<void(const std::string&)>>( [](const std::string& dot_filename) -> void { - Assert(p_root_node != nullptr, "unable to find AST's root node"); - - const auto& root_node = *p_root_node; + const auto& root_node = ASTExecutionInfo::current().rootNode(); std::ofstream fout(dot_filename); @@ -51,7 +47,7 @@ UtilsModule::UtilsModule() throw NormalError(os.str()); } - ASTDotPrinter dot_printer{*root_node}; + ASTDotPrinter dot_printer{root_node}; fout << dot_printer; if (not fout) { diff --git a/src/language/utils/ASTExecutionInfo.cpp b/src/language/utils/ASTExecutionInfo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c0327d5012ed1d1e56412b97852615e8a6d6e5e4 --- /dev/null +++ b/src/language/utils/ASTExecutionInfo.cpp @@ -0,0 +1,24 @@ +#include <language/utils/ASTExecutionInfo.hpp> + +#include <language/ast/ASTNode.hpp> + +const ASTExecutionInfo* ASTExecutionInfo::m_current_execution_info = nullptr; + +ASTExecutionInfo::ASTExecutionInfo(const ASTNode& root_node) : m_root_node(root_node) +{ + Assert(m_current_execution_info == nullptr, "Can only define one ASTExecutionInfo"); + + m_current_execution_info = this; +} + +const ASTExecutionInfo& +ASTExecutionInfo::current() +{ + Assert(m_current_execution_info != nullptr, "ASTExecutionInfo is not defined!"); + return *m_current_execution_info; +} + +ASTExecutionInfo::~ASTExecutionInfo() +{ + m_current_execution_info = nullptr; +} diff --git a/src/language/utils/ASTExecutionInfo.hpp b/src/language/utils/ASTExecutionInfo.hpp new file mode 100644 index 0000000000000000000000000000000000000000..90baa8a6fbec82fa2c76a4999b7351e1d38f319e --- /dev/null +++ b/src/language/utils/ASTExecutionInfo.hpp @@ -0,0 +1,33 @@ +#ifndef AST_EXECUTION_INFO_HPP +#define AST_EXECUTION_INFO_HPP + +#include <string> + +class ASTNode; +class ASTExecutionInfo +{ + private: + static const ASTExecutionInfo* m_current_execution_info; + + const ASTNode& m_root_node; + + // The only place where the ASTExecutionInfo can be built + friend void parser(const std::string& filename); + + ASTExecutionInfo(const ASTNode& root_node); + + public: + const ASTNode& + rootNode() const + { + return m_root_node; + } + + static const ASTExecutionInfo& current(); + + ASTExecutionInfo() = delete; + + ~ASTExecutionInfo(); +}; + +#endif // AST_EXECUTION_INFO_HPP diff --git a/src/language/utils/CMakeLists.txt b/src/language/utils/CMakeLists.txt index 6a8216a9ca62a440c7eb84111cbb87d26ae6b1d3..1cb991d6c6d19a18579d3c0802a6ea032891d5c2 100644 --- a/src/language/utils/CMakeLists.txt +++ b/src/language/utils/CMakeLists.txt @@ -2,6 +2,7 @@ add_library(PugsLanguageUtils ASTDotPrinter.cpp + ASTExecutionInfo.cpp ASTPrinter.cpp DataVariant.cpp EmbeddedData.cpp