patterns: Allow str to be used in function bodies
This commit is contained in:
parent
a93049056a
commit
4b9aff5b29
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 "< ??? >";
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user