From 929437c15940cb6a74fe714cdd89b350d287899b Mon Sep 17 00:00:00 2001 From: WerWolv Date: Mon, 18 Oct 2021 22:04:54 +0200 Subject: [PATCH] patterns: Added global variables --- .../source/pattern_language/evaluator.cpp | 42 ++++++++++++++++--- .../source/pattern_language/parser.cpp | 10 +++-- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/plugins/libimhex/source/pattern_language/evaluator.cpp b/plugins/libimhex/source/pattern_language/evaluator.cpp index 4189bf419..697ec4d78 100644 --- a/plugins/libimhex/source/pattern_language/evaluator.cpp +++ b/plugins/libimhex/source/pattern_language/evaluator.cpp @@ -49,11 +49,26 @@ namespace hex::pl { void Evaluator::setVariable(const std::string &name, const Token::Literal& value) { PatternData *pattern = nullptr; - auto &variables = *this->getScope(0).scope; - for (auto &variable : variables) { - if (variable->getVariableName() == name) { - pattern = variable; - break; + { + auto &variables = *this->getScope(0).scope; + for (auto &variable : variables) { + if (variable->getVariableName() == name) { + pattern = variable; + break; + } + } + } + + if (pattern == nullptr) { + auto &variables = *this->getGlobalScope().scope; + for (auto &variable : variables) { + if (variable->getVariableName() == name) { + if (!variable->isLocal()) + LogConsole::abortEvaluation(hex::format("cannot modify global variable '{}' which has been placed in memory", name)); + + pattern = variable; + break; + } } } @@ -127,6 +142,18 @@ namespace hex::pl { delete node->evaluate(this); } else if (dynamic_cast(node)) { this->m_customFunctionDefinitions.push_back(node->evaluate(this)); + } else if (auto varDeclNode = dynamic_cast(node)) { + auto pattern = node->createPatterns(this).front(); + + if (varDeclNode->getPlacementOffset() == nullptr) { + auto type = varDeclNode->getType()->evaluate(this); + ON_SCOPE_EXIT { delete type; }; + + this->createVariable(pattern->getVariableName(), type); + delete pattern; + } else { + patterns.push_back(pattern); + } } else { auto newPatterns = node->createPatterns(this); patterns.insert(patterns.end(), newPatterns.begin(), newPatterns.end()); @@ -164,6 +191,11 @@ namespace hex::pl { return std::nullopt; } + // Remove global local variables + std::erase_if(patterns, [](PatternData *pattern) { + return pattern->isLocal(); + }); + return patterns; } diff --git a/plugins/libimhex/source/pattern_language/parser.cpp b/plugins/libimhex/source/pattern_language/parser.cpp index 6f59ac446..67cafdde3 100644 --- a/plugins/libimhex/source/pattern_language/parser.cpp +++ b/plugins/libimhex/source/pattern_language/parser.cpp @@ -1009,10 +1009,12 @@ namespace hex::pl { ASTNode* Parser::parseVariablePlacement(ASTNodeTypeDecl *type) { auto name = getValue(-1).get(); - if (!MATCHES(sequence(OPERATOR_AT))) - throwParseError("expected placement instruction", -1); - - auto placementOffset = parseMathematicalExpression(); + ASTNode *placementOffset; + if (MATCHES(sequence(OPERATOR_AT))) { + placementOffset = parseMathematicalExpression(); + } else { + placementOffset = nullptr; + } return create(new ASTNodeVariableDecl(name, type, placementOffset)); }