mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-03-28 15:57:03 -05:00
Completely rewrite highlight and pattern evaluator
This commit is contained in:
@@ -4,11 +4,12 @@
|
||||
#include "lang/parser.hpp"
|
||||
#include "lang/lexer.hpp"
|
||||
#include "lang/validator.hpp"
|
||||
#include "lang/evaluator.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
namespace hex {
|
||||
|
||||
ViewPattern::ViewPattern(prv::Provider* &dataProvider, std::vector<hex::PatternData*> &patternData)
|
||||
ViewPattern::ViewPattern(prv::Provider* &dataProvider, std::vector<lang::PatternData*> &patternData)
|
||||
: View(), m_dataProvider(dataProvider), m_patternData(patternData) {
|
||||
|
||||
this->m_buffer = new char[0xFF'FFFF];
|
||||
@@ -84,16 +85,12 @@ namespace hex {
|
||||
}
|
||||
|
||||
|
||||
void ViewPattern::addPatternData(PatternData *patternData) {
|
||||
this->m_patternData.push_back(patternData);
|
||||
}
|
||||
|
||||
void ViewPattern::clearPatternData() {
|
||||
for (auto &data : this->m_patternData)
|
||||
delete data;
|
||||
|
||||
this->m_patternData.clear();
|
||||
PatternData::resetPalette();
|
||||
lang::PatternData::resetPalette();
|
||||
}
|
||||
|
||||
template<std::derived_from<lang::ASTNode> T>
|
||||
@@ -108,10 +105,11 @@ namespace hex {
|
||||
}
|
||||
|
||||
void ViewPattern::parsePattern(char *buffer) {
|
||||
static hex::lang::Preprocessor preprocessor;
|
||||
static hex::lang::Lexer lexer;
|
||||
static hex::lang::Parser parser;
|
||||
static hex::lang::Validator validator;
|
||||
hex::lang::Preprocessor preprocessor;
|
||||
hex::lang::Lexer lexer;
|
||||
hex::lang::Parser parser;
|
||||
hex::lang::Validator validator;
|
||||
hex::lang::Evaluator evaluator;
|
||||
|
||||
this->clearPatternData();
|
||||
this->postEvent(Events::PatternChanged);
|
||||
@@ -127,275 +125,23 @@ namespace hex {
|
||||
|
||||
auto [parseResult, ast] = parser.parse(tokens);
|
||||
if (parseResult.failed()) {
|
||||
for(auto &node : ast) delete node;
|
||||
return;
|
||||
}
|
||||
|
||||
hex::ScopeExit deleteAst([&ast]{ for(auto &node : ast) delete node; });
|
||||
|
||||
auto validatorResult = validator.validate(ast);
|
||||
if (!validatorResult) {
|
||||
for(auto &node : ast) delete node;
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto &varNode : findNodes<lang::ASTNodeVariableDecl>(lang::ASTNode::Type::VariableDecl, ast)) {
|
||||
if (!varNode->getOffset().has_value())
|
||||
continue;
|
||||
|
||||
u64 offset = varNode->getOffset().value();
|
||||
if (varNode->getVariableType() != lang::Token::TypeToken::Type::CustomType) {
|
||||
size_t size = getTypeSize(varNode->getVariableType()) * varNode->getArraySize();
|
||||
|
||||
if (isUnsigned(varNode->getVariableType()))
|
||||
this->addPatternData(new PatternDataUnsigned(offset, size, varNode->getVariableName()));
|
||||
else if (isSigned(varNode->getVariableType())) {
|
||||
if (getTypeSize(varNode->getVariableType()) == 1 && varNode->getArraySize() == 1)
|
||||
this->addPatternData(new PatternDataCharacter(offset, size, varNode->getVariableName()));
|
||||
else if (getTypeSize(varNode->getVariableType()) == 1 && varNode->getArraySize() > 1)
|
||||
this->addPatternData(new PatternDataString(offset, size, varNode->getVariableName()));
|
||||
else
|
||||
this->addPatternData(new PatternDataSigned(offset, size, varNode->getVariableName()));
|
||||
}
|
||||
else if (isFloatingPoint(varNode->getVariableType()))
|
||||
this->addPatternData(new PatternDataFloat(offset, size, varNode->getVariableName()));
|
||||
} else {
|
||||
for (auto &structNode : findNodes<lang::ASTNodeStruct>(lang::ASTNode::Type::Struct, ast)) {
|
||||
if (varNode->getCustomVariableTypeName() == structNode->getName()) {
|
||||
for (u32 i = 0; i < varNode->getArraySize(); i++) {
|
||||
std::string name = varNode->getVariableName();
|
||||
if (varNode->getArraySize() > 1)
|
||||
name += "[" + std::to_string(varNode->getArraySize()) + "]";
|
||||
|
||||
if (size_t size = this->highlightStruct(ast, structNode, offset, name); size == -1)
|
||||
this->clearPatternData();
|
||||
else
|
||||
offset += size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &enumNode : findNodes<lang::ASTNodeEnum>(lang::ASTNode::Type::Enum, ast)) {
|
||||
if (varNode->getCustomVariableTypeName() == enumNode->getName()) {
|
||||
for (u32 i = 0; i < varNode->getArraySize(); i++) {
|
||||
std::string name = varNode->getVariableName();
|
||||
if (varNode->getArraySize() > 1)
|
||||
name += "[" + std::to_string(varNode->getArraySize()) + "]";
|
||||
|
||||
if (size_t size = this->highlightEnum(ast, enumNode, offset, name); size == -1)
|
||||
this->clearPatternData();
|
||||
else
|
||||
offset += size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &usingNode : findNodes<lang::ASTNodeTypeDecl>(lang::ASTNode::Type::TypeDecl, ast)) {
|
||||
if (varNode->getCustomVariableTypeName() == usingNode->getTypeName()) {
|
||||
for (u32 i = 0; i < varNode->getArraySize(); i++) {
|
||||
std::string name = varNode->getVariableName();
|
||||
if (varNode->getArraySize() > 1)
|
||||
name += "[" + std::to_string(varNode->getArraySize()) + "]";
|
||||
|
||||
if (size_t size = this->highlightUsingDecls(ast, usingNode, varNode, offset, name); size == -1)
|
||||
this->clearPatternData();
|
||||
else
|
||||
offset += size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto [evaluateResult, patternData] = evaluator.evaluate(ast);
|
||||
if (evaluateResult.failed()) {
|
||||
return;
|
||||
}
|
||||
this->m_patternData = patternData;
|
||||
|
||||
for(auto &node : ast) delete node;
|
||||
this->postEvent(Events::PatternChanged);
|
||||
}
|
||||
|
||||
s32 ViewPattern::highlightUsingDecls(std::vector<lang::ASTNode*> &ast, lang::ASTNodeTypeDecl* currTypeDeclNode, lang::ASTNodeVariableDecl* currVarDecl, u64 offset, std::string name) {
|
||||
u64 startOffset = offset;
|
||||
|
||||
if (currTypeDeclNode->getAssignedType() != lang::Token::TypeToken::Type::CustomType) {
|
||||
size_t size = (static_cast<u32>(currTypeDeclNode->getAssignedType()) >> 4);
|
||||
|
||||
if (isUnsigned(currTypeDeclNode->getAssignedType()))
|
||||
this->addPatternData(new PatternDataUnsigned(offset, size, name));
|
||||
else if (isSigned(currTypeDeclNode->getAssignedType()))
|
||||
this->addPatternData(new PatternDataSigned(offset, size, name));
|
||||
else if (isFloatingPoint(currTypeDeclNode->getAssignedType()))
|
||||
this->addPatternData(new PatternDataFloat(offset, size, name));
|
||||
|
||||
offset += size;
|
||||
} else {
|
||||
bool foundType = false;
|
||||
for (auto &structNode : findNodes<lang::ASTNodeStruct>(lang::ASTNode::Type::Struct, ast)) {
|
||||
if (structNode->getName() == currTypeDeclNode->getAssignedCustomTypeName()) {
|
||||
for (size_t i = 0; i < currVarDecl->getArraySize(); i++) {
|
||||
size_t size = this->highlightStruct(ast, structNode, offset, name);
|
||||
|
||||
if (size == -1)
|
||||
return -1;
|
||||
|
||||
offset += size;
|
||||
}
|
||||
|
||||
foundType = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &enumNode : findNodes<lang::ASTNodeEnum>(lang::ASTNode::Type::Enum, ast)) {
|
||||
if (enumNode->getName() == currTypeDeclNode->getAssignedCustomTypeName()) {
|
||||
for (size_t i = 0; i < currVarDecl->getArraySize(); i++) {
|
||||
size_t size = this->highlightEnum(ast, enumNode, offset, name);
|
||||
|
||||
if (size == -1)
|
||||
return -1;
|
||||
|
||||
offset += size;
|
||||
}
|
||||
|
||||
foundType = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (auto &typeDeclNode : findNodes<lang::ASTNodeTypeDecl>(lang::ASTNode::Type::TypeDecl, ast)) {
|
||||
if (typeDeclNode->getTypeName() == currTypeDeclNode->getAssignedCustomTypeName()) {
|
||||
for (size_t i = 0; i < currVarDecl->getArraySize(); i++) {
|
||||
size_t size = this->highlightUsingDecls(ast, typeDeclNode, currVarDecl, offset, name);
|
||||
|
||||
if (size == -1)
|
||||
return -1;
|
||||
|
||||
offset += size;
|
||||
}
|
||||
|
||||
foundType = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundType)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return offset - startOffset;
|
||||
}
|
||||
|
||||
s32 ViewPattern::highlightStruct(std::vector<lang::ASTNode*> &ast, lang::ASTNodeStruct* currStructNode, u64 offset, std::string name) {
|
||||
u64 startOffset = offset;
|
||||
|
||||
for (auto &node : currStructNode->getNodes()) {
|
||||
auto varNode = static_cast<lang::ASTNodeVariableDecl*>(node);
|
||||
|
||||
if (varNode->getVariableType() != lang::Token::TypeToken::Type::CustomType) {
|
||||
size_t size = (static_cast<u32>(varNode->getVariableType()) >> 4);
|
||||
for (size_t i = 0; i < varNode->getArraySize(); i++) {
|
||||
std::string memberName = name + "." + varNode->getVariableName();
|
||||
if (varNode->getArraySize() > 1)
|
||||
memberName += "[" + std::to_string(i) + "]";
|
||||
|
||||
if (isUnsigned(varNode->getVariableType()))
|
||||
this->addPatternData(new PatternDataUnsigned(offset, size, memberName));
|
||||
else if (isSigned(varNode->getVariableType())) {
|
||||
if (getTypeSize(varNode->getVariableType()) == 1 && varNode->getArraySize() == 1)
|
||||
this->addPatternData(new PatternDataCharacter(offset, size, memberName));
|
||||
else if (getTypeSize(varNode->getVariableType()) == 1 && varNode->getArraySize() > 1) {
|
||||
this->addPatternData(new PatternDataString(offset, size * varNode->getArraySize(), name + "." + varNode->getVariableName()));
|
||||
offset += size * varNode->getArraySize();
|
||||
break;
|
||||
}
|
||||
else
|
||||
this->addPatternData(new PatternDataSigned(offset, size, memberName));
|
||||
}
|
||||
else if (isFloatingPoint(varNode->getVariableType()))
|
||||
this->addPatternData(new PatternDataFloat(offset, size, memberName));
|
||||
|
||||
offset += size;
|
||||
}
|
||||
} else {
|
||||
bool foundType = false;
|
||||
for (auto &structNode : findNodes<lang::ASTNodeStruct>(lang::ASTNode::Type::Struct, ast)) {
|
||||
if (structNode->getName() == varNode->getCustomVariableTypeName()) {
|
||||
for (size_t i = 0; i < varNode->getArraySize(); i++) {
|
||||
std::string memberName = name + "." + varNode->getVariableName();
|
||||
if (varNode->getArraySize() > 1)
|
||||
memberName += "[" + std::to_string(i) + "]";
|
||||
|
||||
size_t size = this->highlightStruct(ast, structNode, offset, memberName);
|
||||
|
||||
if (size == -1)
|
||||
return -1;
|
||||
|
||||
offset += size;
|
||||
}
|
||||
|
||||
foundType = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &enumNode : findNodes<lang::ASTNodeEnum>(lang::ASTNode::Type::Enum, ast)) {
|
||||
if (enumNode->getName() == varNode->getCustomVariableTypeName()) {
|
||||
for (size_t i = 0; i < varNode->getArraySize(); i++) {
|
||||
std::string memberName = name + "." + varNode->getVariableName();
|
||||
if (varNode->getArraySize() > 1)
|
||||
memberName += "[" + std::to_string(i) + "]";
|
||||
|
||||
size_t size = this->highlightEnum(ast, enumNode, offset, memberName);
|
||||
|
||||
if (size == -1)
|
||||
return -1;
|
||||
|
||||
offset += size;
|
||||
}
|
||||
|
||||
foundType = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &typeDeclNode : findNodes<lang::ASTNodeTypeDecl>(lang::ASTNode::Type::TypeDecl, ast)) {
|
||||
if (typeDeclNode->getTypeName() == varNode->getCustomVariableTypeName()) {
|
||||
for (size_t i = 0; i < varNode->getArraySize(); i++) {
|
||||
std::string memberName = name + "." + varNode->getVariableName();
|
||||
if (varNode->getArraySize() > 1)
|
||||
memberName += "[" + std::to_string(i) + "]";
|
||||
|
||||
size_t size = this->highlightUsingDecls(ast, typeDeclNode, varNode, offset, memberName);
|
||||
|
||||
if (size == -1)
|
||||
return -1;
|
||||
|
||||
offset += size;
|
||||
}
|
||||
|
||||
foundType = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundType)
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return offset - startOffset;
|
||||
}
|
||||
|
||||
s32 ViewPattern::highlightEnum(std::vector<lang::ASTNode*> &ast, lang::ASTNodeEnum* currEnumNode, u64 offset, std::string name) {
|
||||
if (!isUnsigned(currEnumNode->getUnderlyingType()))
|
||||
return -1;
|
||||
|
||||
s32 size = static_cast<u32>(currEnumNode->getUnderlyingType()) >> 4;
|
||||
|
||||
if (size > 8)
|
||||
return -1;
|
||||
|
||||
this->addPatternData(new PatternDataEnum(offset, size, name, currEnumNode->getName(), currEnumNode->getValues()));
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user