1
0
mirror of synced 2025-01-31 03:53:44 +01:00

Added array sizes based on other local variables

This commit is contained in:
WerWolv 2020-11-21 20:19:33 +01:00
parent 4cd18b8358
commit ed4ed6b433
7 changed files with 73 additions and 13 deletions

View File

@ -31,20 +31,22 @@ namespace hex::lang {
class ASTNodeVariableDecl : public ASTNode { class ASTNodeVariableDecl : public ASTNode {
public: public:
explicit ASTNodeVariableDecl(const Token::TypeToken::Type &type, const std::string &name, const std::string& customTypeName = "", std::optional<u64> offset = { }, size_t arraySize = 1) explicit ASTNodeVariableDecl(const Token::TypeToken::Type &type, const std::string &name, const std::string& customTypeName = "", std::optional<u64> offset = { }, size_t arraySize = 1, std::optional<std::string> arraySizeVariable = { })
: ASTNode(Type::VariableDecl), m_type(type), m_name(name), m_customTypeName(customTypeName), m_offset(offset), m_arraySize(arraySize) { } : ASTNode(Type::VariableDecl), m_type(type), m_name(name), m_customTypeName(customTypeName), m_offset(offset), m_arraySize(arraySize), m_arraySizeVariable(arraySizeVariable) { }
const Token::TypeToken::Type& getVariableType() const { return this->m_type; } const Token::TypeToken::Type& getVariableType() const { return this->m_type; }
const std::string& getCustomVariableTypeName() const { return this->m_customTypeName; } const std::string& getCustomVariableTypeName() const { return this->m_customTypeName; }
const std::string& getVariableName() const { return this->m_name; }; const std::string& getVariableName() const { return this->m_name; };
std::optional<u64> getOffset() const { return this->m_offset; } std::optional<u64> getOffset() const { return this->m_offset; }
size_t getArraySize() const { return this->m_arraySize; } size_t getArraySize() const { return this->m_arraySize; }
std::optional<std::string> getArraySizeVariable() const { return this->m_arraySizeVariable; }
private: private:
Token::TypeToken::Type m_type; Token::TypeToken::Type m_type;
std::string m_name, m_customTypeName; std::string m_name, m_customTypeName;
std::optional<u64> m_offset; std::optional<u64> m_offset;
size_t m_arraySize; size_t m_arraySize;
std::optional<std::string> m_arraySizeVariable;
}; };
class ASTNodeScope : public ASTNode { class ASTNodeScope : public ASTNode {

View File

@ -2,6 +2,7 @@
#include <hex.hpp> #include <hex.hpp>
#include "providers/provider.hpp"
#include "lang/pattern_data.hpp" #include "lang/pattern_data.hpp"
#include "ast_node.hpp" #include "ast_node.hpp"
@ -13,12 +14,13 @@ namespace hex::lang {
class Evaluator { class Evaluator {
public: public:
Evaluator(); Evaluator(prv::Provider* &provider);
std::pair<Result, std::vector<PatternData*>> evaluate(const std::vector<ASTNode*>& ast); std::pair<Result, std::vector<PatternData*>> evaluate(const std::vector<ASTNode*>& ast);
private: private:
std::unordered_map<std::string, ASTNode*> m_types; std::unordered_map<std::string, ASTNode*> m_types;
prv::Provider* &m_provider;
std::pair<PatternData*, size_t> createStructPattern(ASTNodeVariableDecl *varDeclNode, u64 offset); std::pair<PatternData*, size_t> createStructPattern(ASTNodeVariableDecl *varDeclNode, u64 offset);
std::pair<PatternData*, size_t> createUnionPattern(ASTNodeVariableDecl *varDeclNode, u64 offset); std::pair<PatternData*, size_t> createUnionPattern(ASTNodeVariableDecl *varDeclNode, u64 offset);

View File

@ -50,9 +50,10 @@ namespace hex::lang {
[[nodiscard]] Type getPatternType() const { return this->m_type; } [[nodiscard]] Type getPatternType() const { return this->m_type; }
[[nodiscard]] u64 getOffset() const { return this->m_offset; } [[nodiscard]] u64 getOffset() const { return this->m_offset; }
[[nodiscard]] size_t getSize() const { return this->m_size; } [[nodiscard]] size_t getSize() const { return this->m_size; }
[[nodiscard]] const std::string& getName() const { return this->m_name; }
[[nodiscard]] u32 getColor() const { return this->m_color; } [[nodiscard]] u32 getColor() const { return this->m_color; }
[[nodiscard]] const std::string& getName() const { return this->m_name; } void setColor(u32 color) { this->m_color = color; }
virtual void createEntry(prv::Provider* &provider) = 0; virtual void createEntry(prv::Provider* &provider) = 0;
virtual std::string getTypeName() = 0; virtual std::string getTypeName() = 0;

View File

@ -5,7 +5,7 @@
namespace hex::lang { namespace hex::lang {
Evaluator::Evaluator() { Evaluator::Evaluator(prv::Provider* &provider) : m_provider(provider) {
} }
@ -52,6 +52,31 @@ namespace hex::lang {
members.push_back(pattern); members.push_back(pattern);
structSize += size; structSize += size;
} }
else if (member->getArraySizeVariable().has_value()) {
std::optional<size_t> arraySize;
for (auto &prevMember : members) {
if (prevMember->getPatternType() == PatternData::Type::Unsigned && prevMember->getName() == member->getArraySizeVariable()) {
u64 value = 0;
this->m_provider->read(prevMember->getOffset(), &value, prevMember->getSize());
arraySize = value;
}
}
if (!arraySize.has_value())
return { nullptr, 0 };
ASTNodeVariableDecl *processedMember = new ASTNodeVariableDecl(member->getVariableType(), member->getVariableName(), member->getCustomVariableTypeName(), member->getOffset(), arraySize.value());
const auto &[pattern, size] = this->createArrayPattern(processedMember, offset + structSize);
if (pattern == nullptr)
return { nullptr, 0 };
members.push_back(pattern);
structSize += size;
}
else if (member->getVariableType() != Token::TypeToken::Type::CustomType) { else if (member->getVariableType() != Token::TypeToken::Type::CustomType) {
const auto &[pattern, size] = this->createBuiltInTypePattern(member, offset + structSize); const auto &[pattern, size] = this->createBuiltInTypePattern(member, offset + structSize);
@ -173,18 +198,27 @@ namespace hex::lang {
std::pair<PatternData*, size_t> Evaluator::createArrayPattern(ASTNodeVariableDecl *varDeclNode, u64 offset) { std::pair<PatternData*, size_t> Evaluator::createArrayPattern(ASTNodeVariableDecl *varDeclNode, u64 offset) {
std::vector<PatternData*> entries; std::vector<PatternData*> entries;
auto arraySizeVariable = varDeclNode->getArraySizeVariable();
size_t arrayOffset = 0; size_t arrayOffset = 0;
std::optional<u32> arrayColor;
for (u32 i = 0; i < varDeclNode->getArraySize(); i++) { for (u32 i = 0; i < varDeclNode->getArraySize(); i++) {
ASTNodeVariableDecl *nonArrayVarDeclNode = new ASTNodeVariableDecl(varDeclNode->getVariableType(), "[" + std::to_string(i) + "]", varDeclNode->getCustomVariableTypeName(), varDeclNode->getOffset(), 1); ASTNodeVariableDecl *nonArrayVarDeclNode = new ASTNodeVariableDecl(varDeclNode->getVariableType(), "[" + std::to_string(i) + "]", varDeclNode->getCustomVariableTypeName(), varDeclNode->getOffset(), 1);
if (varDeclNode->getVariableType() == Token::TypeToken::Type::Padding) { if (varDeclNode->getVariableType() == Token::TypeToken::Type::Padding) {
return { new PatternDataPadding(offset, varDeclNode->getArraySize()), varDeclNode->getArraySize() }; return { new PatternDataPadding(offset, varDeclNode->getArraySize()), varDeclNode->getArraySize() };
} else if (varDeclNode->getVariableType() != Token::TypeToken::Type::CustomType) { } else if (varDeclNode->getVariableType() != Token::TypeToken::Type::CustomType) {
const auto &[pattern, size] = this->createBuiltInTypePattern(nonArrayVarDeclNode, offset + arrayOffset); const auto& [pattern, size] = this->createBuiltInTypePattern(nonArrayVarDeclNode, offset + arrayOffset);
if (pattern == nullptr) if (pattern == nullptr)
return { nullptr, 0 }; return { nullptr, 0 };
if (!arrayColor.has_value())
arrayColor = pattern->getColor();
pattern->setColor(arrayColor.value());
entries.push_back(pattern); entries.push_back(pattern);
arrayOffset += size; arrayOffset += size;
} else { } else {
@ -193,6 +227,11 @@ namespace hex::lang {
if (pattern == nullptr) if (pattern == nullptr)
return { nullptr, 0 }; return { nullptr, 0 };
if (!arrayColor.has_value())
arrayColor = pattern->getColor();
pattern->setColor(arrayColor.value());
entries.push_back(pattern); entries.push_back(pattern);
arrayOffset += size; arrayOffset += size;
} }

View File

@ -39,14 +39,22 @@ namespace hex::lang {
return new ASTNodeVariableDecl(curr[-6].typeToken.type, curr[-5].identifierToken.identifier, "", { }, curr[-3].integerToken.integer); return new ASTNodeVariableDecl(curr[-6].typeToken.type, curr[-5].identifierToken.identifier, "", { }, curr[-3].integerToken.integer);
} }
ASTNode* parsePaddingDecl(TokenIter &curr) {
return new ASTNodeVariableDecl(curr[-5].typeToken.type, "", "", { }, curr[-3].integerToken.integer);
}
ASTNode* parseCustomTypeArrayDecl(TokenIter &curr) { ASTNode* parseCustomTypeArrayDecl(TokenIter &curr) {
return new ASTNodeVariableDecl(Token::TypeToken::Type::CustomType, curr[-5].identifierToken.identifier, curr[-6].identifierToken.identifier, { }, curr[-3].integerToken.integer); return new ASTNodeVariableDecl(Token::TypeToken::Type::CustomType, curr[-5].identifierToken.identifier, curr[-6].identifierToken.identifier, { }, curr[-3].integerToken.integer);
} }
ASTNode* parseBuiltinVariableArrayDecl(TokenIter &curr) {
return new ASTNodeVariableDecl(curr[-6].typeToken.type, curr[-5].identifierToken.identifier, "", { }, 0, curr[-3].identifierToken.identifier);
}
ASTNode* parseCustomTypeVariableArrayDecl(TokenIter &curr) {
return new ASTNodeVariableDecl(Token::TypeToken::Type::CustomType, curr[-5].identifierToken.identifier, curr[-6].identifierToken.identifier, { }, 0, curr[-3].identifierToken.identifier);
}
ASTNode* parsePaddingDecl(TokenIter &curr) {
return new ASTNodeVariableDecl(curr[-5].typeToken.type, "", "", { }, curr[-3].integerToken.integer);
}
ASTNode* parseFreeBuiltinVariableDecl(TokenIter &curr) { ASTNode* parseFreeBuiltinVariableDecl(TokenIter &curr) {
return new ASTNodeVariableDecl(curr[-5].typeToken.type, curr[-4].identifierToken.identifier, "", curr[-2].integerToken.integer); return new ASTNodeVariableDecl(curr[-5].typeToken.type, curr[-4].identifierToken.identifier, "", curr[-2].integerToken.integer);
} }
@ -68,6 +76,10 @@ namespace hex::lang {
nodes.push_back(parseBuiltinArrayDecl(curr)); 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})) 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)); nodes.push_back(parseCustomTypeArrayDecl(curr));
else if (tryConsume(curr, {Token::Type::Type, Token::Type::Identifier, Token::Type::ArrayOpen, Token::Type::Identifier, Token::Type::ArrayClose, Token::Type::EndOfExpression}))
nodes.push_back(parseBuiltinVariableArrayDecl(curr));
else if (tryConsume(curr, {Token::Type::Identifier, Token::Type::Identifier, Token::Type::ArrayOpen, Token::Type::Identifier, Token::Type::ArrayClose, Token::Type::EndOfExpression}))
nodes.push_back(parseCustomTypeVariableArrayDecl(curr));
else if (tryConsume(curr, {Token::Type::Type, Token::Type::ArrayOpen, Token::Type::Integer, Token::Type::ArrayClose, Token::Type::EndOfExpression})) { else if (tryConsume(curr, {Token::Type::Type, Token::Type::ArrayOpen, Token::Type::Integer, Token::Type::ArrayClose, Token::Type::EndOfExpression})) {
if (curr[-5].typeToken.type != Token::TypeToken::Type::Padding) { if (curr[-5].typeToken.type != Token::TypeToken::Type::Padding) {
for(auto &node : nodes) delete node; for(auto &node : nodes) delete node;

View File

@ -21,6 +21,10 @@ namespace hex::lang {
auto varDeclNode = static_cast<ASTNodeVariableDecl*>(node); auto varDeclNode = static_cast<ASTNodeVariableDecl*>(node);
if (!typeNames.insert(varDeclNode->getVariableName()).second) if (!typeNames.insert(varDeclNode->getVariableName()).second)
return false; return false;
if (varDeclNode->getArraySize() == 0 && !varDeclNode->getArraySizeVariable().has_value() ||
varDeclNode->getArraySize() != 0 && varDeclNode->getArraySizeVariable().has_value())
return false;
} }
break; break;
case ASTNode::Type::TypeDecl: case ASTNode::Type::TypeDecl:

View File

@ -85,7 +85,7 @@ namespace hex {
magicFiles += entry.path().string() + MAGIC_PATH_SEPARATOR; magicFiles += entry.path().string() + MAGIC_PATH_SEPARATOR;
} }
std::vector<u8> buffer(this->m_dataProvider->getSize(), 0x00); std::vector<u8> buffer(std::min(this->m_dataProvider->getSize(), size_t(0xFF'FFFF)), 0x00);
this->m_dataProvider->read(0, buffer.data(), buffer.size()); this->m_dataProvider->read(0, buffer.data(), buffer.size());
std::string mimeType; std::string mimeType;
@ -172,7 +172,7 @@ namespace hex {
this->loadPatternFile(this->m_fileBrowser.selected_path); this->loadPatternFile(this->m_fileBrowser.selected_path);
} }
if (ImGui::BeginPopupModal("Accept Pattern", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove)) { if (ImGui::BeginPopupModal("Accept Pattern", nullptr, ImGuiWindowFlags_NoResize)) {
ImGui::TextUnformatted("A pattern compatible with this data type has been found:"); ImGui::TextUnformatted("A pattern compatible with this data type has been found:");
ImGui::Text("%ls", this->m_possiblePatternFile.filename().c_str()); ImGui::Text("%ls", this->m_possiblePatternFile.filename().c_str());
ImGui::NewLine(); ImGui::NewLine();
@ -241,7 +241,7 @@ namespace hex {
hex::lang::Lexer lexer; hex::lang::Lexer lexer;
hex::lang::Parser parser; hex::lang::Parser parser;
hex::lang::Validator validator; hex::lang::Validator validator;
hex::lang::Evaluator evaluator; hex::lang::Evaluator evaluator(this->m_dataProvider);
this->clearPatternData(); this->clearPatternData();
this->postEvent(Events::PatternChanged); this->postEvent(Events::PatternChanged);