Skip to content

Commit

Permalink
parser: Fixed built-in types only being accessible in main translatio…
Browse files Browse the repository at this point in the history
…n unit
  • Loading branch information
WerWolv committed Jan 16, 2025
1 parent cbd3760 commit c550979
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 72 deletions.
4 changes: 1 addition & 3 deletions lib/include/pl/core/parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -55,7 +53,7 @@ namespace pl::core {
TokenIter m_startToken, m_originalPosition, m_partOriginalPosition;

std::vector<hlp::safe_shared_ptr<ast::ASTNodeTypeDecl>> m_currTemplateType;
std::map<std::string, hlp::safe_shared_ptr<ast::ASTNodeTypeDecl>> m_builtinTypes, m_types;
std::map<std::string, hlp::safe_shared_ptr<ast::ASTNodeTypeDecl>> m_types;

std::vector<TokenIter> m_matchedOptionals;
std::vector<std::vector<std::string>> m_currNamespace;
Expand Down
9 changes: 8 additions & 1 deletion lib/include/pl/core/parser_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,15 @@ namespace pl::core {
std::set<OnceIncludePair> & getOnceIncluded() { return m_onceIncluded; }
std::set<OnceIncludePair> & getPreprocessorOnceIncluded() { return m_preprocessorOnceIncluded; }
void setPreprocessorOnceIncluded(const std::set<OnceIncludePair>& onceIncluded) { m_preprocessorOnceIncluded = onceIncluded; }

ast::ASTNodeTypeDecl* addBuiltinType(const std::string &name, api::FunctionParameterCount parameterCount, const api::TypeCallback &func);
const std::map<std::string, hlp::safe_shared_ptr<ast::ASTNodeTypeDecl>>& getBuiltinTypes() const {
return m_builtinTypes;
}

private:
std::map<OnceIncludePair, std::map<std::string, hlp::safe_shared_ptr<ast::ASTNodeTypeDecl>>> m_parsedTypes {};
std::map<OnceIncludePair, std::map<std::string, hlp::safe_shared_ptr<ast::ASTNodeTypeDecl>>> m_parsedTypes;
std::map<std::string, hlp::safe_shared_ptr<ast::ASTNodeTypeDecl>> m_builtinTypes;
std::set<OnceIncludePair> m_onceIncluded {};
std::set<OnceIncludePair> m_preprocessorOnceIncluded {};
api::Resolver m_resolver = nullptr;
Expand Down
21 changes: 1 addition & 20 deletions lib/source/pl/core/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<ast::ASTNodeTypeDecl>(
new ast::ASTNodeTypeDecl(name, std::make_shared<ast::ASTNodeBuiltinType>(parameterCount, func))
)
).first->second.get();

if (parameterCount.min != parameterCount.max)
throw std::runtime_error("Types cannot have a variable amount of parameters");

std::vector<std::shared_ptr<ast::ASTNode>> templateParameters;
for (u32 i = 0; i < parameterCount.max; i += 1) {
templateParameters.emplace_back(std::make_shared<ast::ASTNodeLValueAssignment>(fmt::format("$param{}$", i), nullptr));
}
type->setTemplateParameters(std::move(templateParameters));

return type;
}

// <(parseNamespace)...> EndOfProgram
hlp::CompileResult<std::vector<std::shared_ptr<ast::ASTNode>>> Parser::parse(std::vector<Token> &tokens) {

Expand All @@ -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 {
Expand Down
117 changes: 70 additions & 47 deletions lib/source/pl/core/parser_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,72 +4,95 @@
#include <pl/core/validator.hpp>
#include <pl/core/parser.hpp>
#include <pl/core/lexer.hpp>
#include <pl/core/ast/ast_node_lvalue_assignment.hpp>

#include <wolv/utils/string.hpp>

using namespace pl::core;
namespace pl::core {

using Result = pl::hlp::CompileResult<ParserManager::ParsedData>;
Result ParserManager::parse(api::Source *source, const std::string &namespacePrefix) {
OnceIncludePair key = { source, namespacePrefix };
using Result = hlp::CompileResult<ParserManager::ParsedData>;
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<std::string> namespaces;
if (!namespacePrefix.empty()) {
namespaces = wolv::util::splitString(namespacePrefix, "::");
}
std::vector<std::string> 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<ast::ASTNodeTypeDecl>(
new ast::ASTNodeTypeDecl(name, std::make_shared<ast::ASTNodeBuiltinType>(parameterCount, func))
)
).first->second.get();

if (parameterCount.min != parameterCount.max)
throw std::runtime_error("Types cannot have a variable amount of parameters");

std::vector<std::shared_ptr<ast::ASTNode>> templateParameters;
for (u32 i = 0; i < parameterCount.max; i += 1) {
templateParameters.emplace_back(std::make_shared<ast::ASTNodeLValueAssignment>(fmt::format("$param{}$", i), nullptr));
}
type->setTemplateParameters(std::move(templateParameters));

return type;
}

m_parsedTypes[key] = types;
}

return Result::good({ result.unwrap(), types });
}
2 changes: 1 addition & 1 deletion lib/source/pl/pattern_language.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down

0 comments on commit c550979

Please sign in to comment.