mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-03-30 21:05:56 -05:00
pattern: Added parameter packs
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user