diff --git a/include/parser/ast_node.hpp b/include/parser/ast_node.hpp index 2288e38bb..aa00fb778 100644 --- a/include/parser/ast_node.hpp +++ b/include/parser/ast_node.hpp @@ -27,19 +27,20 @@ namespace hex::lang { class ASTNodeVariableDecl : public ASTNode { public: - explicit ASTNodeVariableDecl(const Token::TypeToken::Type &type, const std::string &name, const std::string& customTypeName = "", std::optional<u64> offset = { }) - : ASTNode(Type::VariableDecl), m_type(type), m_name(name), m_customTypeName(customTypeName), m_offset(offset) { } + explicit ASTNodeVariableDecl(const Token::TypeToken::Type &type, const std::string &name, const std::string& customTypeName = "", std::optional<u64> offset = { }, size_t arraySize = 1) + : ASTNode(Type::VariableDecl), m_type(type), m_name(name), m_customTypeName(customTypeName), m_offset(offset), m_arraySize(arraySize) { } const Token::TypeToken::Type& getVariableType() const { return this->m_type; } const std::string& getCustomVariableTypeName() const { return this->m_customTypeName; } const std::string& getVariableName() const { return this->m_name; }; - std::optional<u64> getOffset() { return this->m_offset; }; + std::optional<u64> getOffset() const { return this->m_offset; } + size_t getArraySize() const { return this->m_arraySize; } private: Token::TypeToken::Type m_type; std::string m_name, m_customTypeName; std::optional<u64> m_offset; - + size_t m_arraySize; }; class ASTNodeScope : public ASTNode { diff --git a/include/parser/token.hpp b/include/parser/token.hpp index f93468043..661ae2685 100644 --- a/include/parser/token.hpp +++ b/include/parser/token.hpp @@ -16,6 +16,8 @@ namespace hex::lang { EndOfExpression, ScopeOpen, ScopeClose, + ArrayOpen, + ArrayClose, Separator, EndOfProgram } type; diff --git a/source/parser/lexer.cpp b/source/parser/lexer.cpp index 5d5e8463b..8a538c190 100644 --- a/source/parser/lexer.cpp +++ b/source/parser/lexer.cpp @@ -83,6 +83,12 @@ namespace hex::lang { } else if (c == '}') { tokens.push_back({.type = Token::Type::ScopeClose}); offset += 1; + } else if (c == '[') { + tokens.push_back({.type = Token::Type::ArrayOpen}); + offset += 1; + } else if (c == ']') { + tokens.push_back({.type = Token::Type::ArrayClose}); + offset += 1; } else if (c == ',') { tokens.push_back({.type = Token::Type::Separator}); offset += 1; diff --git a/source/parser/parser.cpp b/source/parser/parser.cpp index b30c5dbb7..cee5665ce 100644 --- a/source/parser/parser.cpp +++ b/source/parser/parser.cpp @@ -35,6 +35,14 @@ namespace hex::lang { return new ASTNodeVariableDecl(Token::TypeToken::Type::CustomType, curr[-2].identifierToken.identifier, curr[-3].identifierToken.identifier); } + ASTNode* parseBuiltinArrayDecl(TokenIter &curr) { + return new ASTNodeVariableDecl(curr[-6].typeToken.type, curr[-5].identifierToken.identifier, "", { }, curr[-3].integerToken.integer); + } + + ASTNode* parseCustomTypeArrayDecl(TokenIter &curr) { + return new ASTNodeVariableDecl(Token::TypeToken::Type::CustomType, curr[-5].identifierToken.identifier, curr[-6].identifierToken.identifier, { }, curr[-3].integerToken.integer); + } + ASTNode* parseFreeBuiltinVariableDecl(TokenIter &curr) { return new ASTNodeVariableDecl(curr[-5].typeToken.type, curr[-4].identifierToken.identifier, "", curr[-2].integerToken.integer); } @@ -52,6 +60,10 @@ namespace hex::lang { nodes.push_back(parseBuiltinVariableDecl(curr)); else if (tryConsume(curr, {Token::Type::Identifier, Token::Type::Identifier, Token::Type::EndOfExpression})) nodes.push_back(parseCustomTypeVariableDecl(curr)); + else if (tryConsume(curr, {Token::Type::Type, Token::Type::Identifier, Token::Type::ArrayOpen, Token::Type::Integer, Token::Type::ArrayClose, Token::Type::EndOfExpression})) + nodes.push_back(parseBuiltinArrayDecl(curr)); + else if (tryConsume(curr, {Token::Type::Identifier, Token::Type::Identifier, Token::Type::ArrayOpen, Token::Type::Integer, Token::Type::ArrayClose, Token::Type::EndOfExpression})) + nodes.push_back(parseCustomTypeArrayDecl(curr)); else break; } diff --git a/source/views/view_pattern.cpp b/source/views/view_pattern.cpp index db0d12e85..6a80742a8 100644 --- a/source/views/view_pattern.cpp +++ b/source/views/view_pattern.cpp @@ -119,7 +119,7 @@ namespace hex { u64 offset = varNode->getOffset().value(); if (varNode->getVariableType() != lang::Token::TypeToken::Type::CustomType) { - this->setHighlight(offset, static_cast<u32>(varNode->getVariableType()) >> 4, varNode->getVariableName()); + this->setHighlight(offset, (static_cast<u32>(varNode->getVariableType()) >> 4) * varNode->getArraySize(), varNode->getVariableName()); } else { for (auto &structNode : findNodes<lang::ASTNodeStruct>(lang::ASTNode::Type::Struct, ast)) if (varNode->getCustomVariableTypeName() == structNode->getName()) @@ -139,7 +139,7 @@ namespace hex { s32 ViewPattern::highlightUsingDecls(std::vector<lang::ASTNode*> &ast, lang::ASTNodeTypeDecl* currTypeDeclNode, lang::ASTNodeVariableDecl* currVarDecl, u64 offset) { if (currTypeDeclNode->getAssignedType() != lang::Token::TypeToken::Type::CustomType) { - size_t size = static_cast<u32>(currTypeDeclNode->getAssignedType()) >> 4; + size_t size = (static_cast<u32>(currTypeDeclNode->getAssignedType()) >> 4) * currVarDecl->getArraySize(); this->setHighlight(offset, size, currVarDecl->getVariableName()); offset += size; @@ -173,7 +173,7 @@ namespace hex { auto var = static_cast<lang::ASTNodeVariableDecl*>(node); if (var->getVariableType() != lang::Token::TypeToken::Type::CustomType) { - size_t size = static_cast<u32>(var->getVariableType()) >> 4; + size_t size = (static_cast<u32>(var->getVariableType()) >> 4) * var->getArraySize(); this->setHighlight(offset, size, var->getVariableName()); offset += size; @@ -181,10 +181,15 @@ namespace hex { bool foundType = false; for (auto &structNode : findNodes<lang::ASTNodeStruct>(lang::ASTNode::Type::Struct, ast)) if (structNode->getName() == var->getCustomVariableTypeName()) { - auto size = this->highlightStruct(ast, structNode, offset); + size_t size = 0; + for (size_t i = 0; i < var->getArraySize(); i++) { + size = this->highlightStruct(ast, structNode, offset); - if (size == -1) - return -1; + if (size == -1) + return -1; + + offset += size; + } offset += size; foundType = true; diff --git a/source/views/view_pattern_data.cpp b/source/views/view_pattern_data.cpp index 270570efe..b153b72d3 100644 --- a/source/views/view_pattern_data.cpp +++ b/source/views/view_pattern_data.cpp @@ -34,19 +34,24 @@ namespace hex { if (ImGui::Begin("Pattern Data", &this->m_windowOpen)) { ImGui::BeginChild("##scrolling", ImVec2(0, 0), false, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoNav); - for (auto& [offset, size, color, name] : this->m_highlights) { - std::vector<u8> buffer(size + 1, 0x00); + if (this->m_dataProvider != nullptr && this->m_dataProvider->isReadable()) { - this->m_dataProvider->read(offset, buffer.data(), size); + for (auto&[offset, size, color, name] : this->m_highlights) { + std::vector<u8> buffer(size + 1, 0x00); - if (size <= 8) { - u64 data = 0; - std::memcpy(&data, buffer.data(), size); + this->m_dataProvider->read(offset, buffer.data(), size); - ImGui::LabelText(name.c_str(), "[0x%08lx:0x%08lx] %lu (0x%08lx) \"%s\"", offset, offset + size, data, data, makeDisplayable(buffer.data(), buffer.size()).c_str()); + if (size <= 8) { + u64 data = 0; + std::memcpy(&data, buffer.data(), size); + + ImGui::LabelText(name.c_str(), "[0x%08lx:0x%08lx] %lu (0x%08lx) \"%s\"", offset, + offset + size, data, data, + makeDisplayable(buffer.data(), buffer.size()).c_str()); + } else + ImGui::LabelText(name.c_str(), "[0x%08lx:0x%08lx] [ ARRAY ] \"%s\"", offset, offset + size, + makeDisplayable(buffer.data(), buffer.size()).c_str()); } - else - ImGui::LabelText(name.c_str(), "[0x%08lx:0x%08lx] [ ARRAY ] \"%s\"", offset, offset + size, makeDisplayable(buffer.data(), buffer.size()).c_str()); } ImGui::EndChild();