1
0
mirror of synced 2024-11-28 17:40:51 +01:00

patterns: Added auto type

This commit is contained in:
WerWolv 2021-09-23 23:43:16 +02:00
parent 82ee4ad4ca
commit 6713f65040
8 changed files with 41 additions and 8 deletions

View File

@ -324,6 +324,8 @@ namespace hex::pl {
pattern = new PatternDataPadding(offset, 1);
else if (this->m_type == Token::ValueType::String)
pattern = new PatternDataString(offset, 1);
else if (this->m_type == Token::ValueType::Auto)
return { nullptr };
else
LogConsole::abortEvaluation("invalid built-in type", this);
@ -371,6 +373,9 @@ namespace hex::pl {
auto patterns = this->m_type->createPatterns(evaluator);
for (auto &pattern : patterns) {
if (pattern == nullptr)
continue;
if (!this->m_name.empty())
pattern->setTypeName(this->m_name);
pattern->setEndian(this->m_endian.value_or(evaluator->getDefaultEndian()));
@ -1799,7 +1804,7 @@ namespace hex::pl {
u32 paramIndex = 0;
for (const auto &[name, type] : this->m_params) {
ctx->createVariable(name, type);
ctx->createVariable(name, type, params[paramIndex]);
ctx->setVariable(name, params[paramIndex]);
paramIndex++;

View File

@ -105,7 +105,7 @@ namespace hex::pl {
return this->m_stack;
}
void createVariable(const std::string &name, ASTNode *type);
void createVariable(const std::string &name, ASTNode *type, const std::optional<Token::Literal> &value = std::nullopt);
void setVariable(const std::string &name, const Token::Literal& value);

View File

@ -99,7 +99,7 @@ namespace hex::pl {
void parseAttribute(Attributable *currNode);
ASTNode* parseConditional();
ASTNode* parseWhileStatement();
ASTNodeTypeDecl* parseType(bool allowString = false);
ASTNodeTypeDecl* parseType(bool allowFunctionTypes = false);
ASTNode* parseUsingDeclaration();
ASTNode* parsePadding();
ASTNode* parseMemberVariable(ASTNodeTypeDecl *type);

View File

@ -91,6 +91,7 @@ namespace hex::pl {
Float = 0x42,
Double = 0x82,
String = 0x15,
Auto = 0x16,
CustomType = 0x00,
Padding = 0x1F,

View File

@ -3,7 +3,7 @@
namespace hex::pl {
void Evaluator::createVariable(const std::string &name, ASTNode *type) {
void Evaluator::createVariable(const std::string &name, ASTNode *type, const std::optional<Token::Literal> &value) {
auto &variables = *this->getScope(0).scope;
for (auto &variable : variables) {
if (variable->getVariableName() == name) {
@ -13,6 +13,27 @@ namespace hex::pl {
auto pattern = type->createPatterns(this).front();
if (pattern == nullptr) {
// Handle auto variables
if (!value.has_value())
LogConsole::abortEvaluation("cannot determine type of auto variable", type);
if (std::get_if<u128>(&*value) != nullptr)
pattern = new PatternDataUnsigned(0, sizeof(u128));
else if (std::get_if<s128>(&*value) != nullptr)
pattern = new PatternDataSigned(0, sizeof(s128));
else if (std::get_if<double>(&*value) != nullptr)
pattern = new PatternDataFloat(0, sizeof(double));
else if (std::get_if<bool>(&*value) != nullptr)
pattern = new PatternDataBoolean(0, sizeof(bool));
else if (std::get_if<char>(&*value) != nullptr)
pattern = new PatternDataCharacter(0, sizeof(char));
else if (std::get_if<PatternData*>(&*value) != nullptr)
pattern = std::get<PatternData*>(*value)->clone();
else if (std::get_if<std::string>(&*value) != nullptr)
pattern = new PatternDataString(0, 1);
}
pattern->setVariableName(name);
pattern->setOffset(this->getStack().size());
pattern->setLocal(true);

View File

@ -450,6 +450,8 @@ namespace hex::pl {
tokens.emplace_back(TOKEN(ValueType, String));
else if (identifier == "padding")
tokens.emplace_back(TOKEN(ValueType, Padding));
else if (identifier == "auto")
tokens.emplace_back(TOKEN(ValueType, Auto));
// If it's not a keyword and a builtin type, it has to be an identifier

View File

@ -645,7 +645,7 @@ namespace hex::pl {
/* Type declarations */
// [be|le] <Identifier|u8|u16|u32|u64|u128|s8|s16|s32|s64|s128|float|double|str>
ASTNodeTypeDecl* Parser::parseType(bool allowString) {
ASTNodeTypeDecl* Parser::parseType(bool allowFunctionTypes) {
std::optional<std::endian> endian;
if (MATCHES(sequence(KEYWORD_LE)))
@ -665,8 +665,12 @@ namespace hex::pl {
}
else if (MATCHES(sequence(VALUETYPE_ANY))) { // Builtin type
auto type = getValue<Token::ValueType>(-1);
if (!allowString && type == Token::ValueType::String)
throwParseError("cannot use 'str' in this context. Use a character array instead");
if (!allowFunctionTypes) {
if (type == Token::ValueType::String)
throwParseError("cannot use 'str' in this context. Use a character array instead");
else if (type == Token::ValueType::Auto)
throwParseError("cannot use 'auto' in this context");
}
return create(new ASTNodeTypeDecl({ }, new ASTNodeBuiltinType(type), endian));
} else throwParseError("failed to parse type. Expected identifier or builtin type");

View File

@ -32,7 +32,7 @@ namespace hex {
"u8", "u16", "u32", "u64", "u128",
"s8", "s16", "s32", "s64", "s128",
"float", "double", "char", "char16",
"bool", "padding", "str"
"bool", "padding", "str", "auto"
};
for (const auto name : builtInTypes) {