diff --git a/include/lang/evaluator.hpp b/include/lang/evaluator.hpp index a79190266..81bbda059 100644 --- a/include/lang/evaluator.hpp +++ b/include/lang/evaluator.hpp @@ -38,6 +38,7 @@ namespace hex::lang { std::endian m_defaultDataEndian; u64 m_currOffset = 0; std::vector m_endianStack; + std::vector m_globalMembers; std::vector*> m_currMembers; std::map m_functions; diff --git a/source/lang/evaluator.cpp b/source/lang/evaluator.cpp index fa1887b00..e584ddbfb 100644 --- a/source/lang/evaluator.cpp +++ b/source/lang/evaluator.cpp @@ -46,25 +46,30 @@ namespace hex::lang { } ASTNodeIntegerLiteral* Evaluator::evaluateRValue(ASTNodeRValue *node) { - if (this->m_currMembers.empty()) + if (this->m_currMembers.empty() && this->m_globalMembers.empty()) throwEvaluateError("no variables available", node->getLineNumber()); - const std::vector* currMembers = this->m_currMembers.back(); + std::vector currMembers; + + if (!this->m_currMembers.empty()) + std::copy(this->m_currMembers.back()->begin(), this->m_currMembers.back()->end(), std::back_inserter(currMembers)); + if (!this->m_globalMembers.empty()) + std::copy(this->m_globalMembers.begin(), this->m_globalMembers.end(), std::back_inserter(currMembers)); PatternData *currPattern = nullptr; for (const auto &identifier : node->getPath()) { if (auto structPattern = dynamic_cast(currPattern); structPattern != nullptr) - currMembers = &structPattern->getMembers(); + currMembers = structPattern->getMembers(); else if (auto unionPattern = dynamic_cast(currPattern); unionPattern != nullptr) - currMembers = &unionPattern->getMembers(); + currMembers = unionPattern->getMembers(); else if (currPattern != nullptr) throwEvaluateError("tried to access member of a non-struct/union type", node->getLineNumber()); - auto candidate = std::find_if(currMembers->begin(), currMembers->end(), [&](auto member) { + auto candidate = std::find_if(currMembers.begin(), currMembers.end(), [&](auto member) { return member->getVariableName() == identifier; }); - if (candidate != currMembers->end()) + if (candidate != currMembers.end()) currPattern = *candidate; else throwEvaluateError(hex::format("could not find identifier '%s'", identifier.c_str()), node->getLineNumber()); @@ -481,7 +486,7 @@ namespace hex::lang { }, valueNode->getValue()); } if (this->m_currOffset >= this->m_provider->getActualSize()) - throwEvaluateError("array exceeds size of file", node->getLineNumber()); + throwEvaluateError("variable placed out of range", node->getLineNumber()); PatternData *pattern; if (auto typeDecl = dynamic_cast(node->getType()); typeDecl != nullptr) @@ -648,18 +653,16 @@ namespace hex::lang { std::optional> Evaluator::evaluate(const std::vector &ast) { - std::vector patterns; - try { for (const auto& node : ast) { this->m_endianStack.push_back(this->m_defaultDataEndian); if (auto variableDeclNode = dynamic_cast(node); variableDeclNode != nullptr) { - patterns.push_back(this->evaluateVariable(variableDeclNode)); + this->m_globalMembers.push_back(this->evaluateVariable(variableDeclNode)); } else if (auto arrayDeclNode = dynamic_cast(node); arrayDeclNode != nullptr) { - patterns.push_back(this->evaluateArray(arrayDeclNode)); + this->m_globalMembers.push_back(this->evaluateArray(arrayDeclNode)); } else if (auto pointerDeclNode = dynamic_cast(node); pointerDeclNode != nullptr) { - patterns.push_back(this->evaluatePointer(pointerDeclNode)); + 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(); } @@ -675,7 +678,7 @@ namespace hex::lang { this->m_endianStack.clear(); - return patterns; + return this->m_globalMembers; } } \ No newline at end of file