From 3850349eaed0fd31b760ecbf6c03cc3d86ef1f4f Mon Sep 17 00:00:00 2001 From: WerWolv Date: Sat, 25 Sep 2021 14:52:17 +0200 Subject: [PATCH] patterns: Fixed enum entry scope resolution --- .../include/hex/pattern_language/ast_node.hpp | 33 +++++++++++++++---- .../source/pattern_language/evaluator.cpp | 4 +-- .../source/pattern_language/lexer.cpp | 2 +- .../source/pattern_language/parser.cpp | 5 ++- 4 files changed, 33 insertions(+), 11 deletions(-) diff --git a/plugins/libimhex/include/hex/pattern_language/ast_node.hpp b/plugins/libimhex/include/hex/pattern_language/ast_node.hpp index 9afc55ac6..d82ed4841 100644 --- a/plugins/libimhex/include/hex/pattern_language/ast_node.hpp +++ b/plugins/libimhex/include/hex/pattern_language/ast_node.hpp @@ -1282,7 +1282,7 @@ namespace hex::pl { }; Token::Literal literal; - if (dynamic_cast(pattern)) { + if (dynamic_cast(pattern) || dynamic_cast(pattern)) { u128 value = 0; readValue(value, pattern); literal = value; @@ -1440,20 +1440,40 @@ namespace hex::pl { class ASTNodeScopeResolution : public ASTNode { public: - explicit ASTNodeScopeResolution(std::vector path) : ASTNode(), m_path(std::move(path)) { } + explicit ASTNodeScopeResolution(ASTNode *type, std::string name) : ASTNode(), m_type(type), m_name(std::move(name)) { } - ASTNodeScopeResolution(const ASTNodeScopeResolution&) = default; + ASTNodeScopeResolution(const ASTNodeScopeResolution &other) { + this->m_type = other.m_type->clone(); + this->m_name = other.m_name; + } + + ~ASTNodeScopeResolution() override { + delete this->m_type; + } [[nodiscard]] ASTNode* clone() const override { return new ASTNodeScopeResolution(*this); } - const std::vector& getPath() { - return this->m_path; + [[nodiscard]] ASTNode* evaluate(Evaluator *evaluator) const override { + auto type = this->m_type->evaluate(evaluator); + ON_SCOPE_EXIT { delete type; }; + + if (auto enumType = dynamic_cast(type)) { + for (auto &[name, value] : enumType->getEntries()) { + if (name == this->m_name) + return value->evaluate(evaluator); + } + } else { + LogConsole::abortEvaluation("invalid scope resolution. Cannot access this type"); + } + + LogConsole::abortEvaluation(hex::format("could not find constant '{}'", this->m_name), this); } private: - std::vector m_path; + ASTNode *m_type; + std::string m_name; }; class ASTNodeConditionalStatement : public ASTNode { @@ -1828,7 +1848,6 @@ namespace hex::pl { u32 paramIndex = 0; for (const auto &[name, type] : this->m_params) { - hex::log::info("{}", name); ctx->createVariable(name, type, params[paramIndex]); ctx->setVariable(name, params[paramIndex]); diff --git a/plugins/libimhex/source/pattern_language/evaluator.cpp b/plugins/libimhex/source/pattern_language/evaluator.cpp index f721326d4..3a24418ca 100644 --- a/plugins/libimhex/source/pattern_language/evaluator.cpp +++ b/plugins/libimhex/source/pattern_language/evaluator.cpp @@ -25,9 +25,9 @@ namespace hex::pl { else if (std::get_if(&*value) != nullptr) pattern = new PatternDataFloat(0, sizeof(double)); else if (std::get_if(&*value) != nullptr) - pattern = new PatternDataBoolean(0, sizeof(bool)); + pattern = new PatternDataBoolean(0); else if (std::get_if(&*value) != nullptr) - pattern = new PatternDataCharacter(0, sizeof(char)); + pattern = new PatternDataCharacter(0); else if (std::get_if(&*value) != nullptr) pattern = std::get(*value)->clone(); else if (std::get_if(&*value) != nullptr) diff --git a/plugins/libimhex/source/pattern_language/lexer.cpp b/plugins/libimhex/source/pattern_language/lexer.cpp index ce856e0a1..53e53daf5 100644 --- a/plugins/libimhex/source/pattern_language/lexer.cpp +++ b/plugins/libimhex/source/pattern_language/lexer.cpp @@ -375,7 +375,7 @@ namespace hex::pl { tokens.emplace_back(VALUE_TOKEN(String, Token::Literal(s))); offset += stringSize; - } else if (std::isalpha(c)) { + } else if (std::isalpha(c) || c == '_') { std::string identifier = matchTillInvalid(&code[offset], [](char c) -> bool { return std::isalnum(c) || c == '_'; }); // Check for reserved keywords diff --git a/plugins/libimhex/source/pattern_language/parser.cpp b/plugins/libimhex/source/pattern_language/parser.cpp index 223675136..601413eae 100644 --- a/plugins/libimhex/source/pattern_language/parser.cpp +++ b/plugins/libimhex/source/pattern_language/parser.cpp @@ -77,7 +77,10 @@ namespace hex::pl { typeName += "::"; continue; } else { - return create(new ASTNodeScopeResolution({ typeName, getValue(-1).get() })); + if (!this->m_types.contains(typeName)) + throwParseError(hex::format("cannot access scope of invalid type '{}'", typeName), -1); + + return create(new ASTNodeScopeResolution(this->m_types[typeName]->clone(), getValue(-1).get())); } } else