#ifndef BUILTIN_MODULE_HPP #define BUILTIN_MODULE_HPP #include <language/modules/IModule.hpp> #include <language/utils/ASTNodeDataType.hpp> #include <utils/Exceptions.hpp> #include <sstream> class IBuiltinFunctionEmbedder; class TypeDescriptor; class ValueDescriptor; template <typename FX, typename... Args> class BuiltinFunctionEmbedder; class BuiltinModule : public IModule { protected: NameBuiltinFunctionMap m_name_builtin_function_map; NameTypeMap m_name_type_map; NameValueMap m_name_value_map; template <typename FX, typename... Args> void _addBuiltinFunction(const std::string& name, std::function<FX(Args...)>&& f) { try { this->_addBuiltinFunction(name, std::make_shared<BuiltinFunctionEmbedder<FX(Args...)>>( std::forward<std::function<FX(Args...)>>(f))); } catch (std::invalid_argument& e) { std::ostringstream os; os << "while defining builtin function '" << rang::fgB::yellow << name << rang::fg::reset << "'\n"; os << e.what(); throw UnexpectedError(os.str()); } } private: void _addBuiltinFunction(const std::string& name, std::shared_ptr<IBuiltinFunctionEmbedder> builtin_function_embedder); protected: void _addTypeDescriptor(const ASTNodeDataType& type); void _addNameValue(const std::string& name, const ASTNodeDataType& type, const DataVariant& data); const bool m_is_mandatory; public: bool isMandatory() const final { return m_is_mandatory; } const NameBuiltinFunctionMap& getNameBuiltinFunctionMap() const final { return m_name_builtin_function_map; } const NameTypeMap& getNameTypeMap() const final { return m_name_type_map; } const NameValueMap& getNameValueMap() const final { return m_name_value_map; } BuiltinModule(bool is_mandatory = false); ~BuiltinModule() = default; }; #endif // BUILTIN_MODULE_HPP