From 9e1d457250304a71b129f39263ba2af79cc9fd98 Mon Sep 17 00:00:00 2001 From: Stephane Del Pino <stephane.delpino44@gmail.com> Date: Fri, 21 Feb 2020 19:09:53 +0100 Subject: [PATCH] Begin MeshModule implementation To this purpose, a type table has been added. A simple version of the import of a `mesh` type is done. It is just the beginning of the building of the machinery for these "dynamic" types (loaded on demand), variables that will be built on them and the associated functions/algorithms. --- src/language/BuiltinModule.cpp | 15 +++++- src/language/BuiltinModule.hpp | 13 +++++- src/language/CMakeLists.txt | 1 + src/language/IModule.hpp | 7 ++- src/language/MeshModule.cpp | 9 ++++ src/language/MeshModule.hpp | 22 +++++++++ src/language/ModuleRepository.cpp | 76 +++++++++++++++++++++++-------- src/language/ModuleRepository.hpp | 10 +++- src/language/SymbolTable.hpp | 29 ++++++++++-- src/language/TypeDescriptor.hpp | 22 +++++++++ src/language/TypeTable.hpp | 30 ++++++++++++ 11 files changed, 206 insertions(+), 28 deletions(-) create mode 100644 src/language/MeshModule.cpp create mode 100644 src/language/MeshModule.hpp create mode 100644 src/language/TypeDescriptor.hpp create mode 100644 src/language/TypeTable.hpp diff --git a/src/language/BuiltinModule.cpp b/src/language/BuiltinModule.cpp index 2d2b1b556..88967ad75 100644 --- a/src/language/BuiltinModule.cpp +++ b/src/language/BuiltinModule.cpp @@ -1,6 +1,7 @@ #include <BuiltinModule.hpp> #include <CFunctionEmbedder.hpp> +#include <TypeDescriptor.hpp> #include <iostream> @@ -10,7 +11,19 @@ BuiltinModule::_addFunction(const std::string& name, std::shared_ptr<ICFunctionE auto [i_function, success] = m_name_cfunction_map.insert(std::make_pair(name, c_function_embedder)); // LCOV_EXCL_START if (not success) { - std::cerr << "function " << name << " cannot be add!\n"; + std::cerr << "function " << name << " cannot be added!\n"; + std::exit(1); + } + // LCOV_EXCL_STOP +} + +void +BuiltinModule::_addTypeDescriptor(std::shared_ptr<TypeDescriptor> type_descriptor) +{ + auto [i_type, success] = m_type_descriptor_map.insert(std::make_pair(type_descriptor->name(), type_descriptor)); + // LCOV_EXCL_START + if (not success) { + std::cerr << "type '" << type_descriptor->name() << "' cannot be added!\n"; std::exit(1); } // LCOV_EXCL_STOP diff --git a/src/language/BuiltinModule.hpp b/src/language/BuiltinModule.hpp index 2a076f511..67adb09e1 100644 --- a/src/language/BuiltinModule.hpp +++ b/src/language/BuiltinModule.hpp @@ -1,18 +1,21 @@ #ifndef BUILTIN_MODULE_HPP #define BUILTIN_MODULE_HPP -#include <PugsMacros.hpp> - #include <IModule.hpp> class ICFunctionEmbedder; +class TypeDescriptor; + class BuiltinModule : public IModule { protected: NameCFunctionMap m_name_cfunction_map; + TypeDescriptorMap m_type_descriptor_map; void _addFunction(const std::string& name, std::shared_ptr<ICFunctionEmbedder> c_function_embedder); + void _addTypeDescriptor(std::shared_ptr<TypeDescriptor> type_descriptor); + public: const NameCFunctionMap& getNameCFunctionsMap() const final @@ -20,6 +23,12 @@ class BuiltinModule : public IModule return m_name_cfunction_map; } + const TypeDescriptorMap& + getTypeDescriptorMap() const final + { + return m_type_descriptor_map; + } + BuiltinModule() = default; ~BuiltinModule() = default; diff --git a/src/language/CMakeLists.txt b/src/language/CMakeLists.txt index e901374f5..14f349b46 100644 --- a/src/language/CMakeLists.txt +++ b/src/language/CMakeLists.txt @@ -33,6 +33,7 @@ add_library( ASTSymbolInitializationChecker.cpp BuiltinModule.cpp MathModule.cpp + MeshModule.cpp ModuleRepository.cpp PugsParser.cpp) diff --git a/src/language/IModule.hpp b/src/language/IModule.hpp index 01afaca3c..459a914b9 100644 --- a/src/language/IModule.hpp +++ b/src/language/IModule.hpp @@ -7,17 +7,20 @@ #include <unordered_map> class ICFunctionEmbedder; +class TypeDescriptor; class IModule { public: - using NameCFunctionMap = std::unordered_map<std::string, std::shared_ptr<ICFunctionEmbedder>>; + using NameCFunctionMap = std::unordered_map<std::string, std::shared_ptr<ICFunctionEmbedder>>; + using TypeDescriptorMap = std::unordered_map<std::string, std::shared_ptr<TypeDescriptor>>; IModule() = default; IModule(IModule&&) = default; IModule& operator=(IModule&&) = default; - virtual const NameCFunctionMap& getNameCFunctionsMap() const = 0; + virtual const NameCFunctionMap& getNameCFunctionsMap() const = 0; + virtual const TypeDescriptorMap& getTypeDescriptorMap() const = 0; virtual std::string_view name() const = 0; diff --git a/src/language/MeshModule.cpp b/src/language/MeshModule.cpp new file mode 100644 index 000000000..7edad9c35 --- /dev/null +++ b/src/language/MeshModule.cpp @@ -0,0 +1,9 @@ +#include <MeshModule.hpp> +#include <TypeDescriptor.hpp> + +#include <memory> + +MeshModule::MeshModule() +{ + this->_addTypeDescriptor(std::make_shared<TypeDescriptor>(std::string{"mesh"})); +} diff --git a/src/language/MeshModule.hpp b/src/language/MeshModule.hpp new file mode 100644 index 000000000..5310e54ab --- /dev/null +++ b/src/language/MeshModule.hpp @@ -0,0 +1,22 @@ +#ifndef MESH_MODULE_HPP +#define MESH_MODULE_HPP + +#include <PugsMacros.hpp> + +#include <BuiltinModule.hpp> + +class MeshModule : public BuiltinModule +{ + public: + std::string_view + name() const final + { + return "mesh"; + } + + MeshModule(); + + ~MeshModule() = default; +}; + +#endif // MESH_MODULE_HPP diff --git a/src/language/ModuleRepository.cpp b/src/language/ModuleRepository.cpp index 1b3fee7d3..f6b0b0d8f 100644 --- a/src/language/ModuleRepository.cpp +++ b/src/language/ModuleRepository.cpp @@ -4,10 +4,11 @@ #include <ASTNode.hpp> +#include <CFunctionEmbedder.hpp> #include <SymbolTable.hpp> -#include <CFunctionEmbedder.hpp> #include <MathModule.hpp> +#include <MeshModule.hpp> void ModuleRepository::_subscribe(std::unique_ptr<IModule> m) @@ -19,35 +20,72 @@ ModuleRepository::_subscribe(std::unique_ptr<IModule> m) ModuleRepository::ModuleRepository() { this->_subscribe(std::make_unique<MathModule>()); + this->_subscribe(std::make_unique<MeshModule>()); } void -ModuleRepository::populateSymbolTable(const ASTNode& module_name_node, SymbolTable& symbol_table) +ModuleRepository::_populateCFunctionsEmbedderTable(const IModule& populating_module, + const ASTNode& module_name_node, + SymbolTable& symbol_table) { - std::string module_name = module_name_node.string(); + const std::string& module_name = module_name_node.string(); - auto i_module = m_module_set.find(module_name); - if (i_module != m_module_set.end()) { - CFunctionEmbedderTable& c_function_embedder_table = symbol_table.cFunctionEbedderTable(); + CFunctionEmbedderTable& c_function_embedder_table = symbol_table.cFunctionEbedderTable(); + + for (auto [symbol_name, c_function] : populating_module.getNameCFunctionsMap()) { + auto [i_symbol, success] = symbol_table.add(symbol_name, module_name_node.begin()); - const IModule& m = *i_module->second; + if (not success) { + std::ostringstream error_message; + error_message << "importing module '" << module_name << "', cannot add symbol '" << symbol_name + << "', it is already defined!"; + throw parse_error(error_message.str(), module_name_node.begin()); + } + + i_symbol->attributes().setDataType(ASTNodeDataType::c_function_t); + i_symbol->attributes().setIsInitialized(); + i_symbol->attributes().value() = c_function_embedder_table.size(); + + c_function_embedder_table.add(c_function); + } +} - for (auto [symbol_name, c_function] : m.getNameCFunctionsMap()) { - auto [i_symbol, success] = symbol_table.add(symbol_name, module_name_node.begin()); +void +ModuleRepository::_populateTypeDescriptor(const IModule& populating_module, + const ASTNode& module_name_node, + SymbolTable& symbol_table) +{ + const std::string& module_name = module_name_node.string(); - if (not success) { - std::ostringstream error_message; - error_message << "importing module '" << module_name << "', cannot add symbol '" << symbol_name - << "', it is already defined!"; - throw parse_error(error_message.str(), module_name_node.begin()); - } + TypeTable& type_table = symbol_table.typeTable(); - i_symbol->attributes().setDataType(ASTNodeDataType::c_function_t); - i_symbol->attributes().setIsInitialized(); - i_symbol->attributes().value() = c_function_embedder_table.size(); + for (auto [symbol_name, type_descriptor] : populating_module.getTypeDescriptorMap()) { + auto [i_symbol, success] = symbol_table.add(symbol_name, module_name_node.begin()); - c_function_embedder_table.add(c_function); + if (not success) { + std::ostringstream error_message; + error_message << "importing module '" << module_name << "', cannot add symbol '" << symbol_name + << "', it is already defined!"; + throw parse_error(error_message.str(), module_name_node.begin()); } + + i_symbol->attributes().setDataType(ASTNodeDataType::type_id_t); + i_symbol->attributes().setIsInitialized(); + i_symbol->attributes().value() = type_table.size(); + + type_table.add(type_descriptor); + } +} + +void +ModuleRepository::populateSymbolTable(const ASTNode& module_name_node, SymbolTable& symbol_table) +{ + const std::string& module_name = module_name_node.string(); + + auto i_module = m_module_set.find(module_name); + if (i_module != m_module_set.end()) { + this->_populateCFunctionsEmbedderTable(*i_module->second, module_name_node, symbol_table); + this->_populateTypeDescriptor(*i_module->second, module_name_node, symbol_table); } else { throw parse_error(std::string{"could not find module "} + module_name, std::vector{module_name_node.begin()}); } diff --git a/src/language/ModuleRepository.hpp b/src/language/ModuleRepository.hpp index 467ffdb09..e71a56587 100644 --- a/src/language/ModuleRepository.hpp +++ b/src/language/ModuleRepository.hpp @@ -17,8 +17,16 @@ class ModuleRepository void _subscribe(std::unique_ptr<IModule> a); + void _populateCFunctionsEmbedderTable(const IModule& populating_module, + const ASTNode& module_name_node, + SymbolTable& symbol_table); + + void _populateTypeDescriptor(const IModule& populating_module, + const ASTNode& module_name_node, + SymbolTable& symbol_table); + public: - void populateSymbolTable(const ASTNode& node_module_name, SymbolTable& symbol_table); + void populateSymbolTable(const ASTNode& module_name_node, SymbolTable& symbol_table); const ModuleRepository& operator=(const ModuleRepository&) = delete; const ModuleRepository& operator=(ModuleRepository&&) = delete; diff --git a/src/language/SymbolTable.hpp b/src/language/SymbolTable.hpp index d6a735151..4dbbc5b2c 100644 --- a/src/language/SymbolTable.hpp +++ b/src/language/SymbolTable.hpp @@ -13,6 +13,8 @@ #include <CFunctionEmbedderTable.hpp> #include <FunctionTable.hpp> +#include <TypeTable.hpp> + class SymbolTable { public: @@ -87,6 +89,8 @@ class SymbolTable { if (attributes.m_data_type == ASTNodeDataType::function_t) { os << "function_id:"; + } else if (attributes.m_data_type == ASTNodeDataType::type_id_t) { + os << "type_id:"; } std::visit( [&](const auto& value) { @@ -196,6 +200,8 @@ class SymbolTable std::shared_ptr<FunctionTable> m_function_table; std::shared_ptr<CFunctionEmbedderTable> m_c_function_embedder_table; + std::shared_ptr<TypeTable> m_type_table; + public: bool hasContext() const @@ -238,6 +244,20 @@ class SymbolTable return *m_c_function_embedder_table; } + TypeTable& + typeTable() + { + Assert(m_type_table); + return *m_type_table; + } + + const TypeTable& + typeTable() const + { + Assert(m_type_table); + return *m_type_table; + } + friend std::ostream& operator<<(std::ostream& os, const SymbolTable& symbol_table) { @@ -299,7 +319,8 @@ class SymbolTable : m_parent_table{parent_table}, m_context{context}, m_function_table{parent_table->m_function_table}, - m_c_function_embedder_table{parent_table->m_c_function_embedder_table} + m_c_function_embedder_table{parent_table->m_c_function_embedder_table}, + m_type_table{parent_table->m_type_table} { ; } @@ -308,7 +329,8 @@ class SymbolTable : m_parent_table{parent_table}, m_context{parent_table->m_context}, m_function_table{parent_table->m_function_table}, - m_c_function_embedder_table{parent_table->m_c_function_embedder_table} + m_c_function_embedder_table{parent_table->m_c_function_embedder_table}, + m_type_table{parent_table->m_type_table} { ; } @@ -317,7 +339,8 @@ class SymbolTable : m_parent_table{nullptr}, m_context{nullptr}, m_function_table{std::make_shared<FunctionTable>()}, - m_c_function_embedder_table{std::make_shared<CFunctionEmbedderTable>()} + m_c_function_embedder_table{std::make_shared<CFunctionEmbedderTable>()}, + m_type_table{std::make_shared<TypeTable>()} { ; } diff --git a/src/language/TypeDescriptor.hpp b/src/language/TypeDescriptor.hpp new file mode 100644 index 000000000..9da24e0d4 --- /dev/null +++ b/src/language/TypeDescriptor.hpp @@ -0,0 +1,22 @@ +#ifndef TYPE_DESCRIPTOR_HPP +#define TYPE_DESCRIPTOR_HPP + +#include <string> + +class TypeDescriptor +{ + private: + std::string m_name; + + public: + const std::string& + name() const + { + return m_name; + } + + TypeDescriptor(std::string_view name) : m_name(name) {} + ~TypeDescriptor() = default; +}; + +#endif // TYPE_DESCRIPTOR_HPP diff --git a/src/language/TypeTable.hpp b/src/language/TypeTable.hpp new file mode 100644 index 000000000..059e686e1 --- /dev/null +++ b/src/language/TypeTable.hpp @@ -0,0 +1,30 @@ +#ifndef TYPE_TABLE_HPP +#define TYPE_TABLE_HPP + +#include <TypeDescriptor.hpp> + +#include <vector> + +class TypeTable +{ + private: + std::vector<std::shared_ptr<TypeDescriptor>> m_type_list; + + public: + size_t + size() const + { + return m_type_list.size(); + } + + void + add(std::shared_ptr<TypeDescriptor> type_descriptor) + { + m_type_list.emplace_back(type_descriptor); + } + + TypeTable() = default; + ~TypeTable() = default; +}; + +#endif // TYPE_TABLE_HPP -- GitLab