1
0
mirror of synced 2025-02-17 18:59:21 +01:00

patterns: Allow str to be used in function bodies

This commit is contained in:
WerWolv 2021-10-04 20:26:34 +02:00
parent a93049056a
commit 4b9aff5b29
5 changed files with 53 additions and 14 deletions

View File

@ -192,7 +192,7 @@ namespace hex::plugin::builtin {
auto string = Token::literalToString(params[0], false);
auto index = Token::literalToSigned(params[1]);
if (std::abs(index) >= string.length())
if (std::abs(index) > string.length())
LogConsole::abortEvaluation("character index out of range");
if (index >= 0)

View File

@ -176,6 +176,22 @@ namespace hex::pl {
LogConsole::abortEvaluation("invalid operand used in mathematical expression", this);
}
},
[this](std::string left, char right) -> ASTNode* {
switch (this->getOperator()) {
case Token::Operator::Plus:
return new ASTNodeLiteral(left + right);
default:
LogConsole::abortEvaluation("invalid operand used in mathematical expression", this);
}
},
[this](char left, std::string right) -> ASTNode* {
switch (this->getOperator()) {
case Token::Operator::Plus:
return new ASTNodeLiteral(left + right);
default:
LogConsole::abortEvaluation("invalid operand used in mathematical expression", this);
}
},
[this](auto &&left, auto &&right) -> ASTNode* {
switch (this->getOperator()) {
case Token::Operator::Plus:
@ -1359,8 +1375,8 @@ namespace hex::pl {
auto &literal = evaluator->getStack()[pattern->getOffset()];
std::visit(overloaded {
[&](std::string &assignmentValue) { },
[&](auto &&assignmentValue) { std::memcpy(&value, &assignmentValue, pattern->getSize()); }
[&](std::string &assignmentValue) { },
[&](auto &&assignmentValue) { std::memcpy(&value, &assignmentValue, pattern->getSize()); }
}, literal);
}
else
@ -1369,6 +1385,21 @@ namespace hex::pl {
value = hex::changeEndianess(value, pattern->getSize(), pattern->getEndian());
};
auto readString = [&evaluator](std::string &value, PatternData *pattern) {
if (pattern->isLocal()) {
auto &literal = evaluator->getStack()[pattern->getOffset()];
std::visit(overloaded {
[&](std::string &assignmentValue) { value = assignmentValue; },
[&](auto &&assignmentValue) { }
}, literal);
}
else {
value.resize(pattern->getSize());
evaluator->getProvider()->read(pattern->getOffset(), value.data(), value.size());
}
};
Token::Literal literal;
if (dynamic_cast<PatternDataUnsigned*>(pattern) || dynamic_cast<PatternDataEnum*>(pattern)) {
u128 value = 0;
@ -1407,7 +1438,14 @@ namespace hex::pl {
auto &literal = evaluator->getStack()[pattern->getOffset()];
std::visit(overloaded {
[&](std::string &assignmentValue) { value = assignmentValue; },
[&](char assignmentValue) { if (assignmentValue != 0x00) value = std::string({ assignmentValue }); },
[&](std::string assignmentValue) { value = assignmentValue; },
[&, this](PatternData * const &assignmentValue) {
if (!dynamic_cast<PatternDataString*>(assignmentValue) && !dynamic_cast<PatternDataCharacter*>(assignmentValue))
LogConsole::abortEvaluation(hex::format("cannot assign '{}' to string", pattern->getTypeName()), this);
readString(value, assignmentValue);
},
[&, this](auto &&assignmentValue) { LogConsole::abortEvaluation(hex::format("cannot assign '{}' to string", pattern->getTypeName()), this); }
}, literal);
}

View File

@ -220,6 +220,7 @@ namespace hex::pl {
case ValueType::Character: return "char";
case ValueType::Character16: return "char16";
case ValueType::Padding: return "padding";
case ValueType::String: return "str";
default: return "< ??? >";
}
}

View File

@ -20,19 +20,19 @@ namespace hex::pl {
if (!value.has_value())
LogConsole::abortEvaluation("cannot determine type of auto variable", type);
if (std::get_if<u128>(&*value) != nullptr)
if (std::get_if<u128>(&value.value()) != nullptr)
pattern = new PatternDataUnsigned(0, sizeof(u128), this);
else if (std::get_if<s128>(&*value) != nullptr)
else if (std::get_if<s128>(&value.value()) != nullptr)
pattern = new PatternDataSigned(0, sizeof(s128), this);
else if (std::get_if<double>(&*value) != nullptr)
else if (std::get_if<double>(&value.value()) != nullptr)
pattern = new PatternDataFloat(0, sizeof(double), this);
else if (std::get_if<bool>(&*value) != nullptr)
else if (std::get_if<bool>(&value.value()) != nullptr)
pattern = new PatternDataBoolean(0, this);
else if (std::get_if<char>(&*value) != nullptr)
else if (std::get_if<char>(&value.value()) != nullptr)
pattern = new PatternDataCharacter(0, this);
else if (std::get_if<PatternData*>(&*value) != nullptr)
pattern = std::get<PatternData*>(*value)->clone();
else if (std::get_if<std::string>(&*value) != nullptr)
else if (std::get_if<PatternData*>(&value.value()) != nullptr)
pattern = std::get<PatternData*>(value.value())->clone();
else if (std::get_if<std::string>(&value.value()) != nullptr)
pattern = new PatternDataString(0, 1, this);
else
__builtin_unreachable();

View File

@ -494,10 +494,10 @@ namespace hex::pl {
statement = parseFunctionCall();
}
else
statement = parseMemberVariable(parseType());
statement = parseMemberVariable(parseType(true));
}
else if (peek(KEYWORD_BE) || peek(KEYWORD_LE) || peek(VALUETYPE_ANY)) {
auto type = parseType();
auto type = parseType(true);
if (MATCHES(sequence(IDENTIFIER)))
statement = parseMemberVariable(type);