diff --git a/lib/include/pl/core/parser.hpp b/lib/include/pl/core/parser.hpp index 37132d5d..978b8d30 100644 --- a/lib/include/pl/core/parser.hpp +++ b/lib/include/pl/core/parser.hpp @@ -44,8 +44,6 @@ namespace pl::core { return this->m_globalDocComments; } - ast::ASTNodeTypeDecl* addBuiltinType(const std::string &name, api::FunctionParameterCount parameterCount, const api::TypeCallback &func); - void setParserManager(ParserManager* parserManager) { this->m_parserManager = parserManager; } @@ -55,7 +53,7 @@ namespace pl::core { TokenIter m_startToken, m_originalPosition, m_partOriginalPosition; std::vector> m_currTemplateType; - std::map> m_builtinTypes, m_types; + std::map> m_types; std::vector m_matchedOptionals; std::vector> m_currNamespace; diff --git a/lib/include/pl/core/parser_manager.hpp b/lib/include/pl/core/parser_manager.hpp index 45acba3b..e588f1a2 100644 --- a/lib/include/pl/core/parser_manager.hpp +++ b/lib/include/pl/core/parser_manager.hpp @@ -50,8 +50,15 @@ namespace pl::core { std::set & getOnceIncluded() { return m_onceIncluded; } std::set & getPreprocessorOnceIncluded() { return m_preprocessorOnceIncluded; } void setPreprocessorOnceIncluded(const std::set& onceIncluded) { m_preprocessorOnceIncluded = onceIncluded; } + + ast::ASTNodeTypeDecl* addBuiltinType(const std::string &name, api::FunctionParameterCount parameterCount, const api::TypeCallback &func); + const std::map>& getBuiltinTypes() const { + return m_builtinTypes; + } + private: - std::map>> m_parsedTypes {}; + std::map>> m_parsedTypes; + std::map> m_builtinTypes; std::set m_onceIncluded {}; std::set m_preprocessorOnceIncluded {}; api::Resolver m_resolver = nullptr; diff --git a/lib/source/pl/core/parser.cpp b/lib/source/pl/core/parser.cpp index f4dc6b92..f4d4ca76 100644 --- a/lib/source/pl/core/parser.cpp +++ b/lib/source/pl/core/parser.cpp @@ -2785,25 +2785,6 @@ namespace pl::core { return std::nullopt; } - ast::ASTNodeTypeDecl* Parser::addBuiltinType(const std::string &name, api::FunctionParameterCount parameterCount, const api::TypeCallback &func) { - auto type = this->m_builtinTypes.emplace(name, - hlp::safe_shared_ptr( - new ast::ASTNodeTypeDecl(name, std::make_shared(parameterCount, func)) - ) - ).first->second.get(); - - if (parameterCount.min != parameterCount.max) - throw std::runtime_error("Types cannot have a variable amount of parameters"); - - std::vector> templateParameters; - for (u32 i = 0; i < parameterCount.max; i += 1) { - templateParameters.emplace_back(std::make_shared(fmt::format("$param{}$", i), nullptr)); - } - type->setTemplateParameters(std::move(templateParameters)); - - return type; - } - // <(parseNamespace)...> EndOfProgram hlp::CompileResult>> Parser::parse(std::vector &tokens) { @@ -2820,7 +2801,7 @@ namespace pl::core { if (!this->m_aliasNamespace.empty()) this->m_currNamespace.push_back(this->m_aliasNamespace); - for (const auto &[name, type] : m_builtinTypes) + for (const auto &[name, type] : m_parserManager->getBuiltinTypes()) this->m_types.emplace(name, type); try { diff --git a/lib/source/pl/core/parser_manager.cpp b/lib/source/pl/core/parser_manager.cpp index 9b2c2ed0..48f6bca0 100644 --- a/lib/source/pl/core/parser_manager.cpp +++ b/lib/source/pl/core/parser_manager.cpp @@ -4,72 +4,95 @@ #include #include #include +#include #include -using namespace pl::core; +namespace pl::core { -using Result = pl::hlp::CompileResult; -Result ParserManager::parse(api::Source *source, const std::string &namespacePrefix) { - OnceIncludePair key = { source, namespacePrefix }; + using Result = hlp::CompileResult; + Result ParserManager::parse(api::Source *source, const std::string &namespacePrefix) { + OnceIncludePair key = { source, namespacePrefix }; - if (m_onceIncluded.contains(key)) { - const auto& types = m_parsedTypes[key]; - return Result::good({ {}, types }); // Even if types is empty we still need to return now - } + if (m_onceIncluded.contains(key)) { + const auto& types = m_parsedTypes[key]; + return Result::good({ {}, types }); // Even if types is empty we still need to return now + } - Parser parser; + Parser parser; - std::vector namespaces; - if (!namespacePrefix.empty()) { - namespaces = wolv::util::splitString(namespacePrefix, "::"); - } + std::vector namespaces; + if (!namespacePrefix.empty()) { + namespaces = wolv::util::splitString(namespacePrefix, "::"); + } - const auto &internals = m_patternLanguage->getInternals(); - auto oldPreprocessor = internals.preprocessor.get(); + const auto &internals = m_patternLanguage->getInternals(); + auto oldPreprocessor = internals.preprocessor.get(); - Preprocessor preprocessor; - preprocessor.setResolver(m_resolver); + Preprocessor preprocessor; + preprocessor.setResolver(m_resolver); - for (const auto& [name, value] : m_patternLanguage->getDefines()) { - preprocessor.addDefine(name, value); - } - for (const auto& [name, handler]: m_patternLanguage->getPragmas()) { - preprocessor.addPragmaHandler(name, handler); - } + for (const auto& [name, value] : m_patternLanguage->getDefines()) { + preprocessor.addDefine(name, value); + } + for (const auto& [name, handler]: m_patternLanguage->getPragmas()) { + preprocessor.addPragmaHandler(name, handler); + } - const auto &validator = internals.validator; + const auto &validator = internals.validator; - auto [tokens, preprocessorErrors] = preprocessor.preprocess(this->m_patternLanguage, source, true); - if (!preprocessorErrors.empty()) { - return Result::err(preprocessorErrors); - } + auto [tokens, preprocessorErrors] = preprocessor.preprocess(this->m_patternLanguage, source, true); + if (!preprocessorErrors.empty()) { + return Result::err(preprocessorErrors); + } + + if (preprocessor.shouldOnlyIncludeOnce()) + m_onceIncluded.insert( { source, namespacePrefix } ); - if (preprocessor.shouldOnlyIncludeOnce()) - m_onceIncluded.insert( { source, namespacePrefix } ); + parser.m_parserManager = this; + parser.m_aliasNamespace = namespaces; + parser.m_aliasNamespaceString = namespacePrefix; - parser.m_parserManager = this; - parser.m_aliasNamespace = namespaces; - parser.m_aliasNamespaceString = namespacePrefix; + auto result = parser.parse(tokens.value()); + oldPreprocessor->appendToNamespaces(tokens.value()); - auto result = parser.parse(tokens.value()); - oldPreprocessor->appendToNamespaces(tokens.value()); + if (result.hasErrs()) + return Result::err(result.errs); - if (result.hasErrs()) - return Result::err(result.errs); + auto [validated, validatorErrors] = validator->validate(result.ok.value()); + if (validated && !validatorErrors.empty()) { + return Result::err(validatorErrors); + } - auto [validated, validatorErrors] = validator->validate(result.ok.value()); - if (validated && !validatorErrors.empty()) { - return Result::err(validatorErrors); + // 'Uncomplete' all types + const auto &types = parser.m_types; + for (auto &[name, type] : types) { + type->setCompleted(false); + } + + m_parsedTypes[key] = types; + + return Result::good({ result.unwrap(), types }); } - // 'Uncomplete' all types - const auto &types = parser.m_types; - for (auto &[name, type] : types) { - type->setCompleted(false); + ast::ASTNodeTypeDecl* ParserManager::addBuiltinType(const std::string &name, api::FunctionParameterCount parameterCount, const api::TypeCallback &func) { + auto type = this->m_builtinTypes.emplace(name, + hlp::safe_shared_ptr( + new ast::ASTNodeTypeDecl(name, std::make_shared(parameterCount, func)) + ) + ).first->second.get(); + + if (parameterCount.min != parameterCount.max) + throw std::runtime_error("Types cannot have a variable amount of parameters"); + + std::vector> templateParameters; + for (u32 i = 0; i < parameterCount.max; i += 1) { + templateParameters.emplace_back(std::make_shared(fmt::format("$param{}$", i), nullptr)); + } + type->setTemplateParameters(std::move(templateParameters)); + + return type; } - m_parsedTypes[key] = types; +} - return Result::good({ result.unwrap(), types }); -} \ No newline at end of file diff --git a/lib/source/pl/pattern_language.cpp b/lib/source/pl/pattern_language.cpp index 7d2f99e6..9ce87a16 100644 --- a/lib/source/pl/pattern_language.cpp +++ b/lib/source/pl/pattern_language.cpp @@ -494,7 +494,7 @@ namespace pl { } void PatternLanguage::addType(const api::Namespace &ns, const std::string &name, api::FunctionParameterCount parameterCount, const api::TypeCallback &func) { - this->m_internals.parser->addBuiltinType(getFunctionName(ns, name), parameterCount, func); + this->m_parserManager.addBuiltinType(getFunctionName(ns, name), parameterCount, func); } void PatternLanguage::flattenPatterns() {