diff --git a/src/language/BuiltinModule.cpp b/src/language/BuiltinModule.cpp index 2d2b1b556642353c53b93f7f54b75d96a074643f..88967ad750e0a37dba9fdfb2f535a57410405066 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 2a076f511022c7aed15a25684865d9c7210b0b94..67adb09e1a79aa1589d12fc979ab431bd87909ec 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 e901374f5167cdaa43750890f6e31d40fe2de91e..14f349b46e2a2956eff77bd18cd5ae338b0ad3c7 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 01afaca3c8872a2ae0b8db6c2d7fac7531049a44..459a914b9bd332b4bbf9744a700fe659f5b6629d 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 0000000000000000000000000000000000000000..7edad9c355ad93668ab3fbb0bdb36436cc81978b --- /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 0000000000000000000000000000000000000000..5310e54ab979e65a9d85b71432f9993a6db9e547 --- /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 1b3fee7d3878f66ed7c5120d542c107e0b2983d7..f6b0b0d8fb667597d0400f4d7e44b978daa19edc 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 467ffdb091c4691fb449f7a6825885521c54d89d..e71a56587dc3a18f1a3d3c62471cdb43b4efe181 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 d6a735151681bacc622eeb0c38912f9a75773c17..4dbbc5b2ca0965e89cf949ceb7cd14965d2873ea 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 0000000000000000000000000000000000000000..9da24e0d42096b93998867923ac26196bd694eb4 --- /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 0000000000000000000000000000000000000000..059e686e1a7d644bab4c7406420eac165813a12b --- /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