diff --git a/src/language/ASTModulesImporter.cpp b/src/language/ASTModulesImporter.cpp index 1a164cf24d949ea9f7072eeedb26107e83b0579e..22769a727c8985bf42eb2a8d828d28c53c5252f2 100644 --- a/src/language/ASTModulesImporter.cpp +++ b/src/language/ASTModulesImporter.cpp @@ -1,23 +1,15 @@ #include <ASTModulesImporter.hpp> -#include <ASTSymbolTableBuilder.hpp> -#include <SymbolTable.hpp> - #include <PEGGrammar.hpp> -#include <CFunctionEmbedder.hpp> -#include <MathModule.hpp> - -#include <memory> - void ASTModulesImporter::_importModule(ASTNode& import_node) { Assert(import_node.is_type<language::import_instruction>()); Assert(import_node.children[0]->is_type<language::module_name>()); - ASTNode& module_name_node = *import_node.children[0]; - const std::string module_name = module_name_node.string(); + const ASTNode& module_name_node = *import_node.children[0]; + const std::string module_name = module_name_node.string(); if (auto [i_module_name, success] = m_imported_modules.insert(module_name); not success) { std::cout << " * ignoring '" << rang::fgB::green << module_name << rang::style::reset @@ -27,29 +19,7 @@ ASTModulesImporter::_importModule(ASTNode& import_node) std::cout << " * importing '" << rang::fgB::green << module_name << rang::style::reset << "' module\n"; - if (module_name == "math") { - MathModule math_module; - - CFunctionEmbedderTable& c_function_embedder_table = m_symbol_table.cFunctionEbedderTable(); - - for (auto [symbol_name, c_function] : math_module.getNameCFunctionsMap()) { - auto [i_symbol, success] = m_symbol_table.add(symbol_name, import_node.begin()); - - if (not success) { - std::ostringstream error_message; - error_message << "cannot add symbol '" << symbol_name << "' it is already defined"; - throw parse_error(error_message.str(), import_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); - } - } else { - throw parse_error(std::string{"could not find module "} + module_name, std::vector{module_name_node.begin()}); - } + m_module_repository.populateSymbolTable(module_name_node, m_symbol_table); } void diff --git a/src/language/ASTModulesImporter.hpp b/src/language/ASTModulesImporter.hpp index d548cfb59157e36b4c25199b1b9c659a799bdeb6..fb9d4897021f7c213c546b9aa079e83b206fbb9a 100644 --- a/src/language/ASTModulesImporter.hpp +++ b/src/language/ASTModulesImporter.hpp @@ -6,6 +6,8 @@ #include <set> #include <string> +#include <ModuleRepository.hpp> + class SymbolTable; class ASTModulesImporter @@ -13,6 +15,8 @@ class ASTModulesImporter std::set<std::string> m_imported_modules; SymbolTable& m_symbol_table; + ModuleRepository m_module_repository; + void _importModule(ASTNode& import_node); void _importAllModules(ASTNode& node); diff --git a/src/language/CMakeLists.txt b/src/language/CMakeLists.txt index 21510acb1af86023c555c093509fb9363c1f5868..8086dfbcae9b20581411be22699dece9ae16e21f 100644 --- a/src/language/CMakeLists.txt +++ b/src/language/CMakeLists.txt @@ -32,6 +32,7 @@ add_library( ASTSymbolTableBuilder.cpp ASTSymbolInitializationChecker.cpp MathModule.cpp + ModuleRepository.cpp PugsParser.cpp) # Additional dependencies diff --git a/src/language/IModule.hpp b/src/language/IModule.hpp new file mode 100644 index 0000000000000000000000000000000000000000..01afaca3c8872a2ae0b8db6c2d7fac7531049a44 --- /dev/null +++ b/src/language/IModule.hpp @@ -0,0 +1,27 @@ +#ifndef IMODULE_HPP +#define IMODULE_HPP + +#include <memory> +#include <string> +#include <string_view> +#include <unordered_map> + +class ICFunctionEmbedder; + +class IModule +{ + public: + using NameCFunctionMap = std::unordered_map<std::string, std::shared_ptr<ICFunctionEmbedder>>; + + IModule() = default; + IModule(IModule&&) = default; + IModule& operator=(IModule&&) = default; + + virtual const NameCFunctionMap& getNameCFunctionsMap() const = 0; + + virtual std::string_view name() const = 0; + + virtual ~IModule() = default; +}; + +#endif // IMODULE_HPP diff --git a/src/language/MathModule.hpp b/src/language/MathModule.hpp index 2d78710766036940d7dff3805ebb5d4213dcebd4..c3ca3ed0a46d8843e231d33fa270d661e191d588 100644 --- a/src/language/MathModule.hpp +++ b/src/language/MathModule.hpp @@ -1,23 +1,24 @@ -#ifndef CMATH_MODULE_HPP -#define CMATH_MODULE_HPP +#ifndef MATH_MODULE_HPP +#define MATH_MODULE_HPP -#include <PugsMacros.hpp> +#include <IModule.hpp> -#include <memory> -#include <string> -#include <unordered_map> - -class ICFunctionEmbedder; -class MathModule +class MathModule : public IModule { private: - std::unordered_map<std::string, std::shared_ptr<ICFunctionEmbedder>> m_name_cfunction_map; + NameCFunctionMap m_name_cfunction_map; void _addFunction(const std::string& name, std::shared_ptr<ICFunctionEmbedder> c_function_embedder); public: - const auto& - getNameCFunctionsMap() const + std::string_view + name() const final + { + return "math"; + } + + const NameCFunctionMap& + getNameCFunctionsMap() const final { return m_name_cfunction_map; } @@ -27,4 +28,4 @@ class MathModule ~MathModule() = default; }; -#endif // CMATH_MODULE_HPP +#endif // MATH_MODULE_HPP diff --git a/src/language/ModuleRepository.cpp b/src/language/ModuleRepository.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4eb46c0ae204e58313f94d46b54e44fb1a2a2f98 --- /dev/null +++ b/src/language/ModuleRepository.cpp @@ -0,0 +1,56 @@ +#include <ModuleRepository.hpp> + +#include <PugsAssert.hpp> + +#include <ASTNode.hpp> + +#include <SymbolTable.hpp> + +#include <CFunctionEmbedder.hpp> +#include <MathModule.hpp> + +void +ModuleRepository::_subscribe(std::unique_ptr<IModule> m) +{ + auto [i_module, success] = m_module_set.emplace(m->name(), std::move(m)); + Assert(success, "module has already been subscribed"); +} + +ModuleRepository::ModuleRepository() +{ + this->_subscribe(std::make_unique<MathModule>()); +} + +void +ModuleRepository::populateSymbolTable(const ASTNode& module_name_node, SymbolTable& symbol_table) +{ + 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(); + + const IModule& m = *i_module->second; + + for (auto [symbol_name, c_function] : m.getNameCFunctionsMap()) { + auto [i_symbol, success] = symbol_table.add(symbol_name, module_name_node.begin()); + + 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); + } + + std::cout << "populating ..."; + } 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 new file mode 100644 index 0000000000000000000000000000000000000000..467ffdb091c4691fb449f7a6825885521c54d89d --- /dev/null +++ b/src/language/ModuleRepository.hpp @@ -0,0 +1,33 @@ +#ifndef MODULE_REGISTRY_HPP +#define MODULE_REGISTRY_HPP + +#include <IModule.hpp> + +#include <map> +#include <memory> +#include <string> + +class ASTNode; +class SymbolTable; + +class ModuleRepository +{ + private: + std::map<std::string, std::unique_ptr<IModule>> m_module_set; + + void _subscribe(std::unique_ptr<IModule> a); + + public: + void populateSymbolTable(const ASTNode& node_module_name, SymbolTable& symbol_table); + + const ModuleRepository& operator=(const ModuleRepository&) = delete; + const ModuleRepository& operator=(ModuleRepository&&) = delete; + + ModuleRepository(const ModuleRepository&) = delete; + ModuleRepository(ModuleRepository&&) = delete; + + ModuleRepository(); + ~ModuleRepository() = default; +}; + +#endif // MODULE_REGISTRY_HPP