1
0
mirror of synced 2024-09-24 19:48:25 +02:00

Added simple pointer type inside structs

This commit is contained in:
WerWolv 2020-11-21 23:00:09 +01:00
parent ed4ed6b433
commit 0ce1b5d40b
6 changed files with 154 additions and 70 deletions

View File

@ -31,8 +31,8 @@ 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, 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) { }
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 = { }, std::optional<u8> pointerSize = { })
: ASTNode(Type::VariableDecl), m_type(type), m_name(name), m_customTypeName(customTypeName), m_offset(offset), m_arraySize(arraySize), m_arraySizeVariable(arraySizeVariable), m_pointerSize(pointerSize) { }
const Token::TypeToken::Type& getVariableType() const { return this->m_type; }
const std::string& getCustomVariableTypeName() const { return this->m_customTypeName; }
@ -40,6 +40,7 @@ namespace hex::lang {
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; }
std::optional<u8> getPointerSize() const { return this->m_pointerSize; }
private:
Token::TypeToken::Type m_type;
@ -47,6 +48,7 @@ namespace hex::lang {
std::optional<u64> m_offset;
size_t m_arraySize;
std::optional<std::string> m_arraySizeVariable;
std::optional<u8> m_pointerSize;
};
class ASTNodeScope : public ASTNode {

View File

@ -50,7 +50,9 @@ 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; }
void setName(std::string name) { this->m_name = name; }
[[nodiscard]] u32 getColor() const { return this->m_color; }
void setColor(u32 color) { this->m_color = color; }
@ -157,6 +159,55 @@ namespace hex::lang {
}
};
class PatternDataPointer : public PatternData {
public:
PatternDataPointer(u64 offset, size_t size, const std::string &name, PatternData *pointedAt, u32 color = 0)
: PatternData(Type::Unsigned, offset, size, name, color), m_pointedAt(pointedAt) {
this->m_pointedAt->setName("*" + this->m_pointedAt->getName());
}
void createEntry(prv::Provider* &provider) override {
u64 data = 0;
provider->read(this->getOffset(), &data, this->getSize());
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
ImGui::TableNextColumn();
ImGui::ColorButton("color", ImColor(this->getColor()), ImGuiColorEditFlags_NoTooltip);
ImGui::TableNextColumn();
bool open = ImGui::TreeNodeEx(this->getName().c_str(), ImGuiTreeNodeFlags_SpanFullWidth);
ImGui::TableNextColumn();
ImGui::Text("0x%08lx : 0x%08lx", this->getOffset(), this->getOffset() + this->getSize() - 1);
ImGui::TableNextColumn();
ImGui::Text("0x%04lx", this->getSize());
ImGui::TableNextColumn();
ImGui::Text("%s", this->getTypeName().c_str());
ImGui::TableNextColumn();
ImGui::Text("*(%08llx)", data);
if (open) {
this->m_pointedAt->createEntry(provider);
ImGui::TreePop();
}
}
virtual std::optional<u32> highlightBytes(size_t offset) {
if (offset >= this->getOffset() && offset < (this->getOffset() + this->getSize()))
return this->getColor();
else if (auto color = this->m_pointedAt->highlightBytes(offset); color.has_value())
return color.value();
else
return { };
}
std::string getTypeName() override {
return "Pointer";
}
private:
PatternData *m_pointedAt;
};
class PatternDataUnsigned : public PatternData {
public:
PatternDataUnsigned(u64 offset, size_t size, const std::string &name, u32 color = 0) : PatternData(Type::Unsigned, offset, size, name, color) { }

View File

@ -38,7 +38,8 @@ namespace hex::lang {
enum class Operator {
AtDeclaration,
Assignment,
Inherit
Inherit,
Star
} op;
} operatorToken;
struct IntegerToken {

View File

@ -21,36 +21,28 @@ namespace hex::lang {
for (const auto &node : structNode->getNodes()) {
const auto &member = static_cast<ASTNodeVariableDecl*>(node);
u64 memberOffset = 0;
if (member->getPointerSize().has_value())
this->m_provider->read(offset + structSize, &memberOffset, member->getPointerSize().value());
else
memberOffset = offset + structSize;
const auto typeDeclNode = static_cast<ASTNodeTypeDecl*>(this->m_types[member->getCustomVariableTypeName()]);
PatternData *pattern = nullptr;
u64 memberSize = 0;
if (member->getVariableType() == Token::TypeToken::Type::Signed8Bit && member->getArraySize() > 1) {
const auto &[pattern, size] = this->createStringPattern(member, offset + structSize);
if (pattern == nullptr)
return { nullptr, 0 };
members.push_back(pattern);
structSize += size;
std::tie(pattern, memberSize) = this->createStringPattern(member, memberOffset);
} else if (member->getVariableType() == Token::TypeToken::Type::CustomType
&& typeDeclNode != nullptr && typeDeclNode->getAssignedType() == Token::TypeToken::Type::Signed8Bit
&& member->getArraySize() > 1) {
const auto &[pattern, size] = this->createStringPattern(member, offset + structSize);
if (pattern == nullptr)
return { nullptr, 0 };
members.push_back(pattern);
structSize += size;
std::tie(pattern, memberSize) = this->createStringPattern(member, memberOffset);
}
else if (member->getArraySize() > 1) {
const auto &[pattern, size] = this->createArrayPattern(member, offset + structSize);
if (pattern == nullptr)
return { nullptr, 0 };
members.push_back(pattern);
structSize += size;
std::tie(pattern, memberSize) = this->createArrayPattern(member, memberOffset);
}
else if (member->getArraySizeVariable().has_value()) {
std::optional<size_t> arraySize;
@ -69,31 +61,25 @@ namespace hex::lang {
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;
std::tie(pattern, memberSize) = this->createArrayPattern(processedMember, memberOffset);
}
else if (member->getVariableType() != Token::TypeToken::Type::CustomType) {
const auto &[pattern, size] = this->createBuiltInTypePattern(member, offset + structSize);
if (pattern == nullptr)
return { nullptr, 0 };
members.push_back(pattern);
structSize += size;
std::tie(pattern, memberSize) = this->createBuiltInTypePattern(member, memberOffset);
}
else {
const auto &[pattern, size] = this->createCustomTypePattern(member, offset + structSize);
std::tie(pattern, memberSize) = this->createCustomTypePattern(member, memberOffset);
}
if (pattern == nullptr)
return { nullptr, 0 };
if (pattern == nullptr)
return { nullptr, 0 };
if (member->getPointerSize().has_value()) {
members.push_back(new PatternDataPointer(offset + structSize, member->getPointerSize().value(), member->getVariableName(), pattern));
structSize += member->getPointerSize().value();
}
else {
members.push_back(pattern);
structSize += size;
structSize += memberSize;
}
}
@ -112,54 +98,68 @@ namespace hex::lang {
for (const auto &node : unionNode->getNodes()) {
const auto &member = static_cast<ASTNodeVariableDecl*>(node);
u64 memberOffset = 0;
if (member->getPointerSize().has_value())
this->m_provider->read(offset + unionSize, &memberOffset, member->getPointerSize().value());
else
memberOffset = offset;
const auto typeDeclNode = static_cast<ASTNodeTypeDecl*>(this->m_types[member->getCustomVariableTypeName()]);
PatternData *pattern = nullptr;
u64 memberSize = 0;
if (member->getVariableType() == Token::TypeToken::Type::Signed8Bit && member->getArraySize() > 1) {
const auto &[pattern, size] = this->createStringPattern(member, offset);
std::tie(pattern, memberSize) = this->createStringPattern(member, memberOffset);
if (pattern == nullptr)
return { nullptr, 0 };
members.push_back(pattern);
unionSize = std::max(size, unionSize);
} else if (member->getVariableType() == Token::TypeToken::Type::CustomType
&& typeDeclNode != nullptr && typeDeclNode->getAssignedType() == Token::TypeToken::Type::Signed8Bit
&& member->getArraySize() > 1) {
const auto &[pattern, size] = this->createStringPattern(member, offset);
std::tie(pattern, memberSize) = this->createStringPattern(member, memberOffset);
if (pattern == nullptr)
return { nullptr, 0 };
members.push_back(pattern);
unionSize = std::max(size, unionSize);
}
else if (member->getArraySize() > 1) {
const auto &[pattern, size] = this->createArrayPattern(member, offset);
std::tie(pattern, memberSize) = this->createArrayPattern(member, memberOffset);
if (pattern == nullptr)
}
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 };
members.push_back(pattern);
unionSize = std::max(size, unionSize);
ASTNodeVariableDecl *processedMember = new ASTNodeVariableDecl(member->getVariableType(), member->getVariableName(), member->getCustomVariableTypeName(), member->getOffset(), arraySize.value());
std::tie(pattern, memberSize) = this->createArrayPattern(processedMember, memberOffset);
}
else if (member->getVariableType() != Token::TypeToken::Type::CustomType) {
const auto &[pattern, size] = this->createBuiltInTypePattern(member, offset);
if (pattern == nullptr)
return { nullptr, 0 };
members.push_back(pattern);
unionSize = std::max(size, unionSize);
std::tie(pattern, memberSize) = this->createBuiltInTypePattern(member, memberOffset);
}
else {
const auto &[pattern, size] = this->createCustomTypePattern(member, offset);
std::tie(pattern, memberSize) = this->createCustomTypePattern(member, memberOffset);
}
if (pattern == nullptr)
return { nullptr, 0 };
if (pattern == nullptr)
return { nullptr, 0 };
if (member->getPointerSize().has_value()) {
members.push_back(new PatternDataPointer(offset, member->getPointerSize().value(), member->getVariableName(), pattern));
unionSize = std::max(size_t(member->getPointerSize().value()), unionSize);
}
else {
members.push_back(pattern);
unionSize = std::max(size, unionSize);
unionSize = std::max(memberSize, unionSize);
}
}

View File

@ -128,6 +128,9 @@ namespace hex::lang {
} else if (c == ':') {
tokens.push_back({ .type = Token::Type::Operator, .operatorToken = { .op = Token::OperatorToken::Operator::Inherit } });
offset += 1;
} else if (c == '*') {
tokens.push_back({ .type = Token::Type::Operator, .operatorToken = { .op = Token::OperatorToken::Operator::Star } });
offset += 1;
} else if (std::isalpha(c)) {
std::string identifier = matchTillInvalid(&code[offset], [](char c) -> bool { return std::isalnum(c) || c == '_'; });

View File

@ -1,5 +1,7 @@
#include "lang/parser.hpp"
#include "utils.hpp"
#include <optional>
namespace hex::lang {
@ -35,6 +37,24 @@ namespace hex::lang {
return new ASTNodeVariableDecl(Token::TypeToken::Type::CustomType, curr[-2].identifierToken.identifier, curr[-3].identifierToken.identifier);
}
ASTNode* parseBuiltinPointerVariableDecl(TokenIter &curr) {
auto pointerType = curr[-2].typeToken.type;
if (!isUnsigned(pointerType) || curr[-5].operatorToken.op != Token::OperatorToken::Operator::Star || curr[-3].operatorToken.op != Token::OperatorToken::Operator::Inherit)
return nullptr;
return new ASTNodeVariableDecl(curr[-6].typeToken.type, curr[-4].identifierToken.identifier, "", { }, 1, { }, getTypeSize(pointerType));
}
ASTNode* parseCustomTypePointerVariableDecl(TokenIter &curr) {
auto pointerType = curr[-2].typeToken.type;
if (!isUnsigned(pointerType) || curr[-5].operatorToken.op != Token::OperatorToken::Operator::Star || curr[-3].operatorToken.op != Token::OperatorToken::Operator::Inherit)
return nullptr;
return new ASTNodeVariableDecl(Token::TypeToken::Type::CustomType, curr[-4].identifierToken.identifier, curr[-6].identifierToken.identifier, { }, 1, { }, getTypeSize(pointerType));
}
ASTNode* parseBuiltinArrayDecl(TokenIter &curr) {
return new ASTNodeVariableDecl(curr[-6].typeToken.type, curr[-5].identifierToken.identifier, "", { }, curr[-3].integerToken.integer);
}
@ -86,7 +106,10 @@ namespace hex::lang {
return nullptr;
}
nodes.push_back(parsePaddingDecl(curr));
}
} else if (tryConsume(curr, {Token::Type::Type, Token::Type::Operator, Token::Type::Identifier, Token::Type::Operator, Token::Type::Type, Token::Type::EndOfExpression}))
nodes.push_back(parseBuiltinPointerVariableDecl(curr));
else if (tryConsume(curr, {Token::Type::Identifier, Token::Type::Operator, Token::Type::Identifier, Token::Type::Operator, Token::Type::Type, Token::Type::EndOfExpression}))
nodes.push_back(parseCustomTypePointerVariableDecl(curr));
else break;
}
@ -111,6 +134,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::Operator, Token::Type::Identifier, Token::Type::Operator, Token::Type::Type, Token::Type::EndOfExpression}))
nodes.push_back(parseBuiltinPointerVariableDecl(curr));
else if (tryConsume(curr, {Token::Type::Identifier, Token::Type::Operator, Token::Type::Identifier, Token::Type::Operator, Token::Type::Type, Token::Type::EndOfExpression}))
nodes.push_back(parseCustomTypePointerVariableDecl(curr));
else break;
}