From b7003d499cb50a227ecece6ad9638e7fc5277db1 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Fri, 27 Aug 2021 09:54:34 +0200 Subject: [PATCH] patterns: Fix function parsing --- plugins/libimhex/source/lang/evaluator.cpp | 36 +++++++++++++++-- plugins/libimhex/source/lang/parser.cpp | 45 +++++++++++----------- 2 files changed, 56 insertions(+), 25 deletions(-) diff --git a/plugins/libimhex/source/lang/evaluator.cpp b/plugins/libimhex/source/lang/evaluator.cpp index 5b9b3cf0f..b78998c4e 100644 --- a/plugins/libimhex/source/lang/evaluator.cpp +++ b/plugins/libimhex/source/lang/evaluator.cpp @@ -74,7 +74,7 @@ namespace hex::lang { if (candidate != currMembers.end()) currPattern = *candidate; else - this->getConsole().abortEvaluation(hex::format("no member found with identifier '{0}'", *stringPart)); + return nullptr; } } else if (auto nodePart = std::get_if(&part); nodePart != nullptr) { if (auto numericalExpressionNode = dynamic_cast(*nodePart)) { @@ -144,7 +144,7 @@ namespace hex::lang { identifier += "."; } identifier.pop_back(); - this->getConsole().abortEvaluation(hex::format("no identifier with name '{}' was found", identifier)); + this->getConsole().abortEvaluation(hex::format("no identifier with name '{}' found", identifier)); } return currPattern; @@ -189,6 +189,30 @@ namespace hex::lang { case 16: return new ASTNodeIntegerLiteral(hex::changeEndianess(*reinterpret_cast(value), 16, signedPattern->getEndian())); default: this->getConsole().abortEvaluation("invalid rvalue size"); } + } else if (auto boolPattern = dynamic_cast(currPattern); boolPattern != nullptr) { + u8 value[boolPattern->getSize()]; + if (currPattern->isLocal()) + std::memcpy(value, this->m_localStack.data() + boolPattern->getOffset(), boolPattern->getSize()); + else + this->m_provider->read(boolPattern->getOffset(), value, boolPattern->getSize()); + + return new ASTNodeIntegerLiteral(hex::changeEndianess(*reinterpret_cast(value), 1, boolPattern->getEndian())); + } else if (auto charPattern = dynamic_cast(currPattern); charPattern != nullptr) { + u8 value[charPattern->getSize()]; + if (currPattern->isLocal()) + std::memcpy(value, this->m_localStack.data() + charPattern->getOffset(), charPattern->getSize()); + else + this->m_provider->read(charPattern->getOffset(), value, charPattern->getSize()); + + return new ASTNodeIntegerLiteral(hex::changeEndianess(*reinterpret_cast(value), 1, charPattern->getEndian())); + } else if (auto char16Pattern = dynamic_cast(currPattern); char16Pattern != nullptr) { + u8 value[char16Pattern->getSize()]; + if (currPattern->isLocal()) + std::memcpy(value, this->m_localStack.data() + char16Pattern->getOffset(), char16Pattern->getSize()); + else + this->m_provider->read(char16Pattern->getOffset(), value, char16Pattern->getSize()); + + return new ASTNodeIntegerLiteral(hex::changeEndianess(*reinterpret_cast(value), 1, char16Pattern->getEndian())); } else if (auto enumPattern = dynamic_cast(currPattern); enumPattern != nullptr) { u8 value[enumPattern->getSize()]; if (currPattern->isLocal()) @@ -494,7 +518,13 @@ namespace hex::lang { evaluator.createLocalVariable(paramNames[i], pattern); evaluator.setLocalVariableValue(paramNames[i], &value, sizeof(value)); }, integerLiteralNode->getValue()); - } + } else if (auto stringLiteralNode = dynamic_cast(params[i]); stringLiteralNode != nullptr) { + auto string = stringLiteralNode->getString(); + + evaluator.createLocalVariable(paramNames[i], new PatternDataString(0, string.length())); + evaluator.setLocalVariableValue(paramNames[i], string.data(), string.length()); + } else + evaluator.getConsole().abortEvaluation(hex::format("cannot create local variable {}, invalid type", paramNames[i])); } evaluator.m_currOffset = startOffset; diff --git a/plugins/libimhex/source/lang/parser.cpp b/plugins/libimhex/source/lang/parser.cpp index 95fa1abb4..6383bc6d4 100644 --- a/plugins/libimhex/source/lang/parser.cpp +++ b/plugins/libimhex/source/lang/parser.cpp @@ -106,13 +106,11 @@ namespace hex::lang { return node; } else if (MATCHES(sequence(IDENTIFIER))) { auto originalPos = this->m_curr; - this->m_curr++; parseScopeResolution(); bool isFunction = peek(SEPARATOR_ROUNDBRACKETOPEN); this->m_curr = originalPos; if (isFunction) { - this->m_curr++; return TO_NUMERIC_EXPRESSION(parseFunctionCall()); } else { @@ -384,7 +382,7 @@ namespace hex::lang { while (hasParams) { params.push_back(getValue(-1)); - if (!MATCHES(sequence(SEPARATOR_COMMA))) { + if (!MATCHES(sequence(SEPARATOR_COMMA, IDENTIFIER))) { if (MATCHES(sequence(SEPARATOR_ROUNDBRACKETCLOSE))) break; else @@ -419,23 +417,7 @@ namespace hex::lang { bool needsSemicolon = true; ASTNode *statement; - if (peek(IDENTIFIER)) { - auto originalPos = this->m_curr; - this->m_curr++; - parseScopeResolution(); - bool isFunction = peek(SEPARATOR_ROUNDBRACKETOPEN); - this->m_curr = originalPos; - - if (isFunction) { - this->m_curr++; - statement = parseFunctionCall(); - } - else - statement = parseMemberVariable(parseType()); - } - else if (peek(KEYWORD_BE) || peek(KEYWORD_LE) || peek(VALUETYPE_ANY)) - statement = parseMemberVariable(parseType()); - else if (MATCHES(sequence(IDENTIFIER, OPERATOR_ASSIGNMENT))) + if (MATCHES(sequence(IDENTIFIER, OPERATOR_ASSIGNMENT))) statement = parseFunctionVariableAssignment(); else if (MATCHES(sequence(KEYWORD_RETURN))) statement = parseFunctionReturnStatement(); @@ -445,6 +427,25 @@ namespace hex::lang { } else if (MATCHES(sequence(KEYWORD_WHILE, SEPARATOR_ROUNDBRACKETOPEN))) { statement = parseFunctionWhileLoop(); needsSemicolon = false; + } else if (MATCHES(sequence(IDENTIFIER))) { + auto originalPos = this->m_curr; + parseScopeResolution(); + bool isFunction = peek(SEPARATOR_ROUNDBRACKETOPEN); + this->m_curr = originalPos; + + if (isFunction) { + statement = parseFunctionCall(); + } + else + statement = parseMemberVariable(parseType()); + } + else if (peek(KEYWORD_BE) || peek(KEYWORD_LE) || peek(VALUETYPE_ANY)) { + auto type = parseType(); + + if (MATCHES(sequence(IDENTIFIER))) + statement = parseMemberVariable(type); + else + throwParseError("invalid variable declaration"); } else throwParseError("invalid sequence", 0); @@ -632,8 +633,6 @@ namespace hex::lang { // (parseType) Identifier ASTNode* Parser::parseMemberVariable(ASTNodeTypeDecl *type) { - if (type == nullptr) throwParseError("invalid type used in variable declaration", -1); - if (peek(SEPARATOR_COMMA)) { std::vector variables; @@ -708,6 +707,8 @@ namespace hex::lang { member = parseMemberVariable(type); else if (MATCHES(sequence(OPERATOR_STAR, IDENTIFIER, OPERATOR_INHERIT))) member = parseMemberPointerVariable(type); + else + throwParseError("invalid variable declaration"); } else if (MATCHES(sequence(VALUETYPE_PADDING, SEPARATOR_SQUAREBRACKETOPEN))) member = parsePadding();