Added overriding of endianess for individual variables
This commit is contained in:
parent
4720cf9fbe
commit
7a9d7b59e8
@ -2,6 +2,7 @@
|
||||
|
||||
#include "token.hpp"
|
||||
|
||||
#include <bit>
|
||||
#include <optional>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
@ -33,8 +34,8 @@ namespace hex::lang {
|
||||
|
||||
class ASTNodeVariableDecl : public ASTNode {
|
||||
public:
|
||||
explicit ASTNodeVariableDecl(u32 lineNumber, 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, lineNumber), m_type(type), m_name(name), m_customTypeName(customTypeName), m_offset(offset), m_arraySize(arraySize), m_arraySizeVariable(arraySizeVariable), m_pointerSize(pointerSize) { }
|
||||
explicit ASTNodeVariableDecl(u32 lineNumber, 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 = { }, std::optional<std::endian> endianess = { })
|
||||
: ASTNode(Type::VariableDecl, lineNumber), m_type(type), m_name(name), m_customTypeName(customTypeName), m_offset(offset), m_arraySize(arraySize), m_arraySizeVariable(arraySizeVariable), m_pointerSize(pointerSize), m_endianess(endianess) { }
|
||||
|
||||
const Token::TypeToken::Type& getVariableType() const { return this->m_type; }
|
||||
const std::string& getCustomVariableTypeName() const { return this->m_customTypeName; }
|
||||
@ -43,6 +44,7 @@ namespace hex::lang {
|
||||
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; }
|
||||
std::optional<std::endian> getEndianess() const { return this->m_endianess; }
|
||||
|
||||
private:
|
||||
Token::TypeToken::Type m_type;
|
||||
@ -51,6 +53,7 @@ namespace hex::lang {
|
||||
size_t m_arraySize;
|
||||
std::optional<std::string> m_arraySizeVariable;
|
||||
std::optional<u8> m_pointerSize;
|
||||
std::optional<std::endian> m_endianess = { };
|
||||
};
|
||||
|
||||
class ASTNodeScope : public ASTNode {
|
||||
|
@ -15,7 +15,7 @@ namespace hex::lang {
|
||||
|
||||
class Evaluator {
|
||||
public:
|
||||
Evaluator(prv::Provider* &provider, std::endian dataEndianess);
|
||||
Evaluator(prv::Provider* &provider, std::endian defaultDataEndianess);
|
||||
|
||||
std::pair<Result, std::vector<PatternData*>> evaluate(const std::vector<ASTNode*>& ast);
|
||||
|
||||
@ -24,7 +24,7 @@ namespace hex::lang {
|
||||
private:
|
||||
std::unordered_map<std::string, ASTNode*> m_types;
|
||||
prv::Provider* &m_provider;
|
||||
std::endian m_dataEndianess;
|
||||
std::endian m_defaultDataEndianess;
|
||||
|
||||
std::pair<u32, std::string> m_error;
|
||||
|
||||
|
@ -22,17 +22,18 @@ namespace hex::lang {
|
||||
std::pair<u32, std::string> m_error;
|
||||
|
||||
|
||||
ASTNode* parseBuiltinVariableDecl(TokenIter &curr);
|
||||
ASTNode* parseCustomTypeVariableDecl(TokenIter &curr);
|
||||
ASTNode* parseBuiltinPointerVariableDecl(TokenIter &curr);
|
||||
ASTNode* parseCustomTypePointerVariableDecl(TokenIter &curr);
|
||||
ASTNode* parseBuiltinArrayDecl(TokenIter &curr);
|
||||
ASTNode* parseCustomTypeArrayDecl(TokenIter &curr);
|
||||
ASTNode* parseBuiltinVariableArrayDecl(TokenIter &curr);
|
||||
ASTNode* parseCustomTypeVariableArrayDecl(TokenIter &curr);
|
||||
ASTNode* parseBuiltinVariableDecl(TokenIter &curr, bool hasEndianDef);
|
||||
ASTNode* parseCustomTypeVariableDecl(TokenIter &curr, bool hasEndianDef);
|
||||
ASTNode* parseBuiltinPointerVariableDecl(TokenIter &curr, bool hasEndianDef);
|
||||
ASTNode* parseCustomTypePointerVariableDecl(TokenIter &curr, bool hasEndianDef);
|
||||
ASTNode* parseBuiltinArrayDecl(TokenIter &curr, bool hasEndianDef);
|
||||
ASTNode* parseCustomTypeArrayDecl(TokenIter &curr, bool hasEndianDef);
|
||||
ASTNode* parseBuiltinVariableArrayDecl(TokenIter &curr, bool hasEndianDef);
|
||||
ASTNode* parseCustomTypeVariableArrayDecl(TokenIter &curr, bool hasEndianDef);
|
||||
ASTNode* parsePaddingDecl(TokenIter &curr);
|
||||
ASTNode* parseFreeBuiltinVariableDecl(TokenIter &curr);
|
||||
ASTNode* parseFreeCustomTypeVariableDecl(TokenIter &curr);
|
||||
ASTNode* parseFreeBuiltinVariableDecl(TokenIter &curr, bool hasEndianDef);
|
||||
ASTNode* parseFreeCustomTypeVariableDecl(TokenIter &curr, bool hasEndianDef);
|
||||
|
||||
ASTNode* parseStruct(TokenIter &curr);
|
||||
ASTNode* parseUnion(TokenIter &curr);
|
||||
ASTNode* parseEnum(TokenIter &curr);
|
||||
|
@ -35,8 +35,8 @@ namespace hex::lang {
|
||||
public:
|
||||
enum class Type { Padding, Unsigned, Signed, Float, Character, String, Struct, Union, Array, Enum };
|
||||
|
||||
PatternData(Type type, u64 offset, size_t size, const std::string &name, u32 color = 0)
|
||||
: m_type(type), m_offset(offset), m_size(size), m_color(color), m_name(name) {
|
||||
PatternData(Type type, u64 offset, size_t size, const std::string &name, std::endian endianess, u32 color = 0)
|
||||
: m_type(type), m_offset(offset), m_size(size), m_name(name), m_endianess(endianess), m_color(color) {
|
||||
constexpr u32 Palette[] = { 0x50b4771f, 0x500e7fff, 0x502ca02c, 0x502827d6, 0x50bd6794, 0x504b568c, 0x50c277e3, 0x507f7f7f, 0x5022bdbc, 0x50cfbe17 };
|
||||
|
||||
if (color != 0)
|
||||
@ -59,6 +59,9 @@ namespace hex::lang {
|
||||
[[nodiscard]] u32 getColor() const { return this->m_color; }
|
||||
void setColor(u32 color) { this->m_color = color; }
|
||||
|
||||
[[nodiscard]] std::endian getEndianess() const { return this->m_endianess; }
|
||||
void setEndianess(std::endian endianess) { this->m_endianess = endianess; }
|
||||
|
||||
virtual void createEntry(prv::Provider* &provider) = 0;
|
||||
virtual std::string getTypeName() = 0;
|
||||
|
||||
@ -97,10 +100,10 @@ namespace hex::lang {
|
||||
provider->read(left->getOffset(), leftBuffer.data(), left->getSize());
|
||||
provider->read(right->getOffset(), rightBuffer.data(), right->getSize());
|
||||
|
||||
if (PatternData::s_endianess != std::endian::native) {
|
||||
if (left->m_endianess != std::endian::native)
|
||||
std::reverse(leftBuffer.begin(), leftBuffer.end());
|
||||
if (right->m_endianess != std::endian::native)
|
||||
std::reverse(rightBuffer.begin(), rightBuffer.end());
|
||||
}
|
||||
|
||||
if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending)
|
||||
return leftBuffer > rightBuffer;
|
||||
@ -124,7 +127,6 @@ namespace hex::lang {
|
||||
}
|
||||
|
||||
static void resetPalette() { PatternData::s_paletteOffset = 0; }
|
||||
static void setEndianess(std::endian endianess) { PatternData::s_endianess = endianess; }
|
||||
|
||||
protected:
|
||||
void createDefaultEntry(std::string value) {
|
||||
@ -150,7 +152,7 @@ namespace hex::lang {
|
||||
}
|
||||
|
||||
protected:
|
||||
static inline std::endian s_endianess = std::endian::native;
|
||||
std::endian m_endianess = std::endian::native;
|
||||
|
||||
private:
|
||||
Type m_type;
|
||||
@ -166,7 +168,7 @@ namespace hex::lang {
|
||||
|
||||
class PatternDataPadding : public PatternData {
|
||||
public:
|
||||
PatternDataPadding(u64 offset, size_t size) : PatternData(Type::Padding, offset, size, "", 0x00FFFFFF) { }
|
||||
PatternDataPadding(u64 offset, size_t size) : PatternData(Type::Padding, offset, size, "", { }, 0x00FFFFFF) { }
|
||||
|
||||
void createEntry(prv::Provider* &provider) override {
|
||||
}
|
||||
@ -178,15 +180,15 @@ 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) {
|
||||
PatternDataPointer(u64 offset, size_t size, const std::string &name, PatternData *pointedAt, std::endian endianess, u32 color = 0)
|
||||
: PatternData(Type::Unsigned, offset, size, name, endianess, 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());
|
||||
data = hex::changeEndianess(data, this->getSize(), PatternData::s_endianess);
|
||||
data = hex::changeEndianess(data, this->getSize(), this->m_endianess);
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
@ -228,12 +230,13 @@ namespace hex::lang {
|
||||
|
||||
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) { }
|
||||
PatternDataUnsigned(u64 offset, size_t size, const std::string &name, std::endian endianess, u32 color = 0)
|
||||
: PatternData(Type::Unsigned, offset, size, name, endianess, color) { }
|
||||
|
||||
void createEntry(prv::Provider* &provider) override {
|
||||
u64 data = 0;
|
||||
provider->read(this->getOffset(), &data, this->getSize());
|
||||
data = hex::changeEndianess(data, this->getSize(), PatternData::s_endianess);
|
||||
data = hex::changeEndianess(data, this->getSize(), this->m_endianess);
|
||||
|
||||
this->createDefaultEntry(hex::format("%lu (0x%0*lx)", data, this->getSize() * 2, data));
|
||||
}
|
||||
@ -252,12 +255,13 @@ namespace hex::lang {
|
||||
|
||||
class PatternDataSigned : public PatternData {
|
||||
public:
|
||||
PatternDataSigned(u64 offset, size_t size, const std::string &name, u32 color = 0) : PatternData(Type::Signed, offset, size, name, color) { }
|
||||
PatternDataSigned(u64 offset, size_t size, const std::string &name, std::endian endianess, u32 color = 0)
|
||||
: PatternData(Type::Signed, offset, size, name, endianess, color) { }
|
||||
|
||||
void createEntry(prv::Provider* &provider) override {
|
||||
u64 data = 0;
|
||||
provider->read(this->getOffset(), &data, this->getSize());
|
||||
data = hex::changeEndianess(data, this->getSize(), PatternData::s_endianess);
|
||||
data = hex::changeEndianess(data, this->getSize(), this->m_endianess);
|
||||
|
||||
s64 signedData = signedData = hex::signExtend(data, this->getSize(), 64);
|
||||
|
||||
@ -278,20 +282,21 @@ namespace hex::lang {
|
||||
|
||||
class PatternDataFloat : public PatternData {
|
||||
public:
|
||||
PatternDataFloat(u64 offset, size_t size, const std::string &name, u32 color = 0) : PatternData(Type::Float, offset, size, name, color) { }
|
||||
PatternDataFloat(u64 offset, size_t size, const std::string &name, std::endian endianess, u32 color = 0)
|
||||
: PatternData(Type::Float, offset, size, name, endianess, color) { }
|
||||
|
||||
void createEntry(prv::Provider* &provider) override {
|
||||
double formatData = 0;
|
||||
if (this->getSize() == 4) {
|
||||
float data = 0;
|
||||
provider->read(this->getOffset(), &data, 4);
|
||||
data = hex::changeEndianess(data, 4, PatternData::s_endianess);
|
||||
data = hex::changeEndianess(data, 4, this->m_endianess);
|
||||
|
||||
formatData = data;
|
||||
} else if (this->getSize() == 8) {
|
||||
double data = 0;
|
||||
provider->read(this->getOffset(), &data, 8);
|
||||
data = hex::changeEndianess(data, 8, PatternData::s_endianess);
|
||||
data = hex::changeEndianess(data, 8, this->m_endianess);
|
||||
|
||||
formatData = data;
|
||||
}
|
||||
@ -310,7 +315,8 @@ namespace hex::lang {
|
||||
|
||||
class PatternDataCharacter : public PatternData {
|
||||
public:
|
||||
PatternDataCharacter(u64 offset, size_t size, const std::string &name, u32 color = 0) : PatternData(Type::Character, offset, size, name, color) { }
|
||||
PatternDataCharacter(u64 offset, size_t size, const std::string &name, std::endian endianess, u32 color = 0)
|
||||
: PatternData(Type::Character, offset, size, name, endianess, color) { }
|
||||
|
||||
void createEntry(prv::Provider* &provider) override {
|
||||
char character;
|
||||
@ -326,7 +332,8 @@ namespace hex::lang {
|
||||
|
||||
class PatternDataString : public PatternData {
|
||||
public:
|
||||
PatternDataString(u64 offset, size_t size, const std::string &name, u32 color = 0) : PatternData(Type::String, offset, size, name, color) { }
|
||||
PatternDataString(u64 offset, size_t size, const std::string &name, std::endian endianess, u32 color = 0)
|
||||
: PatternData(Type::String, offset, size, name, endianess, color) { }
|
||||
|
||||
void createEntry(prv::Provider* &provider) override {
|
||||
std::vector<u8> buffer(this->getSize() + 1, 0x00);
|
||||
@ -343,8 +350,8 @@ namespace hex::lang {
|
||||
|
||||
class PatternDataArray : public PatternData {
|
||||
public:
|
||||
PatternDataArray(u64 offset, size_t size, const std::string &name, const std::vector<PatternData*> & entries, u32 color = 0)
|
||||
: PatternData(Type::Array, offset, size, name, color), m_entries(entries) { }
|
||||
PatternDataArray(u64 offset, size_t size, const std::string &name, std::endian endianess, const std::vector<PatternData*> & entries, u32 color = 0)
|
||||
: PatternData(Type::Array, offset, size, name, endianess, color), m_entries(entries) { }
|
||||
|
||||
void createEntry(prv::Provider* &provider) override {
|
||||
ImGui::TableNextRow();
|
||||
@ -396,8 +403,8 @@ namespace hex::lang {
|
||||
|
||||
class PatternDataStruct : public PatternData {
|
||||
public:
|
||||
PatternDataStruct(u64 offset, size_t size, const std::string &name, const std::string &structName, const std::vector<PatternData*> & members, u32 color = 0)
|
||||
: PatternData(Type::Struct, offset, size, name, color), m_structName(structName), m_members(members), m_sortedMembers(members) { }
|
||||
PatternDataStruct(u64 offset, size_t size, const std::string &name, std::endian endianess, const std::string &structName, const std::vector<PatternData*> & members, u32 color = 0)
|
||||
: PatternData(Type::Struct, offset, size, name, endianess, color), m_structName(structName), m_members(members), m_sortedMembers(members) { }
|
||||
|
||||
void createEntry(prv::Provider* &provider) override {
|
||||
ImGui::TableNextRow();
|
||||
@ -454,8 +461,8 @@ namespace hex::lang {
|
||||
|
||||
class PatternDataUnion : public PatternData {
|
||||
public:
|
||||
PatternDataUnion(u64 offset, size_t size, const std::string &name, const std::string &unionName, const std::vector<PatternData*> & members, u32 color = 0)
|
||||
: PatternData(Type::Union, offset, size, name, color), m_unionName(unionName), m_members(members), m_sortedMembers(members) { }
|
||||
PatternDataUnion(u64 offset, size_t size, const std::string &name, const std::string &unionName, const std::vector<PatternData*> & members, std::endian endianess, u32 color = 0)
|
||||
: PatternData(Type::Union, offset, size, name, endianess, color), m_unionName(unionName), m_members(members), m_sortedMembers(members) { }
|
||||
|
||||
void createEntry(prv::Provider* &provider) override {
|
||||
ImGui::TableNextRow();
|
||||
@ -513,13 +520,13 @@ namespace hex::lang {
|
||||
|
||||
class PatternDataEnum : public PatternData {
|
||||
public:
|
||||
PatternDataEnum(u64 offset, size_t size, const std::string &name, const std::string &enumName, std::vector<std::pair<u64, std::string>> enumValues, u32 color = 0)
|
||||
: PatternData(Type::Enum, offset, size, name, color), m_enumName(enumName), m_enumValues(enumValues) { }
|
||||
PatternDataEnum(u64 offset, size_t size, const std::string &name, const std::string &enumName, std::vector<std::pair<u64, std::string>> enumValues, std::endian endianess, u32 color = 0)
|
||||
: PatternData(Type::Enum, offset, size, name, endianess, color), m_enumName(enumName), m_enumValues(enumValues) { }
|
||||
|
||||
void createEntry(prv::Provider* &provider) override {
|
||||
u64 value = 0;
|
||||
provider->read(this->getOffset(), &value, this->getSize());
|
||||
value = hex::changeEndianess(value, this->getSize(), PatternData::s_endianess);
|
||||
value = hex::changeEndianess(value, this->getSize(), this->m_endianess);
|
||||
|
||||
std::string valueString = this->m_enumName + "::";
|
||||
|
||||
@ -567,13 +574,13 @@ namespace hex::lang {
|
||||
|
||||
class PatternDataBitfield : public PatternData {
|
||||
public:
|
||||
PatternDataBitfield(u64 offset, size_t size, const std::string &name, const std::string &bitfieldName, std::vector<std::pair<std::string, size_t>> fields, u32 color = 0)
|
||||
: PatternData(Type::Enum, offset, size, name, color), m_bitfieldName(bitfieldName), m_fields(fields) { }
|
||||
PatternDataBitfield(u64 offset, size_t size, const std::string &name, const std::string &bitfieldName, std::vector<std::pair<std::string, size_t>> fields, std::endian endianess, u32 color = 0)
|
||||
: PatternData(Type::Enum, offset, size, name, endianess, color), m_bitfieldName(bitfieldName), m_fields(fields) { }
|
||||
|
||||
void createEntry(prv::Provider* &provider) override {
|
||||
u64 value = 0;
|
||||
provider->read(this->getOffset(), &value, this->getSize());
|
||||
value = hex::changeEndianess(value, this->getSize(), PatternData::s_endianess);
|
||||
value = hex::changeEndianess(value, this->getSize(), this->m_endianess);
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
@ -28,7 +28,9 @@ namespace hex::lang {
|
||||
Union,
|
||||
Using,
|
||||
Enum,
|
||||
Bitfield
|
||||
Bitfield,
|
||||
LittleEndian,
|
||||
BigEndian
|
||||
} keyword;
|
||||
} keywordToken;
|
||||
struct IdentifierToken {
|
||||
|
@ -5,8 +5,8 @@
|
||||
|
||||
namespace hex::lang {
|
||||
|
||||
Evaluator::Evaluator(prv::Provider* &provider, std::endian dataEndianess) : m_provider(provider), m_dataEndianess(dataEndianess) {
|
||||
PatternData::setEndianess(dataEndianess);
|
||||
Evaluator::Evaluator(prv::Provider* &provider, std::endian defaultDataEndianess) : m_provider(provider), m_defaultDataEndianess(defaultDataEndianess) {
|
||||
|
||||
}
|
||||
|
||||
std::pair<PatternData*, size_t> Evaluator::createStructPattern(ASTNodeVariableDecl *varDeclNode, u64 offset) {
|
||||
@ -28,7 +28,7 @@ namespace hex::lang {
|
||||
if (member->getPointerSize().has_value()) {
|
||||
this->m_provider->read(offset + structSize, &memberOffset, member->getPointerSize().value());
|
||||
|
||||
memberOffset = hex::changeEndianess(memberOffset, member->getPointerSize().value(), this->m_dataEndianess);
|
||||
memberOffset = hex::changeEndianess(memberOffset, member->getPointerSize().value(), member->getEndianess().value_or(varDeclNode->getEndianess().value_or(this->m_defaultDataEndianess)));
|
||||
}
|
||||
else
|
||||
memberOffset = offset + structSize;
|
||||
@ -58,7 +58,7 @@ namespace hex::lang {
|
||||
u64 value = 0;
|
||||
this->m_provider->read(prevMember->getOffset(), &value, prevMember->getSize());
|
||||
|
||||
value = hex::changeEndianess(value, prevMember->getSize(), this->m_dataEndianess);
|
||||
value = hex::changeEndianess(value, prevMember->getSize(), prevMember->getEndianess());
|
||||
|
||||
arraySize = value;
|
||||
}
|
||||
@ -83,8 +83,10 @@ namespace hex::lang {
|
||||
if (pattern == nullptr)
|
||||
return { nullptr, 0 };
|
||||
|
||||
pattern->setEndianess(member->getEndianess().value_or(varDeclNode->getEndianess().value_or(this->m_defaultDataEndianess)));
|
||||
|
||||
if (member->getPointerSize().has_value()) {
|
||||
members.push_back(new PatternDataPointer(offset + structSize, member->getPointerSize().value(), member->getVariableName(), pattern));
|
||||
members.push_back(new PatternDataPointer(offset + structSize, member->getPointerSize().value(), member->getVariableName(), pattern, member->getEndianess().value_or(varDeclNode->getEndianess().value_or(this->m_defaultDataEndianess))));
|
||||
structSize += member->getPointerSize().value();
|
||||
}
|
||||
else {
|
||||
@ -93,7 +95,7 @@ namespace hex::lang {
|
||||
}
|
||||
}
|
||||
|
||||
return { new PatternDataStruct(offset, structSize, varDeclNode->getVariableName(), structNode->getName(), members, 0x00FFFFFF), structSize };
|
||||
return { new PatternDataStruct(offset, structSize, varDeclNode->getVariableName(), varDeclNode->getEndianess().value_or(this->m_defaultDataEndianess), structNode->getName(), members, 0x00FFFFFF), structSize };
|
||||
}
|
||||
|
||||
std::pair<PatternData*, size_t> Evaluator::createUnionPattern(ASTNodeVariableDecl *varDeclNode, u64 offset) {
|
||||
@ -115,7 +117,7 @@ namespace hex::lang {
|
||||
if (member->getPointerSize().has_value()) {
|
||||
this->m_provider->read(offset + unionSize, &memberOffset, member->getPointerSize().value());
|
||||
|
||||
memberOffset = hex::changeEndianess(memberOffset, member->getPointerSize().value(), this->m_dataEndianess);
|
||||
memberOffset = hex::changeEndianess(memberOffset, member->getPointerSize().value(), member->getEndianess().value_or(this->m_defaultDataEndianess));
|
||||
}
|
||||
else
|
||||
memberOffset = offset;
|
||||
@ -148,7 +150,7 @@ namespace hex::lang {
|
||||
u64 value = 0;
|
||||
this->m_provider->read(prevMember->getOffset(), &value, prevMember->getSize());
|
||||
|
||||
value = hex::changeEndianess(value, prevMember->getSize(), this->m_dataEndianess);
|
||||
value = hex::changeEndianess(value, prevMember->getSize(), prevMember->getEndianess());
|
||||
|
||||
arraySize = value;
|
||||
}
|
||||
@ -178,8 +180,10 @@ namespace hex::lang {
|
||||
if (pattern == nullptr)
|
||||
return { nullptr, 0 };
|
||||
|
||||
pattern->setEndianess(member->getEndianess().value_or(varDeclNode->getEndianess().value_or(this->m_defaultDataEndianess)));
|
||||
|
||||
if (member->getPointerSize().has_value()) {
|
||||
members.push_back(new PatternDataPointer(offset, member->getPointerSize().value(), member->getVariableName(), pattern));
|
||||
members.push_back(new PatternDataPointer(offset, member->getPointerSize().value(), member->getVariableName(), pattern, member->getEndianess().value_or(this->m_defaultDataEndianess)));
|
||||
unionSize = std::max(size_t(member->getPointerSize().value()), unionSize);
|
||||
}
|
||||
else {
|
||||
@ -188,7 +192,7 @@ namespace hex::lang {
|
||||
}
|
||||
}
|
||||
|
||||
return { new PatternDataUnion(offset, unionSize, varDeclNode->getVariableName(), unionNode->getName(), members, 0x00FFFFFF), unionSize };
|
||||
return { new PatternDataUnion(offset, unionSize, varDeclNode->getVariableName(), unionNode->getName(), members, varDeclNode->getEndianess().value_or(this->m_defaultDataEndianess), 0x00FFFFFF), unionSize };
|
||||
}
|
||||
|
||||
std::pair<PatternData*, size_t> Evaluator::createEnumPattern(ASTNodeVariableDecl *varDeclNode, u64 offset) {
|
||||
@ -201,7 +205,7 @@ namespace hex::lang {
|
||||
|
||||
size_t size = getTypeSize(enumType->getUnderlyingType());
|
||||
|
||||
return { new PatternDataEnum(offset, size, varDeclNode->getVariableName(), enumType->getName(), enumType->getValues()), size };
|
||||
return { new PatternDataEnum(offset, size, varDeclNode->getVariableName(), enumType->getName(), enumType->getValues(), varDeclNode->getEndianess().value_or(this->m_defaultDataEndianess)), size };
|
||||
}
|
||||
|
||||
std::pair<PatternData*, size_t> Evaluator::createBitfieldPattern(ASTNodeVariableDecl *varDeclNode, u64 offset) {
|
||||
@ -219,7 +223,7 @@ namespace hex::lang {
|
||||
|
||||
size = std::bit_ceil(size) / 8;
|
||||
|
||||
return { new PatternDataBitfield(offset, size, varDeclNode->getVariableName(), bitfieldType->getName(), bitfieldType->getFields()), size };
|
||||
return { new PatternDataBitfield(offset, size, varDeclNode->getVariableName(), bitfieldType->getName(), bitfieldType->getFields(), varDeclNode->getEndianess().value_or(this->m_defaultDataEndianess)), size };
|
||||
}
|
||||
|
||||
std::pair<PatternData*, size_t> Evaluator::createArrayPattern(ASTNodeVariableDecl *varDeclNode, u64 offset) {
|
||||
@ -236,8 +240,12 @@ namespace hex::lang {
|
||||
} else if (varDeclNode->getVariableType() != Token::TypeToken::Type::CustomType) {
|
||||
const auto& [pattern, size] = this->createBuiltInTypePattern(nonArrayVarDeclNode, offset + arrayOffset);
|
||||
|
||||
if (pattern == nullptr)
|
||||
if (pattern == nullptr) {
|
||||
delete nonArrayVarDeclNode;
|
||||
return { nullptr, 0 };
|
||||
}
|
||||
|
||||
pattern->setEndianess(varDeclNode->getEndianess().value_or(varDeclNode->getEndianess().value_or(this->m_defaultDataEndianess)));
|
||||
|
||||
if (!arrayColor.has_value())
|
||||
arrayColor = pattern->getColor();
|
||||
@ -249,8 +257,12 @@ namespace hex::lang {
|
||||
} else {
|
||||
const auto &[pattern, size] = this->createCustomTypePattern(nonArrayVarDeclNode, offset + arrayOffset);
|
||||
|
||||
if (pattern == nullptr)
|
||||
if (pattern == nullptr) {
|
||||
delete nonArrayVarDeclNode;
|
||||
return { nullptr, 0 };
|
||||
}
|
||||
|
||||
pattern->setEndianess(varDeclNode->getEndianess().value_or(varDeclNode->getEndianess().value_or(this->m_defaultDataEndianess)));
|
||||
|
||||
if (!arrayColor.has_value())
|
||||
arrayColor = pattern->getColor();
|
||||
@ -264,13 +276,13 @@ namespace hex::lang {
|
||||
delete nonArrayVarDeclNode;
|
||||
}
|
||||
|
||||
return { new PatternDataArray(offset, arrayOffset, varDeclNode->getVariableName(), entries, arrayColor.value()), arrayOffset };
|
||||
return { new PatternDataArray(offset, arrayOffset, varDeclNode->getVariableName(), varDeclNode->getEndianess().value_or(this->m_defaultDataEndianess), entries, arrayColor.value()), arrayOffset };
|
||||
}
|
||||
|
||||
std::pair<PatternData*, size_t> Evaluator::createStringPattern(ASTNodeVariableDecl *varDeclNode, u64 offset) {
|
||||
size_t arraySize = varDeclNode->getArraySize();
|
||||
|
||||
return { new PatternDataString(offset, arraySize, varDeclNode->getVariableName()), arraySize };
|
||||
return { new PatternDataString(offset, arraySize, varDeclNode->getVariableName(), varDeclNode->getEndianess().value_or(this->m_defaultDataEndianess)), arraySize };
|
||||
}
|
||||
|
||||
std::pair<PatternData*, size_t> Evaluator::createCustomTypePattern(ASTNodeVariableDecl *varDeclNode, u64 offset) {
|
||||
@ -314,21 +326,21 @@ namespace hex::lang {
|
||||
|
||||
if (isSigned(type)) {
|
||||
if (typeSize == 1 && arraySize == 1)
|
||||
return { new PatternDataCharacter(offset, typeSize, varDeclNode->getVariableName()), 1 };
|
||||
return { new PatternDataCharacter(offset, typeSize, varDeclNode->getVariableName(), varDeclNode->getEndianess().value_or(this->m_defaultDataEndianess)), 1 };
|
||||
else if (arraySize > 1)
|
||||
return createArrayPattern(varDeclNode, offset);
|
||||
else
|
||||
return { new PatternDataSigned(offset, typeSize, varDeclNode->getVariableName()), typeSize * arraySize };
|
||||
return { new PatternDataSigned(offset, typeSize, varDeclNode->getVariableName(), varDeclNode->getEndianess().value_or(this->m_defaultDataEndianess)), typeSize * arraySize };
|
||||
} else if (isUnsigned(varDeclNode->getVariableType())) {
|
||||
if (arraySize > 1)
|
||||
return createArrayPattern(varDeclNode, offset);
|
||||
else
|
||||
return { new PatternDataUnsigned(offset, typeSize, varDeclNode->getVariableName()), typeSize * arraySize };
|
||||
return { new PatternDataUnsigned(offset, typeSize, varDeclNode->getVariableName(), varDeclNode->getEndianess().value_or(this->m_defaultDataEndianess)), typeSize * arraySize };
|
||||
} else if (isFloatingPoint(varDeclNode->getVariableType())) {
|
||||
if (arraySize > 1)
|
||||
return createArrayPattern(varDeclNode, offset);
|
||||
else
|
||||
return { new PatternDataFloat(offset, typeSize, varDeclNode->getVariableName()), typeSize * arraySize };
|
||||
return { new PatternDataFloat(offset, typeSize, varDeclNode->getVariableName(), varDeclNode->getEndianess().value_or(this->m_defaultDataEndianess)), typeSize * arraySize };
|
||||
}
|
||||
|
||||
return { nullptr, 0 };
|
||||
|
@ -192,8 +192,12 @@ namespace hex::lang {
|
||||
tokens.push_back({ .type = Token::Type::Keyword, .keywordToken = { .keyword = Token::KeywordToken::Keyword::Enum }, .lineNumber = lineNumber });
|
||||
else if (identifier == "bitfield")
|
||||
tokens.push_back({ .type = Token::Type::Keyword, .keywordToken = { .keyword = Token::KeywordToken::Keyword::Bitfield }, .lineNumber = lineNumber });
|
||||
else if (identifier == "be")
|
||||
tokens.push_back({ .type = Token::Type::Keyword, .keywordToken = { .keyword = Token::KeywordToken::Keyword::BigEndian }, .lineNumber = lineNumber });
|
||||
else if (identifier == "le")
|
||||
tokens.push_back({ .type = Token::Type::Keyword, .keywordToken = { .keyword = Token::KeywordToken::Keyword::LittleEndian }, .lineNumber = lineNumber });
|
||||
|
||||
// Check for built-in types
|
||||
// Check for built-in types
|
||||
else if (identifier == "u8")
|
||||
tokens.push_back({ .type = Token::Type::Type, .typeToken = { .type = Token::TypeToken::Type::Unsigned8Bit }, .lineNumber = lineNumber });
|
||||
else if (identifier == "s8")
|
||||
|
@ -25,15 +25,42 @@ namespace hex::lang {
|
||||
}
|
||||
|
||||
|
||||
ASTNode* Parser::parseBuiltinVariableDecl(TokenIter &curr) {
|
||||
return new ASTNodeVariableDecl(curr[-3].lineNumber, curr[-3].typeToken.type, curr[-2].identifierToken.identifier);
|
||||
ASTNode* Parser::parseBuiltinVariableDecl(TokenIter &curr, bool hasEndianDef) {
|
||||
if (hasEndianDef) {
|
||||
std::endian endianess;
|
||||
|
||||
if (curr[-4].keywordToken.keyword == Token::KeywordToken::Keyword::LittleEndian)
|
||||
endianess = std::endian::little;
|
||||
else if (curr[-4].keywordToken.keyword == Token::KeywordToken::Keyword::BigEndian)
|
||||
endianess = std::endian::big;
|
||||
else {
|
||||
this->m_error = { curr->lineNumber, "Expected be or le identifier" };
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new ASTNodeVariableDecl(curr[-4].lineNumber, curr[-3].typeToken.type, curr[-2].identifierToken.identifier, "", {}, 1, {}, {}, endianess);
|
||||
}
|
||||
else
|
||||
return new ASTNodeVariableDecl(curr[-3].lineNumber, curr[-3].typeToken.type, curr[-2].identifierToken.identifier);
|
||||
}
|
||||
|
||||
ASTNode* Parser::parseCustomTypeVariableDecl(TokenIter &curr) {
|
||||
return new ASTNodeVariableDecl(curr[-3].lineNumber, Token::TypeToken::Type::CustomType, curr[-2].identifierToken.identifier, curr[-3].identifierToken.identifier);
|
||||
ASTNode* Parser::parseCustomTypeVariableDecl(TokenIter &curr, bool hasEndianDef) {
|
||||
if (hasEndianDef) {
|
||||
std::endian endianess;
|
||||
|
||||
if (curr[-4].keywordToken.keyword == Token::KeywordToken::Keyword::LittleEndian)
|
||||
endianess = std::endian::little;
|
||||
else if (curr[-4].keywordToken.keyword == Token::KeywordToken::Keyword::BigEndian)
|
||||
endianess = std::endian::big;
|
||||
else return nullptr;
|
||||
|
||||
return new ASTNodeVariableDecl(curr[-4].lineNumber, Token::TypeToken::Type::CustomType, curr[-2].identifierToken.identifier, curr[-3].identifierToken.identifier, {}, 1, {}, {}, endianess);
|
||||
}
|
||||
else
|
||||
return new ASTNodeVariableDecl(curr[-3].lineNumber, Token::TypeToken::Type::CustomType, curr[-2].identifierToken.identifier, curr[-3].identifierToken.identifier);
|
||||
}
|
||||
|
||||
ASTNode* Parser::parseBuiltinPointerVariableDecl(TokenIter &curr) {
|
||||
ASTNode* Parser::parseBuiltinPointerVariableDecl(TokenIter &curr, bool hasEndianDef) {
|
||||
auto pointerType = curr[-2].typeToken.type;
|
||||
|
||||
if (!isUnsigned(pointerType)) {
|
||||
@ -51,10 +78,23 @@ namespace hex::lang {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new ASTNodeVariableDecl(curr[-6].lineNumber, curr[-6].typeToken.type, curr[-4].identifierToken.identifier, "", { }, 1, { }, getTypeSize(pointerType));
|
||||
|
||||
if (hasEndianDef) {
|
||||
std::endian endianess;
|
||||
|
||||
if (curr[-7].keywordToken.keyword == Token::KeywordToken::Keyword::LittleEndian)
|
||||
endianess = std::endian::little;
|
||||
else if (curr[-7].keywordToken.keyword == Token::KeywordToken::Keyword::BigEndian)
|
||||
endianess = std::endian::big;
|
||||
else return nullptr;
|
||||
|
||||
return new ASTNodeVariableDecl(curr[-7].lineNumber, curr[-6].typeToken.type, curr[-4].identifierToken.identifier, "", { }, 1, { }, getTypeSize(pointerType), endianess);
|
||||
}
|
||||
else
|
||||
return new ASTNodeVariableDecl(curr[-6].lineNumber, curr[-6].typeToken.type, curr[-4].identifierToken.identifier, "", { }, 1, { }, getTypeSize(pointerType));
|
||||
}
|
||||
|
||||
ASTNode* Parser::parseCustomTypePointerVariableDecl(TokenIter &curr) {
|
||||
ASTNode* Parser::parseCustomTypePointerVariableDecl(TokenIter &curr, bool hasEndianDef) {
|
||||
auto pointerType = curr[-2].typeToken.type;
|
||||
|
||||
if (!isUnsigned(pointerType)) {
|
||||
@ -72,35 +112,140 @@ namespace hex::lang {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new ASTNodeVariableDecl(curr[-6].lineNumber, Token::TypeToken::Type::CustomType, curr[-4].identifierToken.identifier, curr[-6].identifierToken.identifier, { }, 1, { }, getTypeSize(pointerType));
|
||||
if (hasEndianDef) {
|
||||
std::endian endianess;
|
||||
|
||||
if (curr[-7].keywordToken.keyword == Token::KeywordToken::Keyword::LittleEndian)
|
||||
endianess = std::endian::little;
|
||||
else if (curr[-7].keywordToken.keyword == Token::KeywordToken::Keyword::BigEndian)
|
||||
endianess = std::endian::big;
|
||||
else {
|
||||
this->m_error = { curr->lineNumber, "Expected be or le identifier" };
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new ASTNodeVariableDecl(curr[-7].lineNumber,Token::TypeToken::Type::CustomType, curr[-4].identifierToken.identifier, curr[-6].identifierToken.identifier, { }, 1, { }, getTypeSize(pointerType), endianess);
|
||||
}
|
||||
else
|
||||
return new ASTNodeVariableDecl(curr[-6].lineNumber, Token::TypeToken::Type::CustomType, curr[-4].identifierToken.identifier, curr[-6].identifierToken.identifier, { }, 1, { }, getTypeSize(pointerType));
|
||||
}
|
||||
|
||||
ASTNode* Parser::parseBuiltinArrayDecl(TokenIter &curr) {
|
||||
return new ASTNodeVariableDecl(curr[-6].lineNumber, curr[-6].typeToken.type, curr[-5].identifierToken.identifier, "", { }, curr[-3].integerToken.integer);
|
||||
ASTNode* Parser::parseBuiltinArrayDecl(TokenIter &curr, bool hasEndianDef) {
|
||||
if (hasEndianDef) {
|
||||
std::endian endianess;
|
||||
|
||||
if (curr[-7].keywordToken.keyword == Token::KeywordToken::Keyword::LittleEndian)
|
||||
endianess = std::endian::little;
|
||||
else if (curr[-7].keywordToken.keyword == Token::KeywordToken::Keyword::BigEndian)
|
||||
endianess = std::endian::big;
|
||||
else {
|
||||
this->m_error = { curr->lineNumber, "Expected be or le identifier" };
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new ASTNodeVariableDecl(curr[-7].lineNumber, curr[-6].typeToken.type, curr[-5].identifierToken.identifier, "", { }, curr[-3].integerToken.integer, { }, { }, endianess);
|
||||
}
|
||||
else
|
||||
return new ASTNodeVariableDecl(curr[-6].lineNumber, curr[-6].typeToken.type, curr[-5].identifierToken.identifier, "", { }, curr[-3].integerToken.integer);
|
||||
}
|
||||
|
||||
ASTNode* Parser::parseCustomTypeArrayDecl(TokenIter &curr) {
|
||||
return new ASTNodeVariableDecl(curr[-6].lineNumber, Token::TypeToken::Type::CustomType, curr[-5].identifierToken.identifier, curr[-6].identifierToken.identifier, { }, curr[-3].integerToken.integer);
|
||||
ASTNode* Parser::parseCustomTypeArrayDecl(TokenIter &curr, bool hasEndianDef) {
|
||||
if (hasEndianDef) {
|
||||
std::endian endianess;
|
||||
|
||||
if (curr[-7].keywordToken.keyword == Token::KeywordToken::Keyword::LittleEndian)
|
||||
endianess = std::endian::little;
|
||||
else if (curr[-7].keywordToken.keyword == Token::KeywordToken::Keyword::BigEndian)
|
||||
endianess = std::endian::big;
|
||||
else {
|
||||
this->m_error = { curr->lineNumber, "Expected be or le identifier" };
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new ASTNodeVariableDecl(curr[-7].lineNumber, Token::TypeToken::Type::CustomType, curr[-5].identifierToken.identifier, curr[-6].identifierToken.identifier, { }, curr[-3].integerToken.integer, { }, { }, endianess);
|
||||
}
|
||||
else
|
||||
return new ASTNodeVariableDecl(curr[-6].lineNumber, Token::TypeToken::Type::CustomType, curr[-5].identifierToken.identifier, curr[-6].identifierToken.identifier, { }, curr[-3].integerToken.integer);
|
||||
}
|
||||
|
||||
ASTNode* Parser::parseBuiltinVariableArrayDecl(TokenIter &curr) {
|
||||
return new ASTNodeVariableDecl(curr[-6].lineNumber, curr[-6].typeToken.type, curr[-5].identifierToken.identifier, "", { }, 0, curr[-3].identifierToken.identifier);
|
||||
ASTNode* Parser::parseBuiltinVariableArrayDecl(TokenIter &curr, bool hasEndianDef) {
|
||||
if (hasEndianDef) {
|
||||
std::endian endianess;
|
||||
|
||||
if (curr[-7].keywordToken.keyword == Token::KeywordToken::Keyword::LittleEndian)
|
||||
endianess = std::endian::little;
|
||||
else if (curr[-7].keywordToken.keyword == Token::KeywordToken::Keyword::BigEndian)
|
||||
endianess = std::endian::big;
|
||||
else {
|
||||
this->m_error = { curr->lineNumber, "Expected be or le identifier" };
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new ASTNodeVariableDecl(curr[-7].lineNumber, curr[-6].typeToken.type, curr[-5].identifierToken.identifier, "", { }, 0, curr[-3].identifierToken.identifier, { }, endianess);
|
||||
}
|
||||
else
|
||||
return new ASTNodeVariableDecl(curr[-6].lineNumber, curr[-6].typeToken.type, curr[-5].identifierToken.identifier, "", { }, 0, curr[-3].identifierToken.identifier);
|
||||
}
|
||||
|
||||
ASTNode* Parser::parseCustomTypeVariableArrayDecl(TokenIter &curr) {
|
||||
return new ASTNodeVariableDecl(curr[-6].lineNumber, Token::TypeToken::Type::CustomType, curr[-5].identifierToken.identifier, curr[-6].identifierToken.identifier, { }, 0, curr[-3].identifierToken.identifier);
|
||||
ASTNode* Parser::parseCustomTypeVariableArrayDecl(TokenIter &curr, bool hasEndianDef) {
|
||||
if (hasEndianDef) {
|
||||
std::endian endianess;
|
||||
|
||||
if (curr[-7].keywordToken.keyword == Token::KeywordToken::Keyword::LittleEndian)
|
||||
endianess = std::endian::little;
|
||||
else if (curr[-7].keywordToken.keyword == Token::KeywordToken::Keyword::BigEndian)
|
||||
endianess = std::endian::big;
|
||||
else {
|
||||
this->m_error = { curr->lineNumber, "Expected be or le identifier" };
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new ASTNodeVariableDecl(curr[-7].lineNumber, Token::TypeToken::Type::CustomType, curr[-5].identifierToken.identifier, curr[-6].identifierToken.identifier, { }, 0, curr[-3].identifierToken.identifier, { }, endianess);
|
||||
}
|
||||
else
|
||||
return new ASTNodeVariableDecl(curr[-6].lineNumber, Token::TypeToken::Type::CustomType, curr[-5].identifierToken.identifier, curr[-6].identifierToken.identifier, { }, 0, curr[-3].identifierToken.identifier);
|
||||
}
|
||||
|
||||
ASTNode* Parser::parsePaddingDecl(TokenIter &curr) {
|
||||
return new ASTNodeVariableDecl(curr[-5].lineNumber, curr[-5].typeToken.type, "", "", { }, curr[-3].integerToken.integer);
|
||||
return new ASTNodeVariableDecl(curr[-5].lineNumber, curr[-5].typeToken.type, "", "", { }, curr[-3].integerToken.integer);
|
||||
}
|
||||
|
||||
ASTNode* Parser::parseFreeBuiltinVariableDecl(TokenIter &curr) {
|
||||
return new ASTNodeVariableDecl(curr[-5].lineNumber, curr[-5].typeToken.type, curr[-4].identifierToken.identifier, "", curr[-2].integerToken.integer);
|
||||
ASTNode* Parser::parseFreeBuiltinVariableDecl(TokenIter &curr, bool hasEndianDef) {
|
||||
if (hasEndianDef) {
|
||||
std::endian endianess;
|
||||
|
||||
if (curr[-6].keywordToken.keyword == Token::KeywordToken::Keyword::LittleEndian)
|
||||
endianess = std::endian::little;
|
||||
else if (curr[-6].keywordToken.keyword == Token::KeywordToken::Keyword::BigEndian)
|
||||
endianess = std::endian::big;
|
||||
else {
|
||||
this->m_error = { curr->lineNumber, "Expected be or le identifier" };
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new ASTNodeVariableDecl(curr[-6].lineNumber, curr[-5].typeToken.type, curr[-4].identifierToken.identifier, "", curr[-2].integerToken.integer, 1, { }, { }, endianess);
|
||||
}
|
||||
else
|
||||
return new ASTNodeVariableDecl(curr[-5].lineNumber, curr[-5].typeToken.type, curr[-4].identifierToken.identifier, "", curr[-2].integerToken.integer);
|
||||
}
|
||||
|
||||
ASTNode* Parser::parseFreeCustomTypeVariableDecl(TokenIter &curr) {
|
||||
return new ASTNodeVariableDecl(curr[-5].lineNumber, Token::TypeToken::Type::CustomType, curr[-4].identifierToken.identifier, curr[-5].identifierToken.identifier, curr[-2].integerToken.integer);
|
||||
ASTNode* Parser::parseFreeCustomTypeVariableDecl(TokenIter &curr, bool hasEndianDef) {
|
||||
if (hasEndianDef) {
|
||||
std::endian endianess;
|
||||
|
||||
if (curr[-6].keywordToken.keyword == Token::KeywordToken::Keyword::LittleEndian)
|
||||
endianess = std::endian::little;
|
||||
else if (curr[-6].keywordToken.keyword == Token::KeywordToken::Keyword::BigEndian)
|
||||
endianess = std::endian::big;
|
||||
else {
|
||||
this->m_error = { curr->lineNumber, "Expected be or le identifier" };
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new ASTNodeVariableDecl(curr[-6].lineNumber, Token::TypeToken::Type::CustomType, curr[-4].identifierToken.identifier, curr[-5].identifierToken.identifier, curr[-2].integerToken.integer, 1, { }, { }, endianess);
|
||||
}
|
||||
else
|
||||
return new ASTNodeVariableDecl(curr[-5].lineNumber, Token::TypeToken::Type::CustomType, curr[-4].identifierToken.identifier, curr[-5].identifierToken.identifier, curr[-2].integerToken.integer);
|
||||
}
|
||||
|
||||
ASTNode* Parser::parseStruct(TokenIter &curr) {
|
||||
@ -111,17 +256,17 @@ namespace hex::lang {
|
||||
|
||||
while (!tryConsume(curr, {Token::Type::ScopeClose})) {
|
||||
if (tryConsume(curr, {Token::Type::Type, Token::Type::Identifier, Token::Type::EndOfExpression}))
|
||||
nodes.push_back(parseBuiltinVariableDecl(curr));
|
||||
nodes.push_back(parseBuiltinVariableDecl(curr, false));
|
||||
else if (tryConsume(curr, {Token::Type::Identifier, Token::Type::Identifier, Token::Type::EndOfExpression}))
|
||||
nodes.push_back(parseCustomTypeVariableDecl(curr));
|
||||
nodes.push_back(parseCustomTypeVariableDecl(curr, false));
|
||||
else if (tryConsume(curr, {Token::Type::Type, Token::Type::Identifier, Token::Type::ArrayOpen, Token::Type::Integer, Token::Type::ArrayClose, Token::Type::EndOfExpression}))
|
||||
nodes.push_back(parseBuiltinArrayDecl(curr));
|
||||
nodes.push_back(parseBuiltinArrayDecl(curr, false));
|
||||
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, false));
|
||||
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));
|
||||
nodes.push_back(parseBuiltinVariableArrayDecl(curr, false));
|
||||
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));
|
||||
nodes.push_back(parseCustomTypeVariableArrayDecl(curr, false));
|
||||
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;
|
||||
@ -131,9 +276,25 @@ namespace hex::lang {
|
||||
}
|
||||
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));
|
||||
nodes.push_back(parseBuiltinPointerVariableDecl(curr, false));
|
||||
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));
|
||||
nodes.push_back(parseCustomTypePointerVariableDecl(curr, false));
|
||||
else if (tryConsume(curr, {Token::Type::Keyword, Token::Type::Type, Token::Type::Identifier, Token::Type::EndOfExpression}))
|
||||
nodes.push_back(parseBuiltinVariableDecl(curr, true));
|
||||
else if (tryConsume(curr, {Token::Type::Keyword, Token::Type::Identifier, Token::Type::Identifier, Token::Type::EndOfExpression}))
|
||||
nodes.push_back(parseCustomTypeVariableDecl(curr, true));
|
||||
else if (tryConsume(curr, {Token::Type::Keyword, Token::Type::Type, Token::Type::Identifier, Token::Type::ArrayOpen, Token::Type::Integer, Token::Type::ArrayClose, Token::Type::EndOfExpression}))
|
||||
nodes.push_back(parseBuiltinArrayDecl(curr, true));
|
||||
else if (tryConsume(curr, {Token::Type::Keyword, Token::Type::Identifier, Token::Type::Identifier, Token::Type::ArrayOpen, Token::Type::Integer, Token::Type::ArrayClose, Token::Type::EndOfExpression}))
|
||||
nodes.push_back(parseCustomTypeArrayDecl(curr, true));
|
||||
else if (tryConsume(curr, {Token::Type::Keyword, Token::Type::Type, Token::Type::Identifier, Token::Type::ArrayOpen, Token::Type::Identifier, Token::Type::ArrayClose, Token::Type::EndOfExpression}))
|
||||
nodes.push_back(parseBuiltinVariableArrayDecl(curr, true));
|
||||
else if (tryConsume(curr, {Token::Type::Keyword, Token::Type::Identifier, Token::Type::Identifier, Token::Type::ArrayOpen, Token::Type::Identifier, Token::Type::ArrayClose, Token::Type::EndOfExpression}))
|
||||
nodes.push_back(parseCustomTypeVariableArrayDecl(curr, true));
|
||||
else if (tryConsume(curr, {Token::Type::Keyword, Token::Type::Type, Token::Type::Operator, Token::Type::Identifier, Token::Type::Operator, Token::Type::Type, Token::Type::EndOfExpression}))
|
||||
nodes.push_back(parseBuiltinPointerVariableDecl(curr, true));
|
||||
else if (tryConsume(curr, {Token::Type::Keyword, Token::Type::Identifier, Token::Type::Operator, Token::Type::Identifier, Token::Type::Operator, Token::Type::Type, Token::Type::EndOfExpression}))
|
||||
nodes.push_back(parseCustomTypePointerVariableDecl(curr, true));
|
||||
else {
|
||||
for(auto &node : nodes) delete node;
|
||||
this->m_error = { curr->lineNumber, "Invalid sequence, expected member declaration" };
|
||||
@ -158,17 +319,29 @@ namespace hex::lang {
|
||||
|
||||
while (!tryConsume(curr, {Token::Type::ScopeClose})) {
|
||||
if (tryConsume(curr, {Token::Type::Type, Token::Type::Identifier, Token::Type::EndOfExpression}))
|
||||
nodes.push_back(parseBuiltinVariableDecl(curr));
|
||||
nodes.push_back(parseBuiltinVariableDecl(curr, false));
|
||||
else if (tryConsume(curr, {Token::Type::Identifier, Token::Type::Identifier, Token::Type::EndOfExpression}))
|
||||
nodes.push_back(parseCustomTypeVariableDecl(curr));
|
||||
nodes.push_back(parseCustomTypeVariableDecl(curr, false));
|
||||
else if (tryConsume(curr, {Token::Type::Type, Token::Type::Identifier, Token::Type::ArrayOpen, Token::Type::Integer, Token::Type::ArrayClose, Token::Type::EndOfExpression}))
|
||||
nodes.push_back(parseBuiltinArrayDecl(curr));
|
||||
nodes.push_back(parseBuiltinArrayDecl(curr, false));
|
||||
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, false));
|
||||
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));
|
||||
nodes.push_back(parseBuiltinPointerVariableDecl(curr, false));
|
||||
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));
|
||||
nodes.push_back(parseCustomTypePointerVariableDecl(curr, false));
|
||||
else if (tryConsume(curr, {Token::Type::Keyword, Token::Type::Type, Token::Type::Identifier, Token::Type::EndOfExpression}))
|
||||
nodes.push_back(parseBuiltinVariableDecl(curr, true));
|
||||
else if (tryConsume(curr, {Token::Type::Keyword, Token::Type::Identifier, Token::Type::Identifier, Token::Type::EndOfExpression}))
|
||||
nodes.push_back(parseCustomTypeVariableDecl(curr, true));
|
||||
else if (tryConsume(curr, {Token::Type::Keyword, Token::Type::Type, Token::Type::Identifier, Token::Type::ArrayOpen, Token::Type::Integer, Token::Type::ArrayClose, Token::Type::EndOfExpression}))
|
||||
nodes.push_back(parseBuiltinArrayDecl(curr, true));
|
||||
else if (tryConsume(curr, {Token::Type::Keyword, Token::Type::Identifier, Token::Type::Identifier, Token::Type::ArrayOpen, Token::Type::Integer, Token::Type::ArrayClose, Token::Type::EndOfExpression}))
|
||||
nodes.push_back(parseCustomTypeArrayDecl(curr, true));
|
||||
else if (tryConsume(curr, {Token::Type::Keyword, Token::Type::Type, Token::Type::Operator, Token::Type::Identifier, Token::Type::Operator, Token::Type::Type, Token::Type::EndOfExpression}))
|
||||
nodes.push_back(parseBuiltinPointerVariableDecl(curr, true));
|
||||
else if (tryConsume(curr, {Token::Type::Keyword, Token::Type::Identifier, Token::Type::Operator, Token::Type::Identifier, Token::Type::Operator, Token::Type::Type, Token::Type::EndOfExpression}))
|
||||
nodes.push_back(parseCustomTypePointerVariableDecl(curr, true));
|
||||
else {
|
||||
for(auto &node : nodes) delete node;
|
||||
this->m_error = { curr->lineNumber, "Invalid sequence, expected member declaration" };
|
||||
@ -390,7 +563,7 @@ namespace hex::lang {
|
||||
return { };
|
||||
}
|
||||
|
||||
auto variableDecl = parseFreeBuiltinVariableDecl(curr);
|
||||
auto variableDecl = parseFreeBuiltinVariableDecl(curr, false);
|
||||
|
||||
program.push_back(variableDecl);
|
||||
|
||||
@ -404,7 +577,35 @@ namespace hex::lang {
|
||||
return { };
|
||||
}
|
||||
|
||||
auto variableDecl = parseFreeCustomTypeVariableDecl(curr);
|
||||
auto variableDecl = parseFreeCustomTypeVariableDecl(curr, false);
|
||||
|
||||
program.push_back(variableDecl);
|
||||
|
||||
return program;
|
||||
|
||||
// Variable placement declaration with built-in type and big/little endian setting
|
||||
} else if (tryConsume(curr, { Token::Type::Keyword, Token::Type::Type, Token::Type::Identifier, Token::Type::Operator, Token::Type::Integer, Token::Type::EndOfExpression})) {
|
||||
if (curr[-3].operatorToken.op != Token::OperatorToken::Operator::AtDeclaration) {
|
||||
this->m_error = { curr[-3].lineNumber, "Expected '@' after variable placement declaration" };
|
||||
for(auto &node : program) delete node;
|
||||
return { };
|
||||
}
|
||||
|
||||
auto variableDecl = parseFreeBuiltinVariableDecl(curr, true);
|
||||
|
||||
program.push_back(variableDecl);
|
||||
|
||||
return program;
|
||||
|
||||
// Variable placement declaration with custom type and big/little endian setting
|
||||
} else if (tryConsume(curr, { Token::Type::Keyword, Token::Type::Identifier, Token::Type::Identifier, Token::Type::Operator, Token::Type::Integer, Token::Type::EndOfExpression})) {
|
||||
if (curr[-3].operatorToken.op != Token::OperatorToken::Operator::AtDeclaration) {
|
||||
this->m_error = { curr[-3].lineNumber, "Expected '@' after variable placement declaration" };
|
||||
for(auto &node : program) delete node;
|
||||
return { };
|
||||
}
|
||||
|
||||
auto variableDecl = parseFreeCustomTypeVariableDecl(curr, true);
|
||||
|
||||
program.push_back(variableDecl);
|
||||
|
||||
|
@ -110,11 +110,13 @@ namespace hex {
|
||||
ImGui::TextWrapped(
|
||||
"Normal variables as well as arrays are used to highlight and display values. "
|
||||
"It is possible to create arrays within structs and unions that use the value of a previously "
|
||||
"declared variable as size.");
|
||||
"declared variable as size. In order to override the native / globally set endianess setting, every "
|
||||
"type in a variable declaration may be prefixed with be or le to turn only it into a big or little endian type.");
|
||||
drawCodeSegment("vars arrays",
|
||||
"u32 variable;\n"
|
||||
"s8 string[16];\n"
|
||||
"u8 customSizedArray[variable];"
|
||||
"u8 customSizedArray[variable];\n"
|
||||
"be u32 bigEndianVariable;"
|
||||
);
|
||||
|
||||
drawTitle("Structs");
|
||||
|
@ -18,7 +18,7 @@ namespace hex {
|
||||
static TextEditor::LanguageDefinition langDef;
|
||||
if (!initialized) {
|
||||
static const char* const keywords[] = {
|
||||
"using", "struct", "union", "enum", "bitfield"
|
||||
"using", "struct", "union", "enum", "bitfield", "be", "le"
|
||||
};
|
||||
for (auto& k : keywords)
|
||||
langDef.mKeywords.insert(k);
|
||||
@ -262,17 +262,17 @@ namespace hex {
|
||||
this->postEvent(Events::PatternChanged);
|
||||
|
||||
hex::lang::Preprocessor preprocessor;
|
||||
std::endian dataEndianess = std::endian::native;
|
||||
std::endian defaultDataEndianess = std::endian::native;
|
||||
|
||||
preprocessor.addPragmaHandler("endian", [&dataEndianess](std::string value) {
|
||||
preprocessor.addPragmaHandler("endian", [&defaultDataEndianess](std::string value) {
|
||||
if (value == "big") {
|
||||
dataEndianess = std::endian::big;
|
||||
defaultDataEndianess = std::endian::big;
|
||||
return true;
|
||||
} else if (value == "little") {
|
||||
dataEndianess = std::endian::little;
|
||||
defaultDataEndianess = std::endian::little;
|
||||
return true;
|
||||
} else if (value == "native") {
|
||||
dataEndianess = std::endian::native;
|
||||
defaultDataEndianess = std::endian::native;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
@ -308,7 +308,7 @@ namespace hex {
|
||||
return;
|
||||
}
|
||||
|
||||
hex::lang::Evaluator evaluator(this->m_dataProvider, dataEndianess);
|
||||
hex::lang::Evaluator evaluator(this->m_dataProvider, defaultDataEndianess);
|
||||
auto [evaluateResult, patternData] = evaluator.evaluate(ast);
|
||||
if (evaluateResult.failed()) {
|
||||
this->m_textEditor.SetErrorMarkers({ evaluator.getError() });
|
||||
|
Loading…
x
Reference in New Issue
Block a user