pattern: Added parameter packs

This commit is contained in:
WerWolv
2022-01-30 15:18:45 +01:00
parent 111c4b71aa
commit 69bd438fe1
7 changed files with 115 additions and 38 deletions

View File

@@ -6,6 +6,13 @@ namespace hex::pl {
Evaluator *PatternCreationLimiter::s_evaluator = nullptr;
void Evaluator::createParameterPack(const std::string &name, const std::vector<Token::Literal> &values) {
this->getScope(0).parameterPack = ParameterPack {
name,
values
};
}
void Evaluator::createVariable(const std::string &name, ASTNode *type, const std::optional<Token::Literal> &value, bool outVariable) {
auto &variables = *this->getScope(0).scope;
for (auto &variable : variables) {
@@ -15,7 +22,7 @@ namespace hex::pl {
}
auto startOffset = this->dataOffset();
auto pattern = type->createPatterns(this).front();
auto pattern = type == nullptr ? nullptr : type->createPatterns(this).front();
this->dataOffset() = startOffset;
if (pattern == nullptr) {
@@ -38,7 +45,7 @@ namespace hex::pl {
else if (std::get_if<std::string>(&value.value()) != nullptr)
pattern = new PatternDataString(0, 1);
else
__builtin_unreachable();
LogConsole::abortEvaluation("cannot determine type of auto variable", type);
}
pattern->setVariableName(name);

View File

@@ -13,7 +13,10 @@ namespace hex::pl {
}
[[noreturn]] void LogConsole::abortEvaluation(const std::string &message, const ASTNode *node) {
throw EvaluateError(static_cast<const ASTNode *>(node)->getLineNumber(), message);
if (node == nullptr)
abortEvaluation(message);
else
throw EvaluateError(node->getLineNumber(), message);
}
void LogConsole::clear() {

View File

@@ -431,31 +431,37 @@ namespace hex::pl {
ASTNode *Parser::parseFunctionDefinition() {
const auto &functionName = getValue<Token::Identifier>(-2).get();
std::vector<std::pair<std::string, ASTNode *>> params;
std::optional<std::string> parameterPack;
// Parse parameter list
bool hasParams = !peek(SEPARATOR_ROUNDBRACKETCLOSE);
u32 unnamedParamCount = 0;
while (hasParams) {
auto type = parseType(true);
if (MATCHES(sequence(VALUETYPE_AUTO, SEPARATOR_DOT, SEPARATOR_DOT, SEPARATOR_DOT, IDENTIFIER))) {
parameterPack = getValue<Token::Identifier>(-1).get();
if (MATCHES(sequence(IDENTIFIER)))
params.emplace_back(getValue<Token::Identifier>(-1).get(), type);
else {
params.emplace_back(std::to_string(unnamedParamCount), type);
unnamedParamCount++;
}
if (MATCHES(sequence(SEPARATOR_COMMA)))
throwParseError("parameter pack can only appear at end of parameter list");
if (!MATCHES(sequence(SEPARATOR_COMMA))) {
if (MATCHES(sequence(SEPARATOR_ROUNDBRACKETCLOSE)))
break;
} else {
auto type = parseType(true);
if (MATCHES(sequence(IDENTIFIER)))
params.emplace_back(getValue<Token::Identifier>(-1).get(), type);
else {
params.emplace_back(std::to_string(unnamedParamCount), type);
unnamedParamCount++;
}
if (!MATCHES(sequence(SEPARATOR_COMMA))) {
break;
else
throwParseError("expected closing ')' after parameter list");
}
}
}
if (!hasParams) {
if (!MATCHES(sequence(SEPARATOR_ROUNDBRACKETCLOSE)))
throwParseError("expected closing ')' after parameter list");
}
if (!MATCHES(sequence(SEPARATOR_ROUNDBRACKETCLOSE)))
throwParseError("expected closing ')' after parameter list");
if (!MATCHES(sequence(SEPARATOR_CURLYBRACKETOPEN)))
throwParseError("expected opening '{' after function definition");
@@ -473,7 +479,7 @@ namespace hex::pl {
}
bodyCleanup.release();
return create(new ASTNodeFunctionDefinition(getNamespacePrefixedName(functionName), params, body));
return create(new ASTNodeFunctionDefinition(getNamespacePrefixedName(functionName), params, body, parameterPack));
}
ASTNode *Parser::parseFunctionVariableDecl() {