From 950598911cb856d949308e487ef4d86eadbb772f Mon Sep 17 00:00:00 2001 From: WerWolv Date: Tue, 13 Apr 2021 20:40:21 +0200 Subject: [PATCH] patterns: Allow usage of types within itself and used out-of-order --- plugins/libimhex/CMakeLists.txt | 2 -- .../libimhex/include/hex/lang/ast_node.hpp | 5 ++++- .../source/lang/builtin_functions.cpp | 10 --------- plugins/libimhex/source/lang/evaluator.cpp | 21 ++++++++++++++----- plugins/libimhex/source/lang/parser.cpp | 20 ++++++++++++++++++ 5 files changed, 40 insertions(+), 18 deletions(-) delete mode 100644 plugins/libimhex/source/lang/builtin_functions.cpp diff --git a/plugins/libimhex/CMakeLists.txt b/plugins/libimhex/CMakeLists.txt index 96f5413d2..c7b77a49d 100644 --- a/plugins/libimhex/CMakeLists.txt +++ b/plugins/libimhex/CMakeLists.txt @@ -33,8 +33,6 @@ set(LIBIMHEX_SOURCES source/lang/parser.cpp source/lang/validator.cpp source/lang/evaluator.cpp - source/lang/builtin_functions.cpp - source/providers/provider.cpp source/views/view.cpp diff --git a/plugins/libimhex/include/hex/lang/ast_node.hpp b/plugins/libimhex/include/hex/lang/ast_node.hpp index 0ea892c25..402df433b 100644 --- a/plugins/libimhex/include/hex/lang/ast_node.hpp +++ b/plugins/libimhex/include/hex/lang/ast_node.hpp @@ -149,7 +149,10 @@ namespace hex::lang { ASTNodeTypeDecl(const ASTNodeTypeDecl& other) : ASTNode(other), Attributable(other) { this->m_name = other.m_name; - this->m_type = other.m_type->clone(); + if (other.m_type != nullptr) + this->m_type = other.m_type->clone(); + else + this->m_type = nullptr; this->m_endian = other.m_endian; } diff --git a/plugins/libimhex/source/lang/builtin_functions.cpp b/plugins/libimhex/source/lang/builtin_functions.cpp deleted file mode 100644 index d55fe9bdb..000000000 --- a/plugins/libimhex/source/lang/builtin_functions.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include - -#include - - -namespace hex::lang { - - - -} \ No newline at end of file diff --git a/plugins/libimhex/source/lang/evaluator.cpp b/plugins/libimhex/source/lang/evaluator.cpp index b26c25272..dab01f0ef 100644 --- a/plugins/libimhex/source/lang/evaluator.cpp +++ b/plugins/libimhex/source/lang/evaluator.cpp @@ -517,10 +517,6 @@ namespace hex::lang { for (auto &member : node->getMembers()) { this->evaluateMember(member, memberPatterns, true); structPattern->setMembers(memberPatterns); - - for (auto &pmember : memberPatterns) - hex::print("{}\n", pmember->getVariableName()); - hex::print("======\n"); } structPattern->setSize(this->m_currOffset - startOffset); @@ -639,6 +635,9 @@ namespace hex::lang { PatternData* Evaluator::evaluateType(ASTNodeTypeDecl *node) { auto type = node->getType(); + if (type == nullptr) + type = this->m_types[node->getName().data()]; + this->m_endianStack.push_back(node->getEndian().value_or(this->m_defaultDataEndian)); PatternData *pattern; @@ -858,6 +857,18 @@ namespace hex::lang { this->m_currOffset = 0; try { + for (const auto& node : ast) { + if (auto typeDeclNode = dynamic_cast(node); typeDeclNode != nullptr) { + if (this->m_types[typeDeclNode->getName().data()] == nullptr) + this->m_types[typeDeclNode->getName().data()] = typeDeclNode->getType(); + } + } + + for (const auto& [name, node] : this->m_types) { + if (auto typeDeclNode = static_cast(node); typeDeclNode->getType() == nullptr) + this->getConsole().abortEvaluation(hex::format("unresolved type '{}'", name)); + } + for (const auto& node : ast) { this->m_currMembers.clear(); this->m_currMemberScope.clear(); @@ -873,7 +884,7 @@ namespace hex::lang { } else if (auto pointerDeclNode = dynamic_cast(node); pointerDeclNode != nullptr) { this->m_globalMembers.push_back(this->evaluatePointer(pointerDeclNode)); } else if (auto typeDeclNode = dynamic_cast(node); typeDeclNode != nullptr) { - this->m_types[typeDeclNode->getName().data()] = typeDeclNode->getType(); + // Handled above } else if (auto functionCallNode = dynamic_cast(node); functionCallNode != nullptr) { auto result = this->evaluateFunctionCall(functionCallNode); delete result; diff --git a/plugins/libimhex/source/lang/parser.cpp b/plugins/libimhex/source/lang/parser.cpp index d50b7f4d1..13aadc537 100644 --- a/plugins/libimhex/source/lang/parser.cpp +++ b/plugins/libimhex/source/lang/parser.cpp @@ -498,6 +498,11 @@ namespace hex::lang { const auto &typeName = getValue(-2); auto structGuard = SCOPE_GUARD { delete structNode; }; + if (this->m_types.contains(typeName)) + throwParseError(hex::format("redefinition of type '{}'", typeName)); + + this->m_types.insert({ typeName, new ASTNodeTypeDecl(typeName, nullptr) }); + while (!MATCHES(sequence(SEPARATOR_CURLYBRACKETCLOSE))) { structNode->addMember(parseMember()); } @@ -513,6 +518,11 @@ namespace hex::lang { const auto &typeName = getValue(-2); auto unionGuard = SCOPE_GUARD { delete unionNode; }; + if (this->m_types.contains(typeName)) + throwParseError(hex::format("redefinition of type '{}'", typeName)); + + this->m_types.insert({ typeName, new ASTNodeTypeDecl(typeName, nullptr) }); + while (!MATCHES(sequence(SEPARATOR_CURLYBRACKETCLOSE))) { unionNode->addMember(parseMember()); } @@ -537,6 +547,11 @@ namespace hex::lang { const auto enumNode = new ASTNodeEnum(underlyingType); auto enumGuard = SCOPE_GUARD { delete enumNode; }; + if (this->m_types.contains(typeName)) + throwParseError(hex::format("redefinition of type '{}'", typeName)); + + this->m_types.insert({ typeName, new ASTNodeTypeDecl(typeName, nullptr) }); + ASTNode *lastEntry = nullptr; while (!MATCHES(sequence(SEPARATOR_CURLYBRACKETCLOSE))) { if (MATCHES(sequence(IDENTIFIER, OPERATOR_ASSIGNMENT))) { @@ -581,6 +596,11 @@ namespace hex::lang { const auto bitfieldNode = new ASTNodeBitfield(); auto enumGuard = SCOPE_GUARD { delete bitfieldNode; }; + if (this->m_types.contains(typeName)) + throwParseError(hex::format("redefinition of type '{}'", typeName)); + + this->m_types.insert({ typeName, new ASTNodeTypeDecl(typeName, nullptr) }); + while (!MATCHES(sequence(SEPARATOR_CURLYBRACKETCLOSE))) { if (MATCHES(sequence(IDENTIFIER, OPERATOR_INHERIT))) { auto name = getValue(-2);