From 45557637530e238145ba704d4450b5e52c499f56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Del=20Pino?= <stephane.delpino44@gmail.com> Date: Tue, 10 Nov 2020 11:04:29 +0100 Subject: [PATCH] Add the ASTExecutionInfo class handle cleanly execution information The purpose of this is to provide some global execution info to parts of execution. This defines a singleton that is only constructable in the `parse` function. The instance thus only leave during the execution of the script. As a first stored, the ugly `p_root_node` static pointer has been encapsulated in this container. --- src/language/PugsParser.cpp | 7 +++--- src/language/modules/UtilsModule.cpp | 14 ++++------- src/language/utils/ASTExecutionInfo.cpp | 24 ++++++++++++++++++ src/language/utils/ASTExecutionInfo.hpp | 33 +++++++++++++++++++++++++ src/language/utils/CMakeLists.txt | 1 + 5 files changed, 66 insertions(+), 13 deletions(-) create mode 100644 src/language/utils/ASTExecutionInfo.cpp create mode 100644 src/language/utils/ASTExecutionInfo.hpp diff --git a/src/language/PugsParser.cpp b/src/language/PugsParser.cpp index 427e084e8..0294206b7 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 8c688e207..90845af9a 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 000000000..c0327d501 --- /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 000000000..90baa8a6f --- /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 6a8216a9c..1cb991d6c 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 -- GitLab