mirror of https://github.com/WerWolv/ImHex
Add "global variables" which will get displayed in the hex editor
This commit is contained in:
parent
f47ff5633b
commit
73f83dc01a
|
|
@ -8,10 +8,10 @@ using u32 = std::uint32_t;
|
||||||
using u64 = std::uint64_t;
|
using u64 = std::uint64_t;
|
||||||
using u128 = __uint128_t;
|
using u128 = __uint128_t;
|
||||||
|
|
||||||
using s8 = std::int8_t;
|
using s8 = std::int8_t;
|
||||||
using s16 = std::int16_t;
|
using s16 = std::int16_t;
|
||||||
using s32 = std::int32_t;
|
using s32 = std::int32_t;
|
||||||
using s64 = std::int64_t;
|
using s64 = std::int64_t;
|
||||||
using s128 = __int128_t;
|
using s128 = __int128_t;
|
||||||
|
|
||||||
#include "parser/result.hpp"
|
#include "parser/result.hpp"
|
||||||
|
|
|
||||||
|
|
@ -27,16 +27,19 @@ 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 = "")
|
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) { }
|
: ASTNode(Type::VariableDecl), m_type(type), m_name(name), m_customTypeName(customTypeName), m_offset(offset) { }
|
||||||
|
|
||||||
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() { return this->m_offset; };
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ASTNodeScope : public ASTNode {
|
class ASTNodeScope : public ASTNode {
|
||||||
|
|
@ -50,16 +53,14 @@ namespace hex::lang {
|
||||||
|
|
||||||
class ASTNodeStruct : public ASTNode {
|
class ASTNodeStruct : public ASTNode {
|
||||||
public:
|
public:
|
||||||
explicit ASTNodeStruct(std::string name, std::vector<ASTNode*> nodes, std::optional<u64> offset = { })
|
explicit ASTNodeStruct(std::string name, std::vector<ASTNode*> nodes)
|
||||||
: ASTNode(Type::Struct), m_name(name), m_nodes(nodes), m_offset(offset) { }
|
: ASTNode(Type::Struct), m_name(name), m_nodes(nodes) { }
|
||||||
|
|
||||||
const std::string& getName() const { return this->m_name; }
|
const std::string& getName() const { return this->m_name; }
|
||||||
std::vector<ASTNode*> &getNodes() { return this->m_nodes; }
|
std::vector<ASTNode*> &getNodes() { return this->m_nodes; }
|
||||||
std::optional<u64> getOffset() { return this->m_offset; };
|
|
||||||
private:
|
private:
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
std::vector<ASTNode*> m_nodes;
|
std::vector<ASTNode*> m_nodes;
|
||||||
std::optional<u64> m_offset;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ASTNodeTypeDecl : public ASTNode {
|
class ASTNodeTypeDecl : public ASTNode {
|
||||||
|
|
|
||||||
|
|
@ -49,14 +49,25 @@ namespace hex {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto &varNode : _this->findNodes<lang::ASTNodeVariableDecl>(lang::ASTNode::Type::VariableDecl, ast)) {
|
||||||
for (auto &structNode : _this->findNodes<lang::ASTNodeStruct>(lang::ASTNode::Type::Struct, ast)) {
|
if (!varNode->getOffset().has_value())
|
||||||
if (!structNode->getOffset().has_value())
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
u64 offset = structNode->getOffset().value();
|
u64 offset = varNode->getOffset().value();
|
||||||
if (_this->highlightStruct(ast, structNode, offset) == -1)
|
if (varNode->getVariableType() != lang::Token::TypeToken::Type::CustomType) {
|
||||||
_this->m_hexEditor->clearHighlights();
|
_this->m_hexEditor->setHighlight(offset, static_cast<u32>(varNode->getVariableType()) >> 4);
|
||||||
|
} else {
|
||||||
|
for (auto &structNode : _this->findNodes<lang::ASTNodeStruct>(lang::ASTNode::Type::Struct, ast))
|
||||||
|
if (varNode->getCustomVariableTypeName() == structNode->getName())
|
||||||
|
if (_this->highlightStruct(ast, structNode, offset) == -1)
|
||||||
|
_this->m_hexEditor->clearHighlights();
|
||||||
|
|
||||||
|
for (auto &usingNode : _this->findNodes<lang::ASTNodeTypeDecl>(lang::ASTNode::Type::TypeDecl, ast))
|
||||||
|
if (varNode->getCustomVariableTypeName() == usingNode->getTypeName())
|
||||||
|
if (_this->highlightUsingDecls(ast, usingNode, offset) == -1)
|
||||||
|
_this->m_hexEditor->clearHighlights();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto &node : ast) delete node;
|
for(auto &node : ast) delete node;
|
||||||
|
|
@ -145,7 +156,7 @@ namespace hex {
|
||||||
if (size == -1)
|
if (size == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
offset += size;
|
offset = size;
|
||||||
foundType = true;
|
foundType = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,9 +56,9 @@ namespace hex::lang {
|
||||||
if (isdigit(c))
|
if (isdigit(c))
|
||||||
integer += (c - '0');
|
integer += (c - '0');
|
||||||
else if (c >= 'A' && c <= 'F')
|
else if (c >= 'A' && c <= 'F')
|
||||||
integer += (c - 'A');
|
integer += 10 + (c - 'A');
|
||||||
else if (c >= 'a' && c <= 'f')
|
else if (c >= 'a' && c <= 'f')
|
||||||
integer += (c - 'a');
|
integer += 10 + (c - 'a');
|
||||||
else return { };
|
else return { };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -138,7 +138,7 @@ namespace hex::lang {
|
||||||
char *end = nullptr;
|
char *end = nullptr;
|
||||||
std::strtoull(&code[offset], &end, 0);
|
std::strtoull(&code[offset], &end, 0);
|
||||||
|
|
||||||
auto integer = parseInt(std::string_view(&code[offset], end));// matchTillInvalid(&code[offset], [](char c) -> bool { return std::isdigit(c); });
|
auto integer = parseInt(std::string_view(&code[offset], end));
|
||||||
|
|
||||||
if (!integer.has_value())
|
if (!integer.has_value())
|
||||||
return { ResultLexicalError, {}};
|
return { ResultLexicalError, {}};
|
||||||
|
|
|
||||||
|
|
@ -35,10 +35,17 @@ namespace hex::lang {
|
||||||
return new ASTNodeVariableDecl(Token::TypeToken::Type::CustomType, curr[-2].identifierToken.identifier, curr[-3].identifierToken.identifier);
|
return new ASTNodeVariableDecl(Token::TypeToken::Type::CustomType, curr[-2].identifierToken.identifier, curr[-3].identifierToken.identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ASTNode* parseFreeBuiltinVariableDecl(TokenIter &curr) {
|
||||||
|
return new ASTNodeVariableDecl(curr[-5].typeToken.type, curr[-4].identifierToken.identifier, "", curr[-2].integerToken.integer);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASTNode* parseFreeCustomTypeVariableDecl(TokenIter &curr) {
|
||||||
|
return new ASTNodeVariableDecl(Token::TypeToken::Type::CustomType, curr[-4].identifierToken.identifier, curr[-5].identifierToken.identifier, curr[-2].integerToken.integer);
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<ASTNode*> parseStruct(TokenIter &curr) {
|
std::optional<ASTNode*> parseStruct(TokenIter &curr) {
|
||||||
const std::string &structName = curr[-2].identifierToken.identifier;
|
const std::string &structName = curr[-2].identifierToken.identifier;
|
||||||
std::vector<ASTNode*> nodes;
|
std::vector<ASTNode*> nodes;
|
||||||
std::optional<u64> offset = { };
|
|
||||||
|
|
||||||
while (!tryConsume(curr, {Token::Type::ScopeClose})) {
|
while (!tryConsume(curr, {Token::Type::ScopeClose})) {
|
||||||
if (tryConsume(curr, {Token::Type::Type, Token::Type::Identifier, Token::Type::EndOfExpression}))
|
if (tryConsume(curr, {Token::Type::Type, Token::Type::Identifier, Token::Type::EndOfExpression}))
|
||||||
|
|
@ -48,26 +55,12 @@ namespace hex::lang {
|
||||||
else break;
|
else break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tryConsume(curr, {Token::Type::Operator})) {
|
|
||||||
if (curr[-1].operatorToken.op == Token::OperatorToken::Operator::AtDeclaration) {
|
|
||||||
if (tryConsume(curr, {Token::Type::Integer})) {
|
|
||||||
offset = curr[-1].integerToken.integer;
|
|
||||||
} else {
|
|
||||||
for(auto &node : nodes) delete node;
|
|
||||||
return { };
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for(auto &node : nodes) delete node;
|
|
||||||
return { };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!tryConsume(curr, {Token::Type::EndOfExpression})) {
|
if (!tryConsume(curr, {Token::Type::EndOfExpression})) {
|
||||||
for(auto &node : nodes) delete node;
|
for(auto &node : nodes) delete node;
|
||||||
return { };
|
return { };
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ASTNodeStruct(structName, nodes, offset);
|
return new ASTNodeStruct(structName, nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTNode *parseScope(TokenIter &curr) {
|
ASTNode *parseScope(TokenIter &curr) {
|
||||||
|
|
@ -101,6 +94,7 @@ namespace hex::lang {
|
||||||
std::optional<std::vector<ASTNode*>> parseStatement(TokenIter &curr) {
|
std::optional<std::vector<ASTNode*>> parseStatement(TokenIter &curr) {
|
||||||
std::vector<ASTNode*> program;
|
std::vector<ASTNode*> program;
|
||||||
|
|
||||||
|
// Struct
|
||||||
if (tryConsume(curr, { Token::Type::Keyword, Token::Type::Identifier, Token::Type::ScopeOpen })) {
|
if (tryConsume(curr, { Token::Type::Keyword, Token::Type::Identifier, Token::Type::ScopeOpen })) {
|
||||||
if (curr[-3].keywordToken.keyword == Token::KeywordToken::Keyword::Struct) {
|
if (curr[-3].keywordToken.keyword == Token::KeywordToken::Keyword::Struct) {
|
||||||
auto structAst = parseStruct(curr);
|
auto structAst = parseStruct(curr);
|
||||||
|
|
@ -114,10 +108,14 @@ namespace hex::lang {
|
||||||
}
|
}
|
||||||
|
|
||||||
return program;
|
return program;
|
||||||
|
|
||||||
|
// Scope
|
||||||
} else if (tryConsume(curr, { Token::Type::ScopeOpen })) {
|
} else if (tryConsume(curr, { Token::Type::ScopeOpen })) {
|
||||||
program.push_back(parseScope(curr));
|
program.push_back(parseScope(curr));
|
||||||
|
|
||||||
return program;
|
return program;
|
||||||
|
|
||||||
|
// Using declaration with built-in type
|
||||||
} else if (tryConsume(curr, { Token::Type::Keyword, Token::Type::Identifier, Token::Type::Operator, Token::Type::Type, Token::Type::EndOfExpression})) {
|
} else if (tryConsume(curr, { Token::Type::Keyword, Token::Type::Identifier, Token::Type::Operator, Token::Type::Type, Token::Type::EndOfExpression})) {
|
||||||
auto usingDecl = parseUsingDeclaration(curr);
|
auto usingDecl = parseUsingDeclaration(curr);
|
||||||
|
|
||||||
|
|
@ -129,6 +127,8 @@ namespace hex::lang {
|
||||||
program.push_back(usingDecl.value());
|
program.push_back(usingDecl.value());
|
||||||
|
|
||||||
return program;
|
return program;
|
||||||
|
|
||||||
|
// Using declaration with custom type
|
||||||
} else if (tryConsume(curr, { Token::Type::Keyword, Token::Type::Identifier, Token::Type::Operator, Token::Type::Identifier, Token::Type::EndOfExpression})) {
|
} else if (tryConsume(curr, { Token::Type::Keyword, Token::Type::Identifier, Token::Type::Operator, Token::Type::Identifier, Token::Type::EndOfExpression})) {
|
||||||
auto usingDecl = parseUsingDeclaration(curr);
|
auto usingDecl = parseUsingDeclaration(curr);
|
||||||
|
|
||||||
|
|
@ -139,6 +139,21 @@ namespace hex::lang {
|
||||||
|
|
||||||
program.push_back(usingDecl.value());
|
program.push_back(usingDecl.value());
|
||||||
|
|
||||||
|
return program;
|
||||||
|
// Variable declaration with built-in type
|
||||||
|
} else if (tryConsume(curr, { Token::Type::Type, Token::Type::Identifier, Token::Type::Operator, Token::Type::Integer, Token::Type::EndOfExpression})) {
|
||||||
|
auto variableDecl = parseFreeBuiltinVariableDecl(curr);
|
||||||
|
|
||||||
|
program.push_back(variableDecl);
|
||||||
|
|
||||||
|
return program;
|
||||||
|
|
||||||
|
// Variable declaration with custom type
|
||||||
|
} else if (tryConsume(curr, { Token::Type::Identifier, Token::Type::Identifier, Token::Type::Operator, Token::Type::Integer, Token::Type::EndOfExpression})) {
|
||||||
|
auto variableDecl = parseFreeCustomTypeVariableDecl(curr);
|
||||||
|
|
||||||
|
program.push_back(variableDecl);
|
||||||
|
|
||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue