1
0
mirror of synced 2025-01-18 17:14:13 +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 {
public:
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) { }
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), m_arraySizeVariable(arraySizeVariable) { }
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() const { return this->m_offset; }
size_t getArraySize() const { return this->m_arraySize; }
std::optional<std::string> getArraySizeVariable() const { return this->m_arraySizeVariable; }
private:
Token::TypeToken::Type m_type;
std::string m_name, m_customTypeName;
std::optional<u64> m_offset;
size_t m_arraySize;
std::optional<std::string> m_arraySizeVariable;
};
class ASTNodeScope : public ASTNode {

View File

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

View File

@ -50,9 +50,10 @@ namespace hex::lang {
[[nodiscard]] Type getPatternType() const { return this->m_type; }
[[nodiscard]] u64 getOffset() const { return this->m_offset; }
[[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]] 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 std::string getTypeName() = 0;

View File

@ -5,7 +5,7 @@
namespace hex::lang {
Evaluator::Evaluator() {
Evaluator::Evaluator(prv::Provider* &provider) : m_provider(provider) {
}
@ -52,6 +52,31 @@ namespace hex::lang {
members.push_back(pattern);
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) {
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::vector<PatternData*> entries;
auto arraySizeVariable = varDeclNode->getArraySizeVariable();
size_t arrayOffset = 0;
std::optional<u32> arrayColor;
for (u32 i = 0; i < varDeclNode->getArraySize(); i++) {
ASTNodeVariableDecl *nonArrayVarDeclNode = new ASTNodeVariableDecl(varDeclNode->getVariableType(), "[" + std::to_string(i) + "]", varDeclNode->getCustomVariableTypeName(), varDeclNode->getOffset(), 1);
if (varDeclNode->getVariableType() == Token::TypeToken::Type::Padding) {
return { new PatternDataPadding(offset, varDeclNode->getArraySize()), varDeclNode->getArraySize() };
} 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)
return { nullptr, 0 };
if (!arrayColor.has_value())
arrayColor = pattern->getColor();
pattern->setColor(arrayColor.value());
entries.push_back(pattern);
arrayOffset += size;
} else {
@ -193,6 +227,11 @@ namespace hex::lang {
if (pattern == nullptr)
return { nullptr, 0 };
if (!arrayColor.has_value())
arrayColor = pattern->getColor();
pattern->setColor(arrayColor.value());
entries.push_back(pattern);
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);
}
ASTNode* parsePaddingDecl(TokenIter &curr) {
return new ASTNodeVariableDecl(curr[-5].typeToken.type, "", "", { }, 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* 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) {
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));
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 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})) {
if (curr[-5].typeToken.type != Token::TypeToken::Type::Padding) {
for(auto &node : nodes) delete node;

View File

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

View File

@ -85,7 +85,7 @@ namespace hex {
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());
std::string mimeType;
@ -172,7 +172,7 @@ namespace hex {
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::Text("%ls", this->m_possiblePatternFile.filename().c_str());
ImGui::NewLine();
@ -241,7 +241,7 @@ namespace hex {
hex::lang::Lexer lexer;
hex::lang::Parser parser;
hex::lang::Validator validator;
hex::lang::Evaluator evaluator;
hex::lang::Evaluator evaluator(this->m_dataProvider);
this->clearPatternData();
this->postEvent(Events::PatternChanged);