Skip to content
Snippets Groups Projects
Commit 854a4ddb authored by Stéphane Del Pino's avatar Stéphane Del Pino
Browse files

Redesign module handling

This concerns built-in modules (external modules will not be defined anytime
soon!)

Now, modules are registered in a repository and have to follow a simple
interface to be imported.

This repository is a member of the ASTModulesImporter but may become a singleton
if needed in future.
parent f1496ad6
No related branches found
No related tags found
1 merge request!37Feature/language
#include <ASTModulesImporter.hpp> #include <ASTModulesImporter.hpp>
#include <ASTSymbolTableBuilder.hpp>
#include <SymbolTable.hpp>
#include <PEGGrammar.hpp> #include <PEGGrammar.hpp>
#include <CFunctionEmbedder.hpp>
#include <MathModule.hpp>
#include <memory>
void void
ASTModulesImporter::_importModule(ASTNode& import_node) ASTModulesImporter::_importModule(ASTNode& import_node)
{ {
Assert(import_node.is_type<language::import_instruction>()); Assert(import_node.is_type<language::import_instruction>());
Assert(import_node.children[0]->is_type<language::module_name>()); Assert(import_node.children[0]->is_type<language::module_name>());
ASTNode& module_name_node = *import_node.children[0]; const ASTNode& module_name_node = *import_node.children[0];
const std::string module_name = module_name_node.string(); const std::string module_name = module_name_node.string();
if (auto [i_module_name, success] = m_imported_modules.insert(module_name); not success) { if (auto [i_module_name, success] = m_imported_modules.insert(module_name); not success) {
...@@ -27,29 +19,7 @@ ASTModulesImporter::_importModule(ASTNode& import_node) ...@@ -27,29 +19,7 @@ ASTModulesImporter::_importModule(ASTNode& import_node)
std::cout << " * importing '" << rang::fgB::green << module_name << rang::style::reset << "' module\n"; std::cout << " * importing '" << rang::fgB::green << module_name << rang::style::reset << "' module\n";
if (module_name == "math") { m_module_repository.populateSymbolTable(module_name_node, m_symbol_table);
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()});
}
} }
void void
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
#include <set> #include <set>
#include <string> #include <string>
#include <ModuleRepository.hpp>
class SymbolTable; class SymbolTable;
class ASTModulesImporter class ASTModulesImporter
...@@ -13,6 +15,8 @@ class ASTModulesImporter ...@@ -13,6 +15,8 @@ class ASTModulesImporter
std::set<std::string> m_imported_modules; std::set<std::string> m_imported_modules;
SymbolTable& m_symbol_table; SymbolTable& m_symbol_table;
ModuleRepository m_module_repository;
void _importModule(ASTNode& import_node); void _importModule(ASTNode& import_node);
void _importAllModules(ASTNode& node); void _importAllModules(ASTNode& node);
......
...@@ -32,6 +32,7 @@ add_library( ...@@ -32,6 +32,7 @@ add_library(
ASTSymbolTableBuilder.cpp ASTSymbolTableBuilder.cpp
ASTSymbolInitializationChecker.cpp ASTSymbolInitializationChecker.cpp
MathModule.cpp MathModule.cpp
ModuleRepository.cpp
PugsParser.cpp) PugsParser.cpp)
# Additional dependencies # Additional dependencies
......
#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
#ifndef CMATH_MODULE_HPP #ifndef MATH_MODULE_HPP
#define CMATH_MODULE_HPP #define MATH_MODULE_HPP
#include <PugsMacros.hpp> #include <IModule.hpp>
#include <memory> class MathModule : public IModule
#include <string>
#include <unordered_map>
class ICFunctionEmbedder;
class MathModule
{ {
private: 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); void _addFunction(const std::string& name, std::shared_ptr<ICFunctionEmbedder> c_function_embedder);
public: public:
const auto& std::string_view
getNameCFunctionsMap() const name() const final
{
return "math";
}
const NameCFunctionMap&
getNameCFunctionsMap() const final
{ {
return m_name_cfunction_map; return m_name_cfunction_map;
} }
...@@ -27,4 +28,4 @@ class MathModule ...@@ -27,4 +28,4 @@ class MathModule
~MathModule() = default; ~MathModule() = default;
}; };
#endif // CMATH_MODULE_HPP #endif // MATH_MODULE_HPP
#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()});
}
}
#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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment