mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 16:15:43 +00:00
Calculate size and alignment in post processor
This commit is contained in:
parent
1264be4274
commit
7c51c26255
@ -1,5 +1,6 @@
|
|||||||
// Game: Modern Warfare 2 (IW4)
|
// Game: Modern Warfare 2 (IW4)
|
||||||
game IW4;
|
game IW4;
|
||||||
|
architecture x86;
|
||||||
|
|
||||||
// Game Assets
|
// Game Assets
|
||||||
asset PhysPreset ASSET_TYPE_PHYSPRESET;
|
asset PhysPreset ASSET_TYPE_PHYSPRESET;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
// Game: Black Ops 2 (T6)
|
// Game: Black Ops 2 (T6)
|
||||||
game T6;
|
game T6;
|
||||||
|
architecture x86;
|
||||||
|
|
||||||
// Game Assets
|
// Game Assets
|
||||||
asset PhysPreset ASSET_TYPE_PHYSPRESET;
|
asset PhysPreset ASSET_TYPE_PHYSPRESET;
|
||||||
|
@ -36,27 +36,21 @@ DefinitionWithMembers::DefinitionWithMembers(std::string _namespace, std::string
|
|||||||
|
|
||||||
unsigned DefinitionWithMembers::GetAlignment() const
|
unsigned DefinitionWithMembers::GetAlignment() const
|
||||||
{
|
{
|
||||||
assert(m_flags & FLAG_ALIGNMENT_CALCULATED);
|
assert(m_flags & FLAG_FIELDS_CALCULATED);
|
||||||
/*if ((m_flags & FLAG_ALIGNMENT_CALCULATED) == 0)
|
|
||||||
CalculateAlignment();*/
|
|
||||||
|
|
||||||
return m_alignment;
|
return m_alignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DefinitionWithMembers::GetForceAlignment() const
|
bool DefinitionWithMembers::GetForceAlignment() const
|
||||||
{
|
{
|
||||||
assert(m_flags & FLAG_ALIGNMENT_CALCULATED);
|
assert(m_flags & FLAG_FIELDS_CALCULATED);
|
||||||
/*if ((m_flags & FLAG_ALIGNMENT_CALCULATED) == 0)
|
|
||||||
CalculateAlignment();*/
|
|
||||||
|
|
||||||
return m_flags & FLAG_ALIGNMENT_FORCED;
|
return m_flags & FLAG_ALIGNMENT_FORCED;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned DefinitionWithMembers::GetSize() const
|
unsigned DefinitionWithMembers::GetSize() const
|
||||||
{
|
{
|
||||||
assert(m_flags & FLAG_SIZE_CALCULATED);
|
assert(m_flags & FLAG_FIELDS_CALCULATED);
|
||||||
/*if ((m_flags & FLAG_SIZE_CALCULATED) == 0)
|
|
||||||
CalculateSize();*/
|
|
||||||
|
|
||||||
return m_size;
|
return m_size;
|
||||||
}
|
}
|
||||||
|
@ -9,17 +9,14 @@
|
|||||||
class DefinitionWithMembers : public DataDefinition
|
class DefinitionWithMembers : public DataDefinition
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static constexpr int FLAG_SIZE_CALCULATED = 1 << 0;
|
static constexpr int FLAG_FIELDS_CALCULATED = 1 << 0;
|
||||||
static constexpr int FLAG_ALIGNMENT_CALCULATED = 1 << 1;
|
static constexpr int FLAG_FIELDS_CALCULATING = 1 << 1;
|
||||||
static constexpr int FLAG_ALIGNMENT_FORCED = 1 << 2;
|
static constexpr int FLAG_ALIGNMENT_FORCED = 1 << 2;
|
||||||
|
|
||||||
unsigned m_flags;
|
unsigned m_flags;
|
||||||
unsigned m_size;
|
unsigned m_size;
|
||||||
unsigned m_alignment;
|
unsigned m_alignment;
|
||||||
|
|
||||||
/*virtual void CalculateSize() = 0;
|
|
||||||
void CalculateAlignment();*/
|
|
||||||
|
|
||||||
bool m_has_alignment_override;
|
bool m_has_alignment_override;
|
||||||
bool m_anonymous;
|
bool m_anonymous;
|
||||||
|
|
||||||
|
@ -1,43 +1,5 @@
|
|||||||
#include "StructDefinition.h"
|
#include "StructDefinition.h"
|
||||||
|
|
||||||
#include "Utils/AlignmentUtils.h"
|
|
||||||
|
|
||||||
//void StructDefinition::CalculateSize()
|
|
||||||
//{
|
|
||||||
// m_size = 0;
|
|
||||||
// auto currentBitOffset = 0u;
|
|
||||||
//
|
|
||||||
// for(const auto& member : m_members)
|
|
||||||
// {
|
|
||||||
// if(member->m_type_declaration->m_has_custom_bit_size)
|
|
||||||
// {
|
|
||||||
// currentBitOffset += member->m_type_declaration->m_custom_bit_size;
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// if (currentBitOffset > 0)
|
|
||||||
// {
|
|
||||||
// currentBitOffset = AlignmentUtils::Align(currentBitOffset, 8u);
|
|
||||||
// m_size += currentBitOffset / 8;
|
|
||||||
// currentBitOffset = 0;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// m_size = AlignmentUtils::Align(m_size, member->GetForceAlignment() ? member->GetAlignment() : std::min(member->GetAlignment(), m_pack));
|
|
||||||
// m_size += member->m_type_declaration->GetSize();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (currentBitOffset > 0)
|
|
||||||
// {
|
|
||||||
// currentBitOffset = AlignmentUtils::Align(currentBitOffset, 8u);
|
|
||||||
// m_size += currentBitOffset / 8;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// m_size = AlignmentUtils::Align(m_size, GetAlignment());
|
|
||||||
//
|
|
||||||
// m_flags |= FLAG_SIZE_CALCULATED;
|
|
||||||
//}
|
|
||||||
|
|
||||||
StructDefinition::StructDefinition(std::string _namespace, std::string name, const int pack)
|
StructDefinition::StructDefinition(std::string _namespace, std::string name, const int pack)
|
||||||
: DefinitionWithMembers(std::move(_namespace), std::move(name), pack)
|
: DefinitionWithMembers(std::move(_namespace), std::move(name), pack)
|
||||||
{
|
{
|
||||||
|
@ -4,9 +4,6 @@
|
|||||||
|
|
||||||
class StructDefinition final : public DefinitionWithMembers
|
class StructDefinition final : public DefinitionWithMembers
|
||||||
{
|
{
|
||||||
//protected:
|
|
||||||
// void CalculateSize() override;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StructDefinition(std::string _namespace, std::string name, int pack);
|
StructDefinition(std::string _namespace, std::string name, int pack);
|
||||||
|
|
||||||
|
@ -16,75 +16,20 @@ TypeDeclaration::TypeDeclaration(const DataDefinition* type)
|
|||||||
assert(m_type != nullptr);
|
assert(m_type != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeDeclaration::CalculateSize()
|
unsigned TypeDeclaration::GetSize() const
|
||||||
{
|
{
|
||||||
auto currentSize = m_type->GetSize();
|
assert(m_flags & FLAG_FIELDS_CALCULATED);
|
||||||
|
|
||||||
for (auto i = m_declaration_modifiers.size(); i > 0; i--)
|
|
||||||
{
|
|
||||||
const auto& declarationModifier = m_declaration_modifiers[i - 1];
|
|
||||||
|
|
||||||
switch (declarationModifier->GetType())
|
|
||||||
{
|
|
||||||
case DeclarationModifierType::POINTER:
|
|
||||||
currentSize = POINTER_SIZE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DeclarationModifierType::ARRAY:
|
|
||||||
currentSize *= dynamic_cast<ArrayDeclarationModifier*>(declarationModifier.get())->m_size;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_flags |= FLAG_SIZE_CALCULATED;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TypeDeclaration::CalculateAlignment()
|
|
||||||
{
|
|
||||||
auto hasPointerModifier = false;
|
|
||||||
for (const auto& declarationModifier : m_declaration_modifiers)
|
|
||||||
{
|
|
||||||
if (declarationModifier->GetType() == DeclarationModifierType::POINTER)
|
|
||||||
{
|
|
||||||
hasPointerModifier = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasPointerModifier)
|
|
||||||
{
|
|
||||||
m_alignment = POINTER_SIZE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_alignment = m_type->GetAlignment();
|
|
||||||
if (m_type->GetForceAlignment())
|
|
||||||
m_flags |= FLAG_ALIGNMENT_FORCED;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_flags |= FLAG_ALIGNMENT_CALCULATED;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned TypeDeclaration::GetSize()
|
|
||||||
{
|
|
||||||
if ((m_flags & FLAG_SIZE_CALCULATED) == 0)
|
|
||||||
CalculateSize();
|
|
||||||
|
|
||||||
return m_size;
|
return m_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned TypeDeclaration::GetAlignment()
|
unsigned TypeDeclaration::GetAlignment() const
|
||||||
{
|
{
|
||||||
if ((m_flags & FLAG_ALIGNMENT_CALCULATED) == 0)
|
assert(m_flags & FLAG_FIELDS_CALCULATED);
|
||||||
CalculateAlignment();
|
|
||||||
|
|
||||||
return m_alignment;
|
return m_alignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeDeclaration::GetForceAlignment()
|
bool TypeDeclaration::GetForceAlignment() const
|
||||||
{
|
{
|
||||||
if ((m_flags & FLAG_ALIGNMENT_CALCULATED) == 0)
|
assert(m_flags & FLAG_FIELDS_CALCULATED);
|
||||||
CalculateAlignment();
|
|
||||||
|
|
||||||
return m_flags & FLAG_ALIGNMENT_FORCED;
|
return m_flags & FLAG_ALIGNMENT_FORCED;
|
||||||
}
|
}
|
||||||
|
@ -1,26 +1,22 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
|
#include "Utils/ClassUtils.h"
|
||||||
#include "DataDefinition.h"
|
#include "DataDefinition.h"
|
||||||
#include "DeclarationModifier.h"
|
#include "DeclarationModifier.h"
|
||||||
|
|
||||||
class TypeDeclaration
|
class TypeDeclaration
|
||||||
{
|
{
|
||||||
static constexpr unsigned POINTER_SIZE = sizeof(uint32_t); // TODO: Change this to support 64bit
|
public:
|
||||||
static constexpr int FLAG_SIZE_CALCULATED = 1 << 0;
|
static constexpr int FLAG_FIELDS_CALCULATED = 1 << 0;
|
||||||
static constexpr int FLAG_ALIGNMENT_CALCULATED = 1 << 1;
|
static constexpr int FLAG_ALIGNMENT_FORCED = 1 << 1;
|
||||||
static constexpr int FLAG_ALIGNMENT_FORCED = 1 << 2;
|
|
||||||
|
|
||||||
unsigned m_flags;
|
unsigned m_flags;
|
||||||
unsigned m_size;
|
unsigned m_size;
|
||||||
unsigned m_alignment;
|
unsigned m_alignment;
|
||||||
|
|
||||||
void CalculateSize();
|
|
||||||
void CalculateAlignment();
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit TypeDeclaration(const DataDefinition* type);
|
explicit TypeDeclaration(const DataDefinition* type);
|
||||||
|
|
||||||
bool m_is_const;
|
bool m_is_const;
|
||||||
@ -31,7 +27,7 @@ public:
|
|||||||
|
|
||||||
std::vector<std::unique_ptr<DeclarationModifier>> m_declaration_modifiers;
|
std::vector<std::unique_ptr<DeclarationModifier>> m_declaration_modifiers;
|
||||||
|
|
||||||
unsigned GetSize();
|
_NODISCARD unsigned GetSize() const;
|
||||||
unsigned GetAlignment();
|
_NODISCARD unsigned GetAlignment() const;
|
||||||
bool GetForceAlignment();
|
_NODISCARD bool GetForceAlignment() const;
|
||||||
};
|
};
|
||||||
|
@ -1,23 +1,5 @@
|
|||||||
#include "UnionDefinition.h"
|
#include "UnionDefinition.h"
|
||||||
|
|
||||||
#include "Utils/AlignmentUtils.h"
|
|
||||||
|
|
||||||
//void UnionDefinition::CalculateSize()
|
|
||||||
//{
|
|
||||||
// m_size = 0;
|
|
||||||
//
|
|
||||||
// for(const auto& member : m_members)
|
|
||||||
// {
|
|
||||||
// const auto memberSize = member->m_type_declaration->GetSize();
|
|
||||||
// if (memberSize > m_size)
|
|
||||||
// m_size = memberSize;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// m_size = AlignmentUtils::Align(m_size, GetAlignment());
|
|
||||||
//
|
|
||||||
// m_flags |= FLAG_SIZE_CALCULATED;
|
|
||||||
//}
|
|
||||||
|
|
||||||
UnionDefinition::UnionDefinition(std::string _namespace, std::string name, const int pack)
|
UnionDefinition::UnionDefinition(std::string _namespace, std::string name, const int pack)
|
||||||
: DefinitionWithMembers(std::move(_namespace), std::move(name), pack)
|
: DefinitionWithMembers(std::move(_namespace), std::move(name), pack)
|
||||||
{
|
{
|
||||||
|
@ -8,7 +8,7 @@ Variable::Variable(std::string name, std::unique_ptr<TypeDeclaration> typeDeclar
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned Variable::GetAlignment()
|
unsigned Variable::GetAlignment() const
|
||||||
{
|
{
|
||||||
if (m_has_alignment_override)
|
if (m_has_alignment_override)
|
||||||
return m_alignment_override;
|
return m_alignment_override;
|
||||||
@ -16,7 +16,7 @@ unsigned Variable::GetAlignment()
|
|||||||
return m_type_declaration->GetAlignment();
|
return m_type_declaration->GetAlignment();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Variable::GetForceAlignment()
|
bool Variable::GetForceAlignment() const
|
||||||
{
|
{
|
||||||
return m_has_alignment_override || m_type_declaration->GetForceAlignment();
|
return m_has_alignment_override || m_type_declaration->GetForceAlignment();
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,6 @@ public:
|
|||||||
|
|
||||||
Variable(std::string name, std::unique_ptr<TypeDeclaration> typeDeclaration);
|
Variable(std::string name, std::unique_ptr<TypeDeclaration> typeDeclaration);
|
||||||
|
|
||||||
unsigned GetAlignment();
|
unsigned GetAlignment() const;
|
||||||
bool GetForceAlignment();
|
bool GetForceAlignment() const;
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
enum class Architecture
|
||||||
|
{
|
||||||
|
UNKNOWN,
|
||||||
|
X86,
|
||||||
|
X64
|
||||||
|
};
|
@ -7,6 +7,13 @@ OperandDynamic::OperandDynamic(StructureInformation* structure)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OperandDynamic::OperandDynamic(StructureInformation* structure, std::vector<MemberInformation*> referencedMemberChain, std::vector<std::unique_ptr<IEvaluation>> arrayIndices)
|
||||||
|
: m_structure(structure),
|
||||||
|
m_referenced_member_chain(std::move(referencedMemberChain)),
|
||||||
|
m_array_indices(std::move(arrayIndices))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
EvaluationType OperandDynamic::GetType() const
|
EvaluationType OperandDynamic::GetType() const
|
||||||
{
|
{
|
||||||
return EvaluationType::OPERAND_DYNAMIC;
|
return EvaluationType::OPERAND_DYNAMIC;
|
||||||
|
@ -14,6 +14,7 @@ public:
|
|||||||
std::vector<std::unique_ptr<IEvaluation>> m_array_indices;
|
std::vector<std::unique_ptr<IEvaluation>> m_array_indices;
|
||||||
|
|
||||||
explicit OperandDynamic(StructureInformation* structure);
|
explicit OperandDynamic(StructureInformation* structure);
|
||||||
|
OperandDynamic(StructureInformation* structure, std::vector<MemberInformation*> referencedMemberChain, std::vector<std::unique_ptr<IEvaluation>> arrayIndices);
|
||||||
|
|
||||||
_NODISCARD EvaluationType GetType() const override;
|
_NODISCARD EvaluationType GetType() const override;
|
||||||
_NODISCARD bool IsStatic() const override;
|
_NODISCARD bool IsStatic() const override;
|
||||||
|
@ -6,8 +6,8 @@ OperandStatic::OperandStatic(const int value)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
OperandStatic::OperandStatic(const int value, EnumMember* enumMember)
|
OperandStatic::OperandStatic(EnumMember* enumMember)
|
||||||
: m_value(value),
|
: m_value(enumMember->m_value),
|
||||||
m_enum_member(enumMember)
|
m_enum_member(enumMember)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ public:
|
|||||||
EnumMember* const m_enum_member;
|
EnumMember* const m_enum_member;
|
||||||
|
|
||||||
explicit OperandStatic(int value);
|
explicit OperandStatic(int value);
|
||||||
OperandStatic(int value, EnumMember* enumMember);
|
explicit OperandStatic(EnumMember* enumMember);
|
||||||
|
|
||||||
_NODISCARD EvaluationType GetType() const override;
|
_NODISCARD EvaluationType GetType() const override;
|
||||||
_NODISCARD bool IsStatic() const override;
|
_NODISCARD bool IsStatic() const override;
|
||||||
|
@ -5,6 +5,13 @@ Operation::Operation(const OperationType* type)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Operation::Operation(const OperationType* type, std::unique_ptr<IEvaluation> operand1, std::unique_ptr<IEvaluation> operand2)
|
||||||
|
: m_operation_type(type),
|
||||||
|
m_operand1(std::move(operand1)),
|
||||||
|
m_operand2(std::move(operand2))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
EvaluationType Operation::GetType() const
|
EvaluationType Operation::GetType() const
|
||||||
{
|
{
|
||||||
return EvaluationType::OPERATION;
|
return EvaluationType::OPERATION;
|
||||||
|
@ -14,6 +14,7 @@ public:
|
|||||||
std::unique_ptr<IEvaluation> m_operand2;
|
std::unique_ptr<IEvaluation> m_operand2;
|
||||||
|
|
||||||
explicit Operation(const OperationType* type);
|
explicit Operation(const OperationType* type);
|
||||||
|
Operation(const OperationType* type, std::unique_ptr<IEvaluation> operand1, std::unique_ptr<IEvaluation> operand2);
|
||||||
|
|
||||||
_NODISCARD EvaluationType GetType() const override;
|
_NODISCARD EvaluationType GetType() const override;
|
||||||
_NODISCARD bool IsStatic() const override;
|
_NODISCARD bool IsStatic() const override;
|
||||||
|
@ -73,7 +73,7 @@ const OperationType* const OperationType::OPERATION_GREATER_THAN
|
|||||||
return op1 > op2 ? 1 : 0;
|
return op1 > op2 ? 1 : 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
const OperationType* const OperationType::OPERATION_GREATER_EQUALS_THAN
|
const OperationType* const OperationType::OPERATION_GREATER_EQUAL_THAN
|
||||||
= new OperationType(">=", OperationPrecedence::RELATIONAL_GREATER_LESS_THAN, [](auto op1, auto op2)
|
= new OperationType(">=", OperationPrecedence::RELATIONAL_GREATER_LESS_THAN, [](auto op1, auto op2)
|
||||||
{
|
{
|
||||||
return op1 >= op2 ? 1 : 0;
|
return op1 >= op2 ? 1 : 0;
|
||||||
@ -85,7 +85,7 @@ const OperationType* const OperationType::OPERATION_LESS_THAN
|
|||||||
return op1 < op2 ? 1 : 0;
|
return op1 < op2 ? 1 : 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
const OperationType* const OperationType::OPERATION_LESS_EQUALS_THAN
|
const OperationType* const OperationType::OPERATION_LESS_EQUAL_THAN
|
||||||
= new OperationType("<=", OperationPrecedence::RELATIONAL_GREATER_LESS_THAN, [](auto op1, auto op2)
|
= new OperationType("<=", OperationPrecedence::RELATIONAL_GREATER_LESS_THAN, [](auto op1, auto op2)
|
||||||
{
|
{
|
||||||
return op1 <= op2 ? 1 : 0;
|
return op1 <= op2 ? 1 : 0;
|
||||||
@ -97,7 +97,7 @@ const OperationType* const OperationType::OPERATION_EQUALS
|
|||||||
return op1 == op2 ? 1 : 0;
|
return op1 == op2 ? 1 : 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
const OperationType* const OperationType::OPERATION_NOT_EQUALS
|
const OperationType* const OperationType::OPERATION_NOT_EQUAL
|
||||||
= new OperationType("!=", OperationPrecedence::RELATIONAL_EQUALS, [](auto op1, auto op2)
|
= new OperationType("!=", OperationPrecedence::RELATIONAL_EQUALS, [](auto op1, auto op2)
|
||||||
{
|
{
|
||||||
return op1 != op2 ? 1 : 0;
|
return op1 != op2 ? 1 : 0;
|
||||||
@ -129,11 +129,11 @@ const OperationType* const OperationType::ALL_OPERATION_TYPES[]
|
|||||||
OPERATION_SHIFT_LEFT,
|
OPERATION_SHIFT_LEFT,
|
||||||
OPERATION_SHIFT_RIGHT,
|
OPERATION_SHIFT_RIGHT,
|
||||||
OPERATION_GREATER_THAN,
|
OPERATION_GREATER_THAN,
|
||||||
OPERATION_GREATER_EQUALS_THAN,
|
OPERATION_GREATER_EQUAL_THAN,
|
||||||
OPERATION_LESS_THAN,
|
OPERATION_LESS_THAN,
|
||||||
OPERATION_LESS_EQUALS_THAN,
|
OPERATION_LESS_EQUAL_THAN,
|
||||||
OPERATION_EQUALS,
|
OPERATION_EQUALS,
|
||||||
OPERATION_NOT_EQUALS,
|
OPERATION_NOT_EQUAL,
|
||||||
OPERATION_AND,
|
OPERATION_AND,
|
||||||
OPERATION_OR
|
OPERATION_OR
|
||||||
};
|
};
|
||||||
|
@ -40,11 +40,11 @@ public:
|
|||||||
static const OperationType* const OPERATION_SHIFT_LEFT;
|
static const OperationType* const OPERATION_SHIFT_LEFT;
|
||||||
static const OperationType* const OPERATION_SHIFT_RIGHT;
|
static const OperationType* const OPERATION_SHIFT_RIGHT;
|
||||||
static const OperationType* const OPERATION_GREATER_THAN;
|
static const OperationType* const OPERATION_GREATER_THAN;
|
||||||
static const OperationType* const OPERATION_GREATER_EQUALS_THAN;
|
static const OperationType* const OPERATION_GREATER_EQUAL_THAN;
|
||||||
static const OperationType* const OPERATION_LESS_THAN;
|
static const OperationType* const OPERATION_LESS_THAN;
|
||||||
static const OperationType* const OPERATION_LESS_EQUALS_THAN;
|
static const OperationType* const OPERATION_LESS_EQUAL_THAN;
|
||||||
static const OperationType* const OPERATION_EQUALS;
|
static const OperationType* const OPERATION_EQUALS;
|
||||||
static const OperationType* const OPERATION_NOT_EQUALS;
|
static const OperationType* const OPERATION_NOT_EQUAL;
|
||||||
static const OperationType* const OPERATION_AND;
|
static const OperationType* const OPERATION_AND;
|
||||||
static const OperationType* const OPERATION_OR;
|
static const OperationType* const OPERATION_OR;
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "CommandsFileReader.h"
|
#include "CommandsFileReader.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
@ -9,12 +10,14 @@
|
|||||||
#include "Parsing/Impl/DefinesStreamProxy.h"
|
#include "Parsing/Impl/DefinesStreamProxy.h"
|
||||||
#include "Parsing/Impl/IncludingStreamProxy.h"
|
#include "Parsing/Impl/IncludingStreamProxy.h"
|
||||||
#include "Parsing/Impl/ParserFilesystemStream.h"
|
#include "Parsing/Impl/ParserFilesystemStream.h"
|
||||||
|
#include "Parsing/PostProcessing/CalculateSizeAndAlignPostProcessor.h"
|
||||||
|
|
||||||
CommandsFileReader::CommandsFileReader(const ZoneCodeGeneratorArguments* args, std::string filename)
|
CommandsFileReader::CommandsFileReader(const ZoneCodeGeneratorArguments* args, std::string filename)
|
||||||
: m_args(args),
|
: m_args(args),
|
||||||
m_filename(std::move(filename)),
|
m_filename(std::move(filename)),
|
||||||
m_stream(nullptr)
|
m_stream(nullptr)
|
||||||
{
|
{
|
||||||
|
SetupPostProcessors();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandsFileReader::OpenBaseStream()
|
bool CommandsFileReader::OpenBaseStream()
|
||||||
@ -45,6 +48,11 @@ void CommandsFileReader::SetupStreamProxies()
|
|||||||
m_open_streams.emplace_back(std::move(definesProxy));
|
m_open_streams.emplace_back(std::move(definesProxy));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CommandsFileReader::SetupPostProcessors()
|
||||||
|
{
|
||||||
|
m_post_processors.emplace_back(std::make_unique<CalculateSizeAndAlignPostProcessor>());
|
||||||
|
}
|
||||||
|
|
||||||
bool CommandsFileReader::ReadCommandsFile(IDataRepository* repository)
|
bool CommandsFileReader::ReadCommandsFile(IDataRepository* repository)
|
||||||
{
|
{
|
||||||
std::cout << "Reading commands file: " << m_filename << std::endl;
|
std::cout << "Reading commands file: " << m_filename << std::endl;
|
||||||
@ -62,5 +70,11 @@ bool CommandsFileReader::ReadCommandsFile(IDataRepository* repository)
|
|||||||
const auto end = std::chrono::steady_clock::now();
|
const auto end = std::chrono::steady_clock::now();
|
||||||
std::cout << "Processing commands took " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms" << std::endl;
|
std::cout << "Processing commands took " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms" << std::endl;
|
||||||
|
|
||||||
return result;
|
if (!result)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return std::all_of(m_post_processors.begin(), m_post_processors.end(), [repository](const std::unique_ptr<IPostProcessor>& postProcessor)
|
||||||
|
{
|
||||||
|
return postProcessor->PostProcess(repository);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "ZoneCodeGeneratorArguments.h"
|
#include "ZoneCodeGeneratorArguments.h"
|
||||||
#include "Parsing/IParserLineStream.h"
|
#include "Parsing/IParserLineStream.h"
|
||||||
|
#include "Parsing/PostProcessing/IPostProcessor.h"
|
||||||
#include "Persistence/IDataRepository.h"
|
#include "Persistence/IDataRepository.h"
|
||||||
|
|
||||||
class CommandsFileReader
|
class CommandsFileReader
|
||||||
@ -17,8 +18,11 @@ class CommandsFileReader
|
|||||||
std::vector<std::unique_ptr<IParserLineStream>> m_open_streams;
|
std::vector<std::unique_ptr<IParserLineStream>> m_open_streams;
|
||||||
IParserLineStream* m_stream;
|
IParserLineStream* m_stream;
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<IPostProcessor>> m_post_processors;
|
||||||
|
|
||||||
bool OpenBaseStream();
|
bool OpenBaseStream();
|
||||||
void SetupStreamProxies();
|
void SetupStreamProxies();
|
||||||
|
void SetupPostProcessors();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CommandsFileReader(const ZoneCodeGeneratorArguments* args, std::string filename);
|
explicit CommandsFileReader(const ZoneCodeGeneratorArguments* args, std::string filename);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "CommandsParser.h"
|
#include "CommandsParser.h"
|
||||||
|
|
||||||
#include "Parsing/Commands/Sequence/SequenceAction.h"
|
#include "Parsing/Commands/Sequence/SequenceAction.h"
|
||||||
|
#include "Parsing/Commands/Sequence/SequenceArchitecture.h"
|
||||||
#include "Parsing/Commands/Sequence/SequenceArrayCount.h"
|
#include "Parsing/Commands/Sequence/SequenceArrayCount.h"
|
||||||
#include "Parsing/Commands/Sequence/SequenceArraySize.h"
|
#include "Parsing/Commands/Sequence/SequenceArraySize.h"
|
||||||
#include "Parsing/Commands/Sequence/SequenceAsset.h"
|
#include "Parsing/Commands/Sequence/SequenceAsset.h"
|
||||||
@ -26,6 +27,7 @@ const std::vector<CommandsParser::sequence_t*>& CommandsParser::GetTestsForState
|
|||||||
{
|
{
|
||||||
static std::vector<sequence_t*> tests({
|
static std::vector<sequence_t*> tests({
|
||||||
new SequenceAction(),
|
new SequenceAction(),
|
||||||
|
new SequenceArchitecture(),
|
||||||
new SequenceArrayCount(),
|
new SequenceArrayCount(),
|
||||||
new SequenceArraySize(),
|
new SequenceArraySize(),
|
||||||
new SequenceAsset(),
|
new SequenceAsset(),
|
||||||
|
@ -16,6 +16,11 @@ void CommandsParserState::AddBlock(std::unique_ptr<FastFileBlock> block) const
|
|||||||
m_repository->Add(std::move(block));
|
m_repository->Add(std::move(block));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CommandsParserState::SetArchitecture(const Architecture architecture) const
|
||||||
|
{
|
||||||
|
m_repository->SetArchitecture(architecture);
|
||||||
|
}
|
||||||
|
|
||||||
void CommandsParserState::SetGame(std::string gameName) const
|
void CommandsParserState::SetGame(std::string gameName) const
|
||||||
{
|
{
|
||||||
m_repository->SetGame(std::move(gameName));
|
m_repository->SetGame(std::move(gameName));
|
||||||
@ -31,12 +36,105 @@ void CommandsParserState::SetInUse(StructureInformation* structure)
|
|||||||
m_in_use = structure;
|
m_in_use = structure;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandsParserState::GetMembersFromParts(const std::string& typeNameValue, StructureInformation* baseType, std::vector<MemberInformation*>& members)
|
MemberInformation* CommandsParserState::GetMemberWithName(const std::string& memberName, StructureInformation* type)
|
||||||
{
|
{
|
||||||
|
for (const auto& member : type->m_ordered_members)
|
||||||
|
{
|
||||||
|
if (member->m_member->m_name == memberName)
|
||||||
|
{
|
||||||
|
return member.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CommandsParserState::GetNextTypenameSeparatorPos(const std::string& typeNameValue, const unsigned startPos, unsigned& separatorPos)
|
||||||
|
{
|
||||||
|
const auto typeNameValueSize = typeNameValue.size();
|
||||||
|
for (auto currentHead = startPos + 1; currentHead < typeNameValueSize; currentHead++)
|
||||||
|
{
|
||||||
|
if (typeNameValue[currentHead] == ':'
|
||||||
|
&& typeNameValue[currentHead - 1] == ':')
|
||||||
|
{
|
||||||
|
separatorPos = currentHead - 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandsParserState::GetTypenameAndMembersFromParts(const std::string& typeNameValue, StructureInformation*& structure, std::vector<MemberInformation*>& members)
|
bool CommandsParserState::ExtractMembersFromTypenameInternal(const std::string& typeNameValue, unsigned typeNameOffset, StructureInformation* type, std::vector<MemberInformation*>& members)
|
||||||
{
|
{
|
||||||
return false;
|
auto startOffset = typeNameOffset;
|
||||||
|
while (GetNextTypenameSeparatorPos(typeNameValue, typeNameOffset, typeNameOffset))
|
||||||
|
{
|
||||||
|
auto* foundMember = GetMemberWithName(std::string(typeNameValue, startOffset, typeNameOffset - startOffset), type);
|
||||||
|
|
||||||
|
if (foundMember == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
members.push_back(foundMember);
|
||||||
|
type = foundMember->m_type;
|
||||||
|
typeNameOffset += 2;
|
||||||
|
startOffset = typeNameOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* foundMember = GetMemberWithName(std::string(typeNameValue, startOffset, typeNameValue.size() - startOffset), type);
|
||||||
|
if (foundMember == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
members.push_back(foundMember);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CommandsParserState::GetMembersFromTypename(const std::string& typeNameValue, StructureInformation* baseType, std::vector<MemberInformation*>& members) const
|
||||||
|
{
|
||||||
|
return m_in_use != nullptr && ExtractMembersFromTypenameInternal(typeNameValue, 0, m_in_use, members)
|
||||||
|
|| ExtractMembersFromTypenameInternal(typeNameValue, 0, baseType, members);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CommandsParserState::GetTypenameAndMembersFromTypename(const std::string& typeNameValue, StructureInformation*& structure, std::vector<MemberInformation*>& members) const
|
||||||
|
{
|
||||||
|
if (m_in_use != nullptr)
|
||||||
|
{
|
||||||
|
if (ExtractMembersFromTypenameInternal(typeNameValue, 0, m_in_use, members))
|
||||||
|
{
|
||||||
|
structure = m_in_use;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
members.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
DataDefinition* foundDefinition = nullptr;
|
||||||
|
unsigned currentSeparatorPos = 0;
|
||||||
|
while (GetNextTypenameSeparatorPos(typeNameValue, currentSeparatorPos, currentSeparatorPos))
|
||||||
|
{
|
||||||
|
std::string currentTypename(typeNameValue, 0, currentSeparatorPos);
|
||||||
|
currentSeparatorPos += 2;
|
||||||
|
|
||||||
|
foundDefinition = m_repository->GetDataDefinitionByName(currentTypename);
|
||||||
|
if (foundDefinition != nullptr)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (foundDefinition == nullptr)
|
||||||
|
{
|
||||||
|
currentSeparatorPos = typeNameValue.size();
|
||||||
|
foundDefinition = m_repository->GetDataDefinitionByName(typeNameValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (foundDefinition == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto* definitionWithMembers = dynamic_cast<DefinitionWithMembers*>(foundDefinition);
|
||||||
|
if (definitionWithMembers == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
structure = m_repository->GetInformationFor(definitionWithMembers);
|
||||||
|
if (currentSeparatorPos >= typeNameValue.size())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return ExtractMembersFromTypenameInternal(typeNameValue, currentSeparatorPos, structure, members);
|
||||||
}
|
}
|
||||||
|
@ -11,17 +11,22 @@ class CommandsParserState
|
|||||||
IDataRepository* m_repository;
|
IDataRepository* m_repository;
|
||||||
StructureInformation* m_in_use;
|
StructureInformation* m_in_use;
|
||||||
|
|
||||||
|
static MemberInformation* GetMemberWithName(const std::string& memberName, StructureInformation* type);
|
||||||
|
static bool GetNextTypenameSeparatorPos(const std::string& typeNameValue, unsigned startPos, unsigned& separatorPos);
|
||||||
|
static bool ExtractMembersFromTypenameInternal(const std::string& typeNameValue, unsigned typeNameOffset, StructureInformation* type, std::vector<MemberInformation*>& members);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CommandsParserState(IDataRepository* repository);
|
explicit CommandsParserState(IDataRepository* repository);
|
||||||
|
|
||||||
_NODISCARD const IDataRepository* GetRepository() const;
|
_NODISCARD const IDataRepository* GetRepository() const;
|
||||||
|
|
||||||
void AddBlock(std::unique_ptr<FastFileBlock> block) const;
|
void AddBlock(std::unique_ptr<FastFileBlock> block) const;
|
||||||
|
void SetArchitecture(Architecture architecture) const;
|
||||||
void SetGame(std::string gameName) const;
|
void SetGame(std::string gameName) const;
|
||||||
|
|
||||||
_NODISCARD StructureInformation* GetInUse() const;
|
_NODISCARD StructureInformation* GetInUse() const;
|
||||||
void SetInUse(StructureInformation* structure);
|
void SetInUse(StructureInformation* structure);
|
||||||
|
|
||||||
bool GetMembersFromParts(const std::string& typeNameValue, StructureInformation* baseType, std::vector<MemberInformation*>& members);
|
bool GetMembersFromTypename(const std::string& typeNameValue, StructureInformation* baseType, std::vector<MemberInformation*>& members) const;
|
||||||
bool GetTypenameAndMembersFromParts(const std::string& typeNameValue, StructureInformation*& structure, std::vector<MemberInformation*>& members);
|
bool GetTypenameAndMembersFromTypename(const std::string& typeNameValue, StructureInformation*& structure, std::vector<MemberInformation*>& members) const;
|
||||||
};
|
};
|
||||||
|
@ -105,6 +105,13 @@ CommandsParserValue CommandsParserValue::TypeName(const TokenPos pos, std::strin
|
|||||||
return pv;
|
return pv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CommandsParserValue CommandsParserValue::OpType(const TokenPos pos, const OperationType* operationType)
|
||||||
|
{
|
||||||
|
CommandsParserValue pv(pos, CommandsParserValueType::OPERATION_TYPE);
|
||||||
|
pv.m_value.op_type_value = operationType;
|
||||||
|
return pv;
|
||||||
|
}
|
||||||
|
|
||||||
CommandsParserValue::CommandsParserValue(const TokenPos pos, const CommandsParserValueType type)
|
CommandsParserValue::CommandsParserValue(const TokenPos pos, const CommandsParserValueType type)
|
||||||
: m_pos(pos),
|
: m_pos(pos),
|
||||||
m_type(type),
|
m_type(type),
|
||||||
@ -201,3 +208,9 @@ std::string& CommandsParserValue::TypeNameValue() const
|
|||||||
assert(m_type == CommandsParserValueType::TYPE_NAME);
|
assert(m_type == CommandsParserValueType::TYPE_NAME);
|
||||||
return *m_value.string_value;
|
return *m_value.string_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const OperationType* CommandsParserValue::OpTypeValue() const
|
||||||
|
{
|
||||||
|
assert(m_type == CommandsParserValueType::OPERATION_TYPE);
|
||||||
|
return m_value.op_type_value;
|
||||||
|
}
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "Domain/Evaluation/OperationType.h"
|
||||||
#include "Parsing/IParserValue.h"
|
#include "Parsing/IParserValue.h"
|
||||||
#include "Utils/ClassUtils.h"
|
#include "Utils/ClassUtils.h"
|
||||||
#include "Parsing/TokenPos.h"
|
#include "Parsing/TokenPos.h"
|
||||||
@ -43,6 +45,7 @@ enum class CommandsParserValueType
|
|||||||
|
|
||||||
// Parser created
|
// Parser created
|
||||||
TYPE_NAME,
|
TYPE_NAME,
|
||||||
|
OPERATION_TYPE,
|
||||||
|
|
||||||
// End
|
// End
|
||||||
MAX
|
MAX
|
||||||
@ -60,6 +63,7 @@ public:
|
|||||||
int int_value;
|
int int_value;
|
||||||
double double_value;
|
double double_value;
|
||||||
std::string* string_value;
|
std::string* string_value;
|
||||||
|
const OperationType* op_type_value;
|
||||||
} m_value;
|
} m_value;
|
||||||
|
|
||||||
static CommandsParserValue Invalid(TokenPos pos);
|
static CommandsParserValue Invalid(TokenPos pos);
|
||||||
@ -78,6 +82,7 @@ public:
|
|||||||
static CommandsParserValue String(TokenPos pos, std::string* stringValue);
|
static CommandsParserValue String(TokenPos pos, std::string* stringValue);
|
||||||
static CommandsParserValue Identifier(TokenPos pos, std::string* identifier);
|
static CommandsParserValue Identifier(TokenPos pos, std::string* identifier);
|
||||||
static CommandsParserValue TypeName(TokenPos pos, std::string* typeName);
|
static CommandsParserValue TypeName(TokenPos pos, std::string* typeName);
|
||||||
|
static CommandsParserValue OpType(TokenPos pos, const OperationType* operationType);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CommandsParserValue(TokenPos pos, CommandsParserValueType type);
|
CommandsParserValue(TokenPos pos, CommandsParserValueType type);
|
||||||
@ -99,4 +104,5 @@ public:
|
|||||||
_NODISCARD std::string& IdentifierValue() const;
|
_NODISCARD std::string& IdentifierValue() const;
|
||||||
_NODISCARD size_t IdentifierHash() const;
|
_NODISCARD size_t IdentifierHash() const;
|
||||||
_NODISCARD std::string& TypeNameValue() const;
|
_NODISCARD std::string& TypeNameValue() const;
|
||||||
|
_NODISCARD const OperationType* OpTypeValue() const;
|
||||||
};
|
};
|
@ -1,8 +1,13 @@
|
|||||||
#include "CommandsCommonMatchers.h"
|
#include "CommandsCommonMatchers.h"
|
||||||
|
|
||||||
|
#include <list>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "CommandsMatcherFactory.h"
|
#include "CommandsMatcherFactory.h"
|
||||||
|
#include "Domain/Evaluation/OperandDynamic.h"
|
||||||
|
#include "Domain/Evaluation/OperandStatic.h"
|
||||||
|
#include "Domain/Evaluation/Operation.h"
|
||||||
|
|
||||||
std::unique_ptr<CommandsCommonMatchers::matcher_t> CommandsCommonMatchers::Typename(const supplier_t* labelSupplier)
|
std::unique_ptr<CommandsCommonMatchers::matcher_t> CommandsCommonMatchers::Typename(const supplier_t* labelSupplier)
|
||||||
{
|
{
|
||||||
@ -86,43 +91,23 @@ std::unique_ptr<CommandsCommonMatchers::matcher_t> CommandsCommonMatchers::Array
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr int TAG_OPERATION_TYPE = std::numeric_limits<int>::max() - 1;
|
static constexpr int TAG_OPERAND = std::numeric_limits<int>::max() - 1;
|
||||||
static constexpr int TAG_ADD = std::numeric_limits<int>::max() - 2;
|
static constexpr int TAG_OPERAND_TYPENAME = std::numeric_limits<int>::max() - 2;
|
||||||
static constexpr int TAG_MINUS = std::numeric_limits<int>::max() - 3;
|
static constexpr int TAG_OPERAND_ARRAY = std::numeric_limits<int>::max() - 3;
|
||||||
static constexpr int TAG_MULTIPLY = std::numeric_limits<int>::max() - 4;
|
static constexpr int TAG_OPERAND_ARRAY_END = std::numeric_limits<int>::max() - 4;
|
||||||
static constexpr int TAG_DIVIDE = std::numeric_limits<int>::max() - 5;
|
static constexpr int TAG_OPERAND_INTEGER = std::numeric_limits<int>::max() - 5;
|
||||||
static constexpr int TAG_REMAINDER = std::numeric_limits<int>::max() - 6;
|
static constexpr int TAG_EVALUATION_NOT = std::numeric_limits<int>::max() - 6;
|
||||||
static constexpr int TAG_BITWISE_AND = std::numeric_limits<int>::max() - 7;
|
static constexpr int TAG_EVALUATION_PARENTHESIS = std::numeric_limits<int>::max() - 7;
|
||||||
static constexpr int TAG_BITWISE_XOR = std::numeric_limits<int>::max() - 8;
|
static constexpr int TAG_EVALUATION_PARENTHESIS_END = std::numeric_limits<int>::max() - 8;
|
||||||
static constexpr int TAG_BITWISE_OR = std::numeric_limits<int>::max() - 9;
|
static constexpr int TAG_EVALUATION = std::numeric_limits<int>::max() - 9;
|
||||||
static constexpr int TAG_SHIFT_LEFT = std::numeric_limits<int>::max() - 10;
|
static constexpr int TAG_EVALUATION_OPERATION = std::numeric_limits<int>::max() - 10;
|
||||||
static constexpr int TAG_SHIFT_RIGHT = std::numeric_limits<int>::max() - 11;
|
|
||||||
static constexpr int TAG_GREATER_THAN = std::numeric_limits<int>::max() - 12;
|
|
||||||
static constexpr int TAG_GREATER_EQUAL = std::numeric_limits<int>::max() - 13;
|
|
||||||
static constexpr int TAG_LESS_THAN = std::numeric_limits<int>::max() - 14;
|
|
||||||
static constexpr int TAG_LESS_EQUAL = std::numeric_limits<int>::max() - 15;
|
|
||||||
static constexpr int TAG_EQUALS = std::numeric_limits<int>::max() - 16;
|
|
||||||
static constexpr int TAG_NOT_EQUAL = std::numeric_limits<int>::max() - 17;
|
|
||||||
static constexpr int TAG_LOGICAL_AND = std::numeric_limits<int>::max() - 18;
|
|
||||||
static constexpr int TAG_LOGICAL_OR = std::numeric_limits<int>::max() - 19;
|
|
||||||
static constexpr int TAG_OPERAND = std::numeric_limits<int>::max() - 20;
|
|
||||||
static constexpr int TAG_OPERAND_TYPENAME = std::numeric_limits<int>::max() - 21;
|
|
||||||
static constexpr int TAG_OPERAND_ARRAY = std::numeric_limits<int>::max() - 22;
|
|
||||||
static constexpr int TAG_OPERAND_ARRAY_END = std::numeric_limits<int>::max() - 23;
|
|
||||||
static constexpr int TAG_OPERAND_INTEGER = std::numeric_limits<int>::max() - 24;
|
|
||||||
static constexpr int TAG_OPERAND_FLOATING_POINT = std::numeric_limits<int>::max() - 25;
|
|
||||||
static constexpr int TAG_EVALUATION_NOT = std::numeric_limits<int>::max() - 26;
|
|
||||||
static constexpr int TAG_EVALUATION_PARENTHESIS = std::numeric_limits<int>::max() - 27;
|
|
||||||
static constexpr int TAG_EVALUATION_PARENTHESIS_END = std::numeric_limits<int>::max() - 28;
|
|
||||||
static constexpr int TAG_EVALUATION = std::numeric_limits<int>::max() - 29;
|
|
||||||
static constexpr int TAG_EVALUATION_OPERATION = std::numeric_limits<int>::max() - 30;
|
|
||||||
|
|
||||||
static constexpr int CAPTURE_OPERAND_TYPENAME = std::numeric_limits<int>::max() - 1;
|
static constexpr int CAPTURE_OPERAND_TYPENAME = std::numeric_limits<int>::max() - 1;
|
||||||
static constexpr int CAPTURE_OPERAND_ARRAY = std::numeric_limits<int>::max() - 1;
|
static constexpr int CAPTURE_OPERAND_ARRAY = std::numeric_limits<int>::max() - 1;
|
||||||
static constexpr int CAPTURE_OPERAND_INTEGER = std::numeric_limits<int>::max() - 2;
|
static constexpr int CAPTURE_OPERAND_INTEGER = std::numeric_limits<int>::max() - 2;
|
||||||
static constexpr int CAPTURE_OPERAND_FLOATING_POINT = std::numeric_limits<int>::max() - 3;
|
static constexpr int CAPTURE_OPERATION_TYPE = std::numeric_limits<int>::max() - 3;
|
||||||
|
|
||||||
std::unique_ptr<CommandsCommonMatchers::matcher_t> CommandsCommonMatchers::OperandArray(const supplier_t* labelSupplier)
|
std::unique_ptr<CommandsCommonMatchers::matcher_t> CommandsCommonMatchers::ParseOperandArray(const supplier_t* labelSupplier)
|
||||||
{
|
{
|
||||||
const CommandsMatcherFactory create(labelSupplier);
|
const CommandsMatcherFactory create(labelSupplier);
|
||||||
|
|
||||||
@ -133,44 +118,97 @@ std::unique_ptr<CommandsCommonMatchers::matcher_t> CommandsCommonMatchers::Opera
|
|||||||
}).Tag(TAG_OPERAND_ARRAY);
|
}).Tag(TAG_OPERAND_ARRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<CommandsCommonMatchers::matcher_t> CommandsCommonMatchers::Operand(const supplier_t* labelSupplier)
|
std::unique_ptr<CommandsCommonMatchers::matcher_t> CommandsCommonMatchers::ParseOperand(const supplier_t* labelSupplier)
|
||||||
{
|
{
|
||||||
const CommandsMatcherFactory create(labelSupplier);
|
const CommandsMatcherFactory create(labelSupplier);
|
||||||
|
|
||||||
return create.Or({
|
return create.Or({
|
||||||
create.And({
|
create.And({
|
||||||
create.Label(LABEL_TYPENAME).Capture(CAPTURE_OPERAND_TYPENAME),
|
create.Label(LABEL_TYPENAME).Capture(CAPTURE_OPERAND_TYPENAME),
|
||||||
create.OptionalLoop(MatcherFactoryWrapper<CommandsParserValue>(OperandArray(labelSupplier)).Capture(CAPTURE_OPERAND_ARRAY))
|
create.OptionalLoop(MatcherFactoryWrapper<CommandsParserValue>(ParseOperandArray(labelSupplier)).Capture(CAPTURE_OPERAND_ARRAY))
|
||||||
}).Tag(TAG_OPERAND_TYPENAME),
|
}).Tag(TAG_OPERAND_TYPENAME),
|
||||||
create.Integer().Tag(TAG_OPERAND_INTEGER).Capture(CAPTURE_OPERAND_INTEGER),
|
create.Integer().Tag(TAG_OPERAND_INTEGER).Capture(CAPTURE_OPERAND_INTEGER)
|
||||||
create.FloatingPoint().Tag(TAG_OPERAND_FLOATING_POINT).Capture(CAPTURE_OPERAND_FLOATING_POINT)
|
|
||||||
}).Tag(TAG_OPERAND);
|
}).Tag(TAG_OPERAND);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<CommandsCommonMatchers::matcher_t> CommandsCommonMatchers::OperationType(const supplier_t* labelSupplier)
|
std::unique_ptr<CommandsCommonMatchers::matcher_t> CommandsCommonMatchers::ParseOperationType(const supplier_t* labelSupplier)
|
||||||
{
|
{
|
||||||
const CommandsMatcherFactory create(labelSupplier);
|
const CommandsMatcherFactory create(labelSupplier);
|
||||||
|
|
||||||
return create.Or({
|
return create.Or({
|
||||||
create.Char('+').Tag(TAG_ADD),
|
create.Char('+').Transform([](CommandsMatcherFactory::token_list_t& values)
|
||||||
create.Char('-').Tag(TAG_MINUS),
|
{
|
||||||
create.Char('*').Tag(TAG_MULTIPLY),
|
return CommandsParserValue::OpType(values[0].get().GetPos(), OperationType::OPERATION_ADD);
|
||||||
create.Char('/').Tag(TAG_DIVIDE),
|
}),
|
||||||
create.Char('%').Tag(TAG_REMAINDER),
|
create.Char('-').Transform([](CommandsMatcherFactory::token_list_t& values)
|
||||||
create.Char('&').Tag(TAG_BITWISE_AND),
|
{
|
||||||
create.Char('^').Tag(TAG_BITWISE_XOR),
|
return CommandsParserValue::OpType(values[0].get().GetPos(), OperationType::OPERATION_SUBTRACT);
|
||||||
create.Char('|').Tag(TAG_BITWISE_OR),
|
}),
|
||||||
create.Type(CommandsParserValueType::SHIFT_LEFT).Tag(TAG_SHIFT_LEFT),
|
create.Char('*').Transform([](CommandsMatcherFactory::token_list_t& values)
|
||||||
create.Type(CommandsParserValueType::SHIFT_RIGHT).Tag(TAG_SHIFT_RIGHT),
|
{
|
||||||
create.Char('>').Tag(TAG_GREATER_THAN),
|
return CommandsParserValue::OpType(values[0].get().GetPos(), OperationType::OPERATION_MULTIPLY);
|
||||||
create.Type(CommandsParserValueType::GREATER_EQUAL).Tag(TAG_GREATER_EQUAL),
|
}),
|
||||||
create.Char('<').Tag(TAG_LESS_THAN),
|
create.Char('/').Transform([](CommandsMatcherFactory::token_list_t& values)
|
||||||
create.Type(CommandsParserValueType::LESS_EQUAL).Tag(TAG_LESS_EQUAL),
|
{
|
||||||
create.Type(CommandsParserValueType::EQUALS).Tag(TAG_EQUALS),
|
return CommandsParserValue::OpType(values[0].get().GetPos(), OperationType::OPERATION_DIVIDE);
|
||||||
create.Type(CommandsParserValueType::NOT_EQUAL).Tag(TAG_NOT_EQUAL),
|
}),
|
||||||
create.Type(CommandsParserValueType::LOGICAL_AND).Tag(TAG_LOGICAL_AND),
|
create.Char('%').Transform([](CommandsMatcherFactory::token_list_t& values)
|
||||||
create.Type(CommandsParserValueType::LOGICAL_OR).Tag(TAG_LOGICAL_OR)
|
{
|
||||||
}).Tag(TAG_OPERATION_TYPE);
|
return CommandsParserValue::OpType(values[0].get().GetPos(), OperationType::OPERATION_REMAINDER);
|
||||||
|
}),
|
||||||
|
create.Char('&').Transform([](CommandsMatcherFactory::token_list_t& values)
|
||||||
|
{
|
||||||
|
return CommandsParserValue::OpType(values[0].get().GetPos(), OperationType::OPERATION_BITWISE_AND);
|
||||||
|
}),
|
||||||
|
create.Char('^').Transform([](CommandsMatcherFactory::token_list_t& values)
|
||||||
|
{
|
||||||
|
return CommandsParserValue::OpType(values[0].get().GetPos(), OperationType::OPERATION_BITWISE_XOR);
|
||||||
|
}),
|
||||||
|
create.Char('|').Transform([](CommandsMatcherFactory::token_list_t& values)
|
||||||
|
{
|
||||||
|
return CommandsParserValue::OpType(values[0].get().GetPos(), OperationType::OPERATION_BITWISE_OR);
|
||||||
|
}),
|
||||||
|
create.Type(CommandsParserValueType::SHIFT_LEFT).Transform([](CommandsMatcherFactory::token_list_t& values)
|
||||||
|
{
|
||||||
|
return CommandsParserValue::OpType(values[0].get().GetPos(), OperationType::OPERATION_SHIFT_LEFT);
|
||||||
|
}),
|
||||||
|
create.Type(CommandsParserValueType::SHIFT_RIGHT).Transform([](CommandsMatcherFactory::token_list_t& values)
|
||||||
|
{
|
||||||
|
return CommandsParserValue::OpType(values[0].get().GetPos(), OperationType::OPERATION_SHIFT_RIGHT);
|
||||||
|
}),
|
||||||
|
create.Char('>').Transform([](CommandsMatcherFactory::token_list_t& values)
|
||||||
|
{
|
||||||
|
return CommandsParserValue::OpType(values[0].get().GetPos(), OperationType::OPERATION_GREATER_THAN);
|
||||||
|
}),
|
||||||
|
create.Type(CommandsParserValueType::GREATER_EQUAL).Transform([](CommandsMatcherFactory::token_list_t& values)
|
||||||
|
{
|
||||||
|
return CommandsParserValue::OpType(values[0].get().GetPos(), OperationType::OPERATION_GREATER_EQUAL_THAN);
|
||||||
|
}),
|
||||||
|
create.Char('<').Transform([](CommandsMatcherFactory::token_list_t& values)
|
||||||
|
{
|
||||||
|
return CommandsParserValue::OpType(values[0].get().GetPos(), OperationType::OPERATION_LESS_THAN);
|
||||||
|
}),
|
||||||
|
create.Type(CommandsParserValueType::LESS_EQUAL).Transform([](CommandsMatcherFactory::token_list_t& values)
|
||||||
|
{
|
||||||
|
return CommandsParserValue::OpType(values[0].get().GetPos(), OperationType::OPERATION_LESS_EQUAL_THAN);
|
||||||
|
}),
|
||||||
|
create.Type(CommandsParserValueType::EQUALS).Transform([](CommandsMatcherFactory::token_list_t& values)
|
||||||
|
{
|
||||||
|
return CommandsParserValue::OpType(values[0].get().GetPos(), OperationType::OPERATION_EQUALS);
|
||||||
|
}),
|
||||||
|
create.Type(CommandsParserValueType::NOT_EQUAL).Transform([](CommandsMatcherFactory::token_list_t& values)
|
||||||
|
{
|
||||||
|
return CommandsParserValue::OpType(values[0].get().GetPos(), OperationType::OPERATION_NOT_EQUAL);
|
||||||
|
}),
|
||||||
|
create.Type(CommandsParserValueType::LOGICAL_AND).Transform([](CommandsMatcherFactory::token_list_t& values)
|
||||||
|
{
|
||||||
|
return CommandsParserValue::OpType(values[0].get().GetPos(), OperationType::OPERATION_AND);
|
||||||
|
}),
|
||||||
|
create.Type(CommandsParserValueType::LOGICAL_OR).Transform([](CommandsMatcherFactory::token_list_t& values)
|
||||||
|
{
|
||||||
|
return CommandsParserValue::OpType(values[0].get().GetPos(), OperationType::OPERATION_OR);
|
||||||
|
})
|
||||||
|
}).Capture(CAPTURE_OPERATION_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<CommandsCommonMatchers::matcher_t> CommandsCommonMatchers::Evaluation(const supplier_t* labelSupplier)
|
std::unique_ptr<CommandsCommonMatchers::matcher_t> CommandsCommonMatchers::Evaluation(const supplier_t* labelSupplier)
|
||||||
@ -185,21 +223,123 @@ std::unique_ptr<CommandsCommonMatchers::matcher_t> CommandsCommonMatchers::Evalu
|
|||||||
create.Label(LABEL_EVALUATION),
|
create.Label(LABEL_EVALUATION),
|
||||||
create.Char(')').Tag(TAG_EVALUATION_PARENTHESIS_END)
|
create.Char(')').Tag(TAG_EVALUATION_PARENTHESIS_END)
|
||||||
}).Tag(TAG_EVALUATION_PARENTHESIS),
|
}).Tag(TAG_EVALUATION_PARENTHESIS),
|
||||||
Operand(labelSupplier)
|
ParseOperand(labelSupplier)
|
||||||
}),
|
}),
|
||||||
create.Optional(create.And({
|
create.Optional(create.And({
|
||||||
OperationType(labelSupplier),
|
ParseOperationType(labelSupplier),
|
||||||
create.Label(LABEL_EVALUATION)
|
create.Label(LABEL_EVALUATION)
|
||||||
})).Tag(TAG_EVALUATION_OPERATION)
|
}).Tag(TAG_EVALUATION_OPERATION))
|
||||||
}).Tag(TAG_EVALUATION);
|
}).Tag(TAG_EVALUATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<IEvaluation> CommandsCommonMatchers::ParseEvaluation(CommandsParserState* state, SequenceResult<CommandsParserValue>& result)
|
std::unique_ptr<IEvaluation> CommandsCommonMatchers::ProcessEvaluationInParenthesis(CommandsParserState* state, SequenceResult<CommandsParserValue>& result)
|
||||||
|
{
|
||||||
|
const auto isNegated = result.PeekAndRemoveIfTag(TAG_EVALUATION_NOT) == TAG_EVALUATION_NOT;
|
||||||
|
|
||||||
|
auto processedEvaluation = ProcessEvaluation(state, result);
|
||||||
|
|
||||||
|
if (result.PeekAndRemoveIfTag(TAG_EVALUATION_PARENTHESIS_END) != TAG_EVALUATION_PARENTHESIS_END)
|
||||||
|
throw ParsingException(TokenPos(), "Expected parenthesis end tag @ EvaluationInParenthesis");
|
||||||
|
|
||||||
|
if (isNegated)
|
||||||
|
processedEvaluation = std::make_unique<Operation>(OperationType::OPERATION_EQUALS, std::move(processedEvaluation), std::make_unique<OperandStatic>(0));
|
||||||
|
|
||||||
|
return processedEvaluation;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<IEvaluation> CommandsCommonMatchers::ProcessOperand(CommandsParserState* state, SequenceResult<CommandsParserValue>& result, StructureInformation* currentType)
|
||||||
|
{
|
||||||
|
const auto nextTag = result.NextTag();
|
||||||
|
|
||||||
|
if (nextTag == TAG_OPERAND_INTEGER)
|
||||||
|
{
|
||||||
|
return std::make_unique<OperandStatic>(result.NextCapture(CAPTURE_OPERAND_INTEGER).IntegerValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextTag == TAG_OPERAND_TYPENAME)
|
||||||
|
{
|
||||||
|
const auto& typeNameToken = result.NextCapture(CAPTURE_OPERAND_TYPENAME);
|
||||||
|
std::vector<std::unique_ptr<IEvaluation>> arrayIndexEvaluations;
|
||||||
|
|
||||||
|
while (result.PeekAndRemoveIfTag(TAG_OPERAND_ARRAY) == TAG_OPERAND_ARRAY)
|
||||||
|
{
|
||||||
|
arrayIndexEvaluations.emplace_back(ProcessEvaluation(state, result, currentType));
|
||||||
|
|
||||||
|
if (result.PeekAndRemoveIfTag(TAG_OPERAND_ARRAY_END) != TAG_OPERAND_ARRAY_END)
|
||||||
|
throw ParsingException(TokenPos(), "Expected operand array end tag @ Operand");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* foundEnumMember = state->GetRepository()->GetEnumMemberByName(typeNameToken.TypeNameValue());
|
||||||
|
if (foundEnumMember != nullptr)
|
||||||
|
return std::make_unique<OperandStatic>(foundEnumMember);
|
||||||
|
|
||||||
|
StructureInformation* structure;
|
||||||
|
std::vector<MemberInformation*> memberChain;
|
||||||
|
if (state->GetTypenameAndMembersFromTypename(typeNameToken.TypeNameValue(), structure, memberChain))
|
||||||
|
return std::make_unique<OperandDynamic>(structure, std::move(memberChain), std::move(arrayIndexEvaluations));
|
||||||
|
|
||||||
|
if (currentType != nullptr && state->GetMembersFromTypename(typeNameToken.TypeNameValue(), currentType, memberChain))
|
||||||
|
return std::make_unique<OperandDynamic>(currentType, std::move(memberChain), std::move(arrayIndexEvaluations));
|
||||||
|
|
||||||
|
throw ParsingException(typeNameToken.GetPos(), "Unknown type");
|
||||||
|
}
|
||||||
|
|
||||||
|
throw ParsingException(TokenPos(), "Unknown operand type @ Operand");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<IEvaluation> CommandsCommonMatchers::ProcessEvaluation(CommandsParserState* state, SequenceResult<CommandsParserValue>& result)
|
||||||
|
{
|
||||||
|
return ProcessEvaluation(state, result, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<IEvaluation> CommandsCommonMatchers::ProcessEvaluation(CommandsParserState* state, SequenceResult<CommandsParserValue>& result, StructureInformation* currentType)
|
||||||
{
|
{
|
||||||
if (result.PeekAndRemoveIfTag(TAG_EVALUATION) != TAG_EVALUATION)
|
if (result.PeekAndRemoveIfTag(TAG_EVALUATION) != TAG_EVALUATION)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
if (currentType == state->GetInUse())
|
||||||
|
currentType = nullptr;
|
||||||
|
|
||||||
|
std::list<std::unique_ptr<IEvaluation>> operands;
|
||||||
|
std::list<std::pair<unsigned, const OperationType*>> operators;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
std::unique_ptr<IEvaluation> firstStatementPart;
|
||||||
|
const auto nextTag = result.NextTag();
|
||||||
|
switch (nextTag)
|
||||||
|
{
|
||||||
|
case TAG_EVALUATION_PARENTHESIS:
|
||||||
|
firstStatementPart = ProcessEvaluationInParenthesis(state, result);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_OPERAND:
|
||||||
|
firstStatementPart = ProcessOperand(state, result, currentType);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw ParsingException(TokenPos(), "Invalid followup tag @ Evaluation");
|
||||||
|
}
|
||||||
|
operands.emplace_back(std::move(firstStatementPart));
|
||||||
|
|
||||||
|
if (result.PeekAndRemoveIfTag(TAG_EVALUATION_OPERATION) == TAG_EVALUATION_OPERATION)
|
||||||
|
operators.emplace_back(operators.size(), result.NextCapture(CAPTURE_OPERATION_TYPE).OpTypeValue());
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (result.PeekAndRemoveIfTag(TAG_EVALUATION) != TAG_EVALUATION)
|
||||||
|
throw ParsingException(TokenPos(), "Expected EvaluationTag @ Evaluation");
|
||||||
|
}
|
||||||
|
|
||||||
|
operators.sort([](const std::pair<unsigned, const OperationType*>& p1, const std::pair<unsigned, const OperationType*>& p2)
|
||||||
|
{
|
||||||
|
return p1.second->m_precedence > p2.second->m_precedence;
|
||||||
|
});
|
||||||
|
|
||||||
|
while (!operators.empty())
|
||||||
|
{
|
||||||
|
operators.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "Domain/Evaluation/IEvaluation.h"
|
#include "Domain/Evaluation/IEvaluation.h"
|
||||||
|
#include "Domain/Evaluation/OperationType.h"
|
||||||
#include "Parsing/Commands/Impl/CommandsParserState.h"
|
#include "Parsing/Commands/Impl/CommandsParserState.h"
|
||||||
#include "Parsing/Commands/Impl/CommandsParserValue.h"
|
#include "Parsing/Commands/Impl/CommandsParserValue.h"
|
||||||
#include "Parsing/Matcher/AbstractMatcher.h"
|
#include "Parsing/Matcher/AbstractMatcher.h"
|
||||||
@ -24,11 +25,15 @@ public:
|
|||||||
static std::unique_ptr<matcher_t> ArrayDef(const supplier_t* labelSupplier);
|
static std::unique_ptr<matcher_t> ArrayDef(const supplier_t* labelSupplier);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::unique_ptr<matcher_t> OperandArray(const supplier_t* labelSupplier);
|
static std::unique_ptr<matcher_t> ParseOperandArray(const supplier_t* labelSupplier);
|
||||||
static std::unique_ptr<matcher_t> Operand(const supplier_t* labelSupplier);
|
static std::unique_ptr<matcher_t> ParseOperand(const supplier_t* labelSupplier);
|
||||||
static std::unique_ptr<matcher_t> OperationType(const supplier_t* labelSupplier);
|
static std::unique_ptr<matcher_t> ParseOperationType(const supplier_t* labelSupplier);
|
||||||
|
|
||||||
|
static std::unique_ptr<IEvaluation> ProcessEvaluationInParenthesis(CommandsParserState* state, SequenceResult<CommandsParserValue>& result);
|
||||||
|
static std::unique_ptr<IEvaluation> ProcessOperand(CommandsParserState* state, SequenceResult<CommandsParserValue>& result, StructureInformation* currentType);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static std::unique_ptr<matcher_t> Evaluation(const supplier_t* labelSupplier);
|
static std::unique_ptr<matcher_t> Evaluation(const supplier_t* labelSupplier);
|
||||||
static std::unique_ptr<IEvaluation> ParseEvaluation(CommandsParserState* state, SequenceResult<CommandsParserValue>& result);
|
static std::unique_ptr<IEvaluation> ProcessEvaluation(CommandsParserState* state, SequenceResult<CommandsParserValue>& result);
|
||||||
|
static std::unique_ptr<IEvaluation> ProcessEvaluation(CommandsParserState* state, SequenceResult<CommandsParserValue>& result, StructureInformation* currentType);
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
#include "SequenceArchitecture.h"
|
||||||
|
|
||||||
|
#include "Parsing/Commands/Matcher/CommandsMatcherFactory.h"
|
||||||
|
#include "Parsing/Commands/Matcher/CommandsCommonMatchers.h"
|
||||||
|
|
||||||
|
SequenceArchitecture::SequenceArchitecture()
|
||||||
|
{
|
||||||
|
const CommandsMatcherFactory create(this);
|
||||||
|
|
||||||
|
AddMatchers({
|
||||||
|
create.Keyword("architecture"),
|
||||||
|
create.Or({
|
||||||
|
create.Keyword("x86").Tag(TAG_X86),
|
||||||
|
create.Keyword("x64").Tag(TAG_X64)
|
||||||
|
}),
|
||||||
|
create.Char(';')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void SequenceArchitecture::ProcessMatch(CommandsParserState* state, SequenceResult<CommandsParserValue>& result) const
|
||||||
|
{
|
||||||
|
switch (result.NextTag())
|
||||||
|
{
|
||||||
|
case TAG_X86:
|
||||||
|
state->SetArchitecture(Architecture::X86);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_X64:
|
||||||
|
state->SetArchitecture(Architecture::X64);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw ParsingException(TokenPos(), "Unknown architecture!");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Parsing/Commands/Impl/CommandsParser.h"
|
||||||
|
|
||||||
|
class SequenceArchitecture final : public CommandsParser::sequence_t
|
||||||
|
{
|
||||||
|
static constexpr auto TAG_X86 = 1;
|
||||||
|
static constexpr auto TAG_X64 = 2;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void ProcessMatch(CommandsParserState* state, SequenceResult<CommandsParserValue>& result) const override;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SequenceArchitecture();
|
||||||
|
};
|
@ -1,5 +1,7 @@
|
|||||||
#include "SequenceArrayCount.h"
|
#include "SequenceArrayCount.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "Domain/Definition/ArrayDeclarationModifier.h"
|
||||||
#include "Parsing/Commands/Matcher/CommandsMatcherFactory.h"
|
#include "Parsing/Commands/Matcher/CommandsMatcherFactory.h"
|
||||||
#include "Parsing/Commands/Matcher/CommandsCommonMatchers.h"
|
#include "Parsing/Commands/Matcher/CommandsCommonMatchers.h"
|
||||||
|
|
||||||
@ -13,11 +15,38 @@ SequenceArrayCount::SequenceArrayCount()
|
|||||||
create.Keyword("set"),
|
create.Keyword("set"),
|
||||||
create.Keyword("arraycount"),
|
create.Keyword("arraycount"),
|
||||||
create.Label(CommandsCommonMatchers::LABEL_TYPENAME).Capture(CAPTURE_TYPE),
|
create.Label(CommandsCommonMatchers::LABEL_TYPENAME).Capture(CAPTURE_TYPE),
|
||||||
create.Label(CommandsCommonMatchers::LABEL_EVALUATION).Capture(CAPTURE_EVALUATION),
|
create.Label(CommandsCommonMatchers::LABEL_EVALUATION),
|
||||||
create.Char(';')
|
create.Char(';')
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void SequenceArrayCount::ProcessMatch(CommandsParserState* state, SequenceResult<CommandsParserValue>& result) const
|
void SequenceArrayCount::ProcessMatch(CommandsParserState* state, SequenceResult<CommandsParserValue>& result) const
|
||||||
{
|
{
|
||||||
|
const auto& typeNameToken = result.NextCapture(CAPTURE_TYPE);
|
||||||
|
|
||||||
|
StructureInformation* structure;
|
||||||
|
std::vector<MemberInformation*> memberChain;
|
||||||
|
if (!state->GetTypenameAndMembersFromTypename(typeNameToken.TypeNameValue(), structure, memberChain))
|
||||||
|
throw ParsingException(typeNameToken.GetPos(), "Unknown type");
|
||||||
|
|
||||||
|
if(memberChain.empty())
|
||||||
|
throw ParsingException(typeNameToken.GetPos(), "Must specify type with member");
|
||||||
|
|
||||||
|
const auto& memberDeclarationModifiers = memberChain.back()->m_member->m_type_declaration->m_declaration_modifiers;
|
||||||
|
ArrayDeclarationModifier* arrayModifier = nullptr;
|
||||||
|
for (const auto& modifier : memberDeclarationModifiers)
|
||||||
|
{
|
||||||
|
if (modifier->GetType() == DeclarationModifierType::ARRAY)
|
||||||
|
{
|
||||||
|
arrayModifier = dynamic_cast<ArrayDeclarationModifier*>(modifier.get());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arrayModifier == nullptr)
|
||||||
|
throw ParsingException(typeNameToken.GetPos(), "Specified member is not an array");
|
||||||
|
|
||||||
|
auto evaluation = CommandsCommonMatchers::ProcessEvaluation(state, result, structure);
|
||||||
|
|
||||||
|
arrayModifier->m_dynamic_count_evaluation = std::move(evaluation);
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
class SequenceArrayCount final : public CommandsParser::sequence_t
|
class SequenceArrayCount final : public CommandsParser::sequence_t
|
||||||
{
|
{
|
||||||
static constexpr auto CAPTURE_TYPE = 1;
|
static constexpr auto CAPTURE_TYPE = 1;
|
||||||
static constexpr auto CAPTURE_EVALUATION = 2;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void ProcessMatch(CommandsParserState* state, SequenceResult<CommandsParserValue>& result) const override;
|
void ProcessMatch(CommandsParserState* state, SequenceResult<CommandsParserValue>& result) const override;
|
||||||
|
@ -17,4 +17,14 @@ SequenceUse::SequenceUse()
|
|||||||
|
|
||||||
void SequenceUse::ProcessMatch(CommandsParserState* state, SequenceResult<CommandsParserValue>& result) const
|
void SequenceUse::ProcessMatch(CommandsParserState* state, SequenceResult<CommandsParserValue>& result) const
|
||||||
{
|
{
|
||||||
|
const auto& typeNameToken = result.NextCapture(CAPTURE_TYPE);
|
||||||
|
auto* definition = state->GetRepository()->GetDataDefinitionByName(typeNameToken.TypeNameValue());
|
||||||
|
if (definition == nullptr)
|
||||||
|
throw ParsingException(typeNameToken.GetPos(), "Unknown type");
|
||||||
|
|
||||||
|
auto* definitionWithMembers = dynamic_cast<DefinitionWithMembers*>(definition);
|
||||||
|
if (definitionWithMembers == nullptr)
|
||||||
|
throw ParsingException(typeNameToken.GetPos(), "Type must be able to have members");
|
||||||
|
|
||||||
|
state->SetInUse(state->GetRepository()->GetInformationFor(definitionWithMembers));
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ void HeaderBlockStruct::SetBlockName(const TokenPos& nameTokenPos, std::string n
|
|||||||
|
|
||||||
bool HeaderBlockStruct::IsDefiningVariable()
|
bool HeaderBlockStruct::IsDefiningVariable()
|
||||||
{
|
{
|
||||||
return !m_is_typedef && !m_variable_name.empty();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataDefinition* HeaderBlockStruct::GetVariableType()
|
DataDefinition* HeaderBlockStruct::GetVariableType()
|
||||||
|
@ -102,7 +102,7 @@ void HeaderBlockUnion::SetBlockName(const TokenPos& nameTokenPos, std::string na
|
|||||||
|
|
||||||
bool HeaderBlockUnion::IsDefiningVariable()
|
bool HeaderBlockUnion::IsDefiningVariable()
|
||||||
{
|
{
|
||||||
return !m_is_typedef && !m_variable_name.empty();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataDefinition* HeaderBlockUnion::GetVariableType()
|
DataDefinition* HeaderBlockUnion::GetVariableType()
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "HeaderFileReader.h"
|
#include "HeaderFileReader.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
@ -11,6 +11,9 @@
|
|||||||
#include "Parsing/Impl/IncludingStreamProxy.h"
|
#include "Parsing/Impl/IncludingStreamProxy.h"
|
||||||
#include "Parsing/Impl/PackDefinitionStreamProxy.h"
|
#include "Parsing/Impl/PackDefinitionStreamProxy.h"
|
||||||
#include "Parsing/Impl/ParserFilesystemStream.h"
|
#include "Parsing/Impl/ParserFilesystemStream.h"
|
||||||
|
#include "Parsing/PostProcessing/CreateMemberInformationPostProcessor.h"
|
||||||
|
#include "Parsing/PostProcessing/CreateStructureInformationPostProcessor.h"
|
||||||
|
#include "Parsing/PostProcessing/IPostProcessor.h"
|
||||||
|
|
||||||
HeaderFileReader::HeaderFileReader(const ZoneCodeGeneratorArguments* args, std::string filename)
|
HeaderFileReader::HeaderFileReader(const ZoneCodeGeneratorArguments* args, std::string filename)
|
||||||
: m_args(args),
|
: m_args(args),
|
||||||
@ -18,6 +21,7 @@ HeaderFileReader::HeaderFileReader(const ZoneCodeGeneratorArguments* args, std::
|
|||||||
m_pack_value_supplier(nullptr),
|
m_pack_value_supplier(nullptr),
|
||||||
m_stream(nullptr)
|
m_stream(nullptr)
|
||||||
{
|
{
|
||||||
|
SetupPostProcessors();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HeaderFileReader::OpenBaseStream()
|
bool HeaderFileReader::OpenBaseStream()
|
||||||
@ -51,6 +55,13 @@ void HeaderFileReader::SetupStreamProxies()
|
|||||||
m_open_streams.emplace_back(std::move(definesProxy));
|
m_open_streams.emplace_back(std::move(definesProxy));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HeaderFileReader::SetupPostProcessors()
|
||||||
|
{
|
||||||
|
// Order is important
|
||||||
|
m_post_processors.emplace_back(std::make_unique<CreateStructureInformationPostProcessor>());
|
||||||
|
m_post_processors.emplace_back(std::make_unique<CreateMemberInformationPostProcessor>());
|
||||||
|
}
|
||||||
|
|
||||||
bool HeaderFileReader::ReadHeaderFile(IDataRepository* repository)
|
bool HeaderFileReader::ReadHeaderFile(IDataRepository* repository)
|
||||||
{
|
{
|
||||||
std::cout << "Reading header file: " << m_filename << std::endl;
|
std::cout << "Reading header file: " << m_filename << std::endl;
|
||||||
@ -64,11 +75,17 @@ bool HeaderFileReader::ReadHeaderFile(IDataRepository* repository)
|
|||||||
const auto parser = std::make_unique<HeaderParser>(lexer.get(), m_pack_value_supplier);
|
const auto parser = std::make_unique<HeaderParser>(lexer.get(), m_pack_value_supplier);
|
||||||
|
|
||||||
const auto start = std::chrono::steady_clock::now();
|
const auto start = std::chrono::steady_clock::now();
|
||||||
const auto result = parser->Parse();
|
auto result = parser->Parse();
|
||||||
if (result)
|
if (result)
|
||||||
parser->SaveToRepository(repository);
|
result = parser->SaveToRepository(repository);
|
||||||
const auto end = std::chrono::steady_clock::now();
|
const auto end = std::chrono::steady_clock::now();
|
||||||
std::cout << "Processing header took " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms" << std::endl;
|
std::cout << "Processing header took " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms" << std::endl;
|
||||||
|
|
||||||
return result;
|
if (!result)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return std::all_of(m_post_processors.begin(), m_post_processors.end(), [repository](const std::unique_ptr<IPostProcessor>& postProcessor)
|
||||||
|
{
|
||||||
|
return postProcessor->PostProcess(repository);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "ZoneCodeGeneratorArguments.h"
|
#include "ZoneCodeGeneratorArguments.h"
|
||||||
#include "Parsing/IPackValueSupplier.h"
|
#include "Parsing/IPackValueSupplier.h"
|
||||||
#include "Parsing/IParserLineStream.h"
|
#include "Parsing/IParserLineStream.h"
|
||||||
|
#include "Parsing/PostProcessing/IPostProcessor.h"
|
||||||
#include "Persistence/IDataRepository.h"
|
#include "Persistence/IDataRepository.h"
|
||||||
|
|
||||||
class HeaderFileReader
|
class HeaderFileReader
|
||||||
@ -19,8 +20,11 @@ class HeaderFileReader
|
|||||||
const IPackValueSupplier* m_pack_value_supplier;
|
const IPackValueSupplier* m_pack_value_supplier;
|
||||||
IParserLineStream* m_stream;
|
IParserLineStream* m_stream;
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<IPostProcessor>> m_post_processors;
|
||||||
|
|
||||||
bool OpenBaseStream();
|
bool OpenBaseStream();
|
||||||
void SetupStreamProxies();
|
void SetupStreamProxies();
|
||||||
|
void SetupPostProcessors();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HeaderFileReader(const ZoneCodeGeneratorArguments* args, std::string filename);
|
HeaderFileReader(const ZoneCodeGeneratorArguments* args, std::string filename);
|
||||||
|
@ -0,0 +1,300 @@
|
|||||||
|
#include "CalculateSizeAndAlignPostProcessor.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <iostream>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "Domain/Definition/ArrayDeclarationModifier.h"
|
||||||
|
#include "Utils/AlignmentUtils.h"
|
||||||
|
|
||||||
|
unsigned CalculateSizeAndAlignPostProcessor::GetPointerSizeForArchitecture(const Architecture architecture)
|
||||||
|
{
|
||||||
|
switch (architecture)
|
||||||
|
{
|
||||||
|
case Architecture::X86:
|
||||||
|
return sizeof(uint32_t);
|
||||||
|
|
||||||
|
case Architecture::X64:
|
||||||
|
return sizeof(uint64_t);
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
return sizeof(uint32_t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CalculateSizeAndAlignPostProcessor::CalculateAlign(IDataRepository* repository, TypeDeclaration* declaration)
|
||||||
|
{
|
||||||
|
auto hasPointerModifier = false;
|
||||||
|
for (const auto& declarationModifier : declaration->m_declaration_modifiers)
|
||||||
|
{
|
||||||
|
if (declarationModifier->GetType() == DeclarationModifierType::POINTER)
|
||||||
|
{
|
||||||
|
hasPointerModifier = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasPointerModifier)
|
||||||
|
{
|
||||||
|
declaration->m_alignment = GetPointerSizeForArchitecture(repository->GetArchitecture());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!CalculateFieldsIfNecessary(repository, declaration->m_type))
|
||||||
|
return false;
|
||||||
|
declaration->m_alignment = declaration->m_type->GetAlignment();
|
||||||
|
if (declaration->m_type->GetForceAlignment())
|
||||||
|
declaration->m_flags |= TypeDeclaration::FLAG_ALIGNMENT_FORCED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CalculateSizeAndAlignPostProcessor::CalculateAlign(IDataRepository* repository, DefinitionWithMembers* definition)
|
||||||
|
{
|
||||||
|
if (definition->m_has_alignment_override)
|
||||||
|
{
|
||||||
|
definition->m_flags |= DefinitionWithMembers::FLAG_ALIGNMENT_FORCED;
|
||||||
|
definition->m_alignment = definition->m_alignment_override;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
definition->m_alignment = 0;
|
||||||
|
for (const auto& member : definition->m_members)
|
||||||
|
{
|
||||||
|
if (!CalculateFields(repository, member->m_type_declaration.get()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const auto memberAlignment = member->GetAlignment();
|
||||||
|
if (memberAlignment > definition->m_alignment)
|
||||||
|
definition->m_alignment = memberAlignment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CalculateSizeAndAlignPostProcessor::CalculateSize(IDataRepository* repository, TypeDeclaration* declaration)
|
||||||
|
{
|
||||||
|
if (declaration->m_declaration_modifiers.empty())
|
||||||
|
{
|
||||||
|
if (!CalculateFieldsIfNecessary(repository, declaration->m_type))
|
||||||
|
return false;
|
||||||
|
declaration->m_size = declaration->m_type->GetSize();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto currentSize = 0u;
|
||||||
|
|
||||||
|
// If the first modifier is a pointer we do not need the actual type size
|
||||||
|
if (declaration->m_declaration_modifiers.back()->GetType() != DeclarationModifierType::POINTER)
|
||||||
|
{
|
||||||
|
if (!CalculateFieldsIfNecessary(repository, declaration->m_type))
|
||||||
|
return false;
|
||||||
|
currentSize = declaration->m_type->GetSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto i = declaration->m_declaration_modifiers.size(); i > 0; i--)
|
||||||
|
{
|
||||||
|
const auto& declarationModifier = declaration->m_declaration_modifiers[i - 1];
|
||||||
|
|
||||||
|
switch (declarationModifier->GetType())
|
||||||
|
{
|
||||||
|
case DeclarationModifierType::POINTER:
|
||||||
|
currentSize = GetPointerSizeForArchitecture(repository->GetArchitecture());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DeclarationModifierType::ARRAY:
|
||||||
|
currentSize *= dynamic_cast<ArrayDeclarationModifier*>(declarationModifier.get())->m_size;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declaration->m_size = currentSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CalculateSizeAndAlignPostProcessor::CalculateSize(IDataRepository* repository, StructDefinition* definition)
|
||||||
|
{
|
||||||
|
definition->m_size = 0;
|
||||||
|
auto currentBitOffset = 0u;
|
||||||
|
|
||||||
|
for (const auto& member : definition->m_members)
|
||||||
|
{
|
||||||
|
if (!CalculateFields(repository, member->m_type_declaration.get()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (member->m_type_declaration->m_has_custom_bit_size)
|
||||||
|
{
|
||||||
|
currentBitOffset += member->m_type_declaration->m_custom_bit_size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (currentBitOffset > 0)
|
||||||
|
{
|
||||||
|
currentBitOffset = AlignmentUtils::Align(currentBitOffset, 8u);
|
||||||
|
definition->m_size += currentBitOffset / 8;
|
||||||
|
currentBitOffset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
definition->m_size = AlignmentUtils::Align(definition->m_size, member->GetForceAlignment() ? member->GetAlignment() : std::min(member->GetAlignment(), definition->m_pack));
|
||||||
|
definition->m_size += member->m_type_declaration->GetSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentBitOffset > 0)
|
||||||
|
{
|
||||||
|
currentBitOffset = AlignmentUtils::Align(currentBitOffset, 8u);
|
||||||
|
definition->m_size += currentBitOffset / 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
definition->m_size = AlignmentUtils::Align(definition->m_size, definition->m_alignment);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CalculateSizeAndAlignPostProcessor::CalculateSize(IDataRepository* repository, UnionDefinition* definition)
|
||||||
|
{
|
||||||
|
definition->m_size = 0;
|
||||||
|
|
||||||
|
for (const auto& member : definition->m_members)
|
||||||
|
{
|
||||||
|
if (!CalculateFields(repository, member->m_type_declaration.get()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const auto memberSize = member->m_type_declaration->GetSize();
|
||||||
|
if (memberSize > definition->m_size)
|
||||||
|
definition->m_size = memberSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
definition->m_size = AlignmentUtils::Align(definition->m_size, definition->m_alignment);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CalculateSizeAndAlignPostProcessor::CalculateFields(IDataRepository* repository, TypeDeclaration* declaration)
|
||||||
|
{
|
||||||
|
if (declaration->m_flags & TypeDeclaration::FLAG_FIELDS_CALCULATED)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if(!CalculateAlign(repository, declaration)
|
||||||
|
|| !CalculateSize(repository, declaration))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
declaration->m_flags |= TypeDeclaration::FLAG_FIELDS_CALCULATED;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CalculateSizeAndAlignPostProcessor::CalculateFields(IDataRepository* repository, StructDefinition* structDefinition)
|
||||||
|
{
|
||||||
|
if (structDefinition->m_flags & DefinitionWithMembers::FLAG_FIELDS_CALCULATED)
|
||||||
|
return true;
|
||||||
|
if (structDefinition->m_flags & DefinitionWithMembers::FLAG_FIELDS_CALCULATING)
|
||||||
|
{
|
||||||
|
std::cout << "Detected circular dependency:\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
structDefinition->m_flags |= DefinitionWithMembers::FLAG_FIELDS_CALCULATING;
|
||||||
|
|
||||||
|
if (!CalculateAlign(repository, structDefinition)
|
||||||
|
|| !CalculateSize(repository, structDefinition))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
structDefinition->m_flags &= ~DefinitionWithMembers::FLAG_FIELDS_CALCULATING;
|
||||||
|
structDefinition->m_flags |= DefinitionWithMembers::FLAG_FIELDS_CALCULATED;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CalculateSizeAndAlignPostProcessor::CalculateFields(IDataRepository* repository, UnionDefinition* unionDefinition)
|
||||||
|
{
|
||||||
|
if (unionDefinition->m_flags & DefinitionWithMembers::FLAG_FIELDS_CALCULATED)
|
||||||
|
return true;
|
||||||
|
if (unionDefinition->m_flags & DefinitionWithMembers::FLAG_FIELDS_CALCULATING)
|
||||||
|
{
|
||||||
|
std::cout << "Detected circular dependency:\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unionDefinition->m_flags |= DefinitionWithMembers::FLAG_FIELDS_CALCULATING;
|
||||||
|
|
||||||
|
if (!CalculateAlign(repository, unionDefinition)
|
||||||
|
|| !CalculateSize(repository, unionDefinition))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unionDefinition->m_flags &= ~DefinitionWithMembers::FLAG_FIELDS_CALCULATING;
|
||||||
|
unionDefinition->m_flags |= DefinitionWithMembers::FLAG_FIELDS_CALCULATED;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CalculateSizeAndAlignPostProcessor::CalculateFieldsIfNecessary(IDataRepository* repository, const DataDefinition* definition)
|
||||||
|
{
|
||||||
|
if(definition->GetType() == DataDefinitionType::STRUCT)
|
||||||
|
{
|
||||||
|
// We can do a const cast here because the only reason that field is const anyway is because it could be a base type
|
||||||
|
return CalculateFields(repository, dynamic_cast<StructDefinition*>(const_cast<DataDefinition*>(definition)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(definition->GetType() == DataDefinitionType::UNION)
|
||||||
|
{
|
||||||
|
// We can do a const cast here because the only reason that field is const anyway is because it could be a base type
|
||||||
|
return CalculateFields(repository, dynamic_cast<UnionDefinition*>(const_cast<DataDefinition*>(definition)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(definition->GetType() == DataDefinitionType::TYPEDEF)
|
||||||
|
{
|
||||||
|
// We can do a const cast here because the only reason that field is const anyway is because it could be a base type
|
||||||
|
return CalculateFields(repository, dynamic_cast<TypedefDefinition*>(const_cast<DataDefinition*>(definition))->m_type_declaration.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CalculateSizeAndAlignPostProcessor::PostProcess(IDataRepository* repository)
|
||||||
|
{
|
||||||
|
if (repository->GetArchitecture() == Architecture::UNKNOWN)
|
||||||
|
{
|
||||||
|
std::cout << "You must set an architecture!" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto* structDefinition : repository->GetAllStructs())
|
||||||
|
{
|
||||||
|
if (!CalculateFields(repository, structDefinition))
|
||||||
|
{
|
||||||
|
std::cout << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto* unionDefinition : repository->GetAllUnions())
|
||||||
|
{
|
||||||
|
if (!CalculateFields(repository, unionDefinition))
|
||||||
|
{
|
||||||
|
std::cout << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto* typedefDeclaration : repository->GetAllTypedefs())
|
||||||
|
{
|
||||||
|
if (!CalculateFields(repository, typedefDeclaration->m_type_declaration.get()))
|
||||||
|
{
|
||||||
|
std::cout << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "IPostProcessor.h"
|
||||||
|
|
||||||
|
class CalculateSizeAndAlignPostProcessor final : public IPostProcessor
|
||||||
|
{
|
||||||
|
static unsigned GetPointerSizeForArchitecture(Architecture architecture);
|
||||||
|
static bool CalculateAlign(IDataRepository* repository, TypeDeclaration* declaration);
|
||||||
|
static bool CalculateAlign(IDataRepository* repository, DefinitionWithMembers* definition);
|
||||||
|
static bool CalculateSize(IDataRepository* repository, TypeDeclaration* declaration);
|
||||||
|
static bool CalculateSize(IDataRepository* repository, StructDefinition* definition);
|
||||||
|
static bool CalculateSize(IDataRepository* repository, UnionDefinition* definition);
|
||||||
|
static bool CalculateFields(IDataRepository* repository, TypeDeclaration* declaration);
|
||||||
|
static bool CalculateFields(IDataRepository* repository, StructDefinition* structDefinition);
|
||||||
|
static bool CalculateFields(IDataRepository* repository, UnionDefinition* unionDefinition);
|
||||||
|
static bool CalculateFieldsIfNecessary(IDataRepository* repository, const DataDefinition* definition);
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool PostProcess(IDataRepository* repository) override;
|
||||||
|
};
|
@ -0,0 +1,29 @@
|
|||||||
|
#include "CreateMemberInformationPostProcessor.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
bool CreateMemberInformationPostProcessor::CreateMemberInformationForStructure(IDataRepository* repository, StructureInformation* structure) const
|
||||||
|
{
|
||||||
|
for(const auto& member : structure->m_definition->m_members)
|
||||||
|
{
|
||||||
|
StructureInformation* typeInfo = nullptr;
|
||||||
|
const auto* memberDefinition = dynamic_cast<const DefinitionWithMembers*>(member->m_type_declaration->m_type);
|
||||||
|
|
||||||
|
if(memberDefinition != nullptr)
|
||||||
|
typeInfo = repository->GetInformationFor(memberDefinition);
|
||||||
|
|
||||||
|
structure->m_ordered_members.emplace_back(std::make_unique<MemberInformation>(structure, typeInfo, member.get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CreateMemberInformationPostProcessor::PostProcess(IDataRepository* repository)
|
||||||
|
{
|
||||||
|
const auto& allStructureInformation = repository->GetAllStructureInformation();
|
||||||
|
|
||||||
|
return std::all_of(allStructureInformation.begin(), allStructureInformation.end(), [this, repository](StructureInformation* structure)
|
||||||
|
{
|
||||||
|
return CreateMemberInformationForStructure(repository, structure);
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "IPostProcessor.h"
|
||||||
|
|
||||||
|
class CreateMemberInformationPostProcessor final : public IPostProcessor
|
||||||
|
{
|
||||||
|
bool CreateMemberInformationForStructure(IDataRepository* repository, StructureInformation* structure) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool PostProcess(IDataRepository* repository) override;
|
||||||
|
};
|
@ -0,0 +1,20 @@
|
|||||||
|
#include "CreateStructureInformationPostProcessor.h"
|
||||||
|
|
||||||
|
bool CreateStructureInformationPostProcessor::PostProcess(IDataRepository* repository)
|
||||||
|
{
|
||||||
|
for(auto* structDefinition : repository->GetAllStructs())
|
||||||
|
{
|
||||||
|
auto* information = repository->GetInformationFor(structDefinition);
|
||||||
|
if(information == nullptr)
|
||||||
|
repository->Add(std::make_unique<StructureInformation>(structDefinition));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(auto* unionDefinition : repository->GetAllUnions())
|
||||||
|
{
|
||||||
|
auto* information = repository->GetInformationFor(unionDefinition);
|
||||||
|
if(information == nullptr)
|
||||||
|
repository->Add(std::make_unique<StructureInformation>(unionDefinition));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "IPostProcessor.h"
|
||||||
|
|
||||||
|
class CreateStructureInformationPostProcessor final : public IPostProcessor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool PostProcess(IDataRepository* repository) override;
|
||||||
|
};
|
@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Persistence/IDataRepository.h"
|
||||||
|
|
||||||
|
class IPostProcessor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IPostProcessor() = default;
|
||||||
|
virtual ~IPostProcessor() = default;
|
||||||
|
IPostProcessor(const IPostProcessor& other) = default;
|
||||||
|
IPostProcessor(IPostProcessor&& other) noexcept = default;
|
||||||
|
IPostProcessor& operator=(const IPostProcessor& other) = default;
|
||||||
|
IPostProcessor& operator=(IPostProcessor&& other) noexcept = default;
|
||||||
|
|
||||||
|
virtual bool PostProcess(IDataRepository* repository) = 0;
|
||||||
|
};
|
@ -7,6 +7,7 @@
|
|||||||
#include "Domain/Definition/StructDefinition.h"
|
#include "Domain/Definition/StructDefinition.h"
|
||||||
#include "Domain/Definition/TypedefDefinition.h"
|
#include "Domain/Definition/TypedefDefinition.h"
|
||||||
#include "Domain/Definition/UnionDefinition.h"
|
#include "Domain/Definition/UnionDefinition.h"
|
||||||
|
#include "Domain/Environment/Architecture.h"
|
||||||
#include "Domain/Information/StructureInformation.h"
|
#include "Domain/Information/StructureInformation.h"
|
||||||
#include "Domain/FastFile/FastFileBlock.h"
|
#include "Domain/FastFile/FastFileBlock.h"
|
||||||
|
|
||||||
@ -29,6 +30,8 @@ public:
|
|||||||
|
|
||||||
_NODISCARD virtual const std::string& GetGameName() const = 0;
|
_NODISCARD virtual const std::string& GetGameName() const = 0;
|
||||||
virtual void SetGame(std::string gameName) = 0;
|
virtual void SetGame(std::string gameName) = 0;
|
||||||
|
_NODISCARD virtual Architecture GetArchitecture() const = 0;
|
||||||
|
virtual void SetArchitecture(Architecture architecture) = 0;
|
||||||
|
|
||||||
_NODISCARD virtual const std::vector<EnumDefinition*>& GetAllEnums() const = 0;
|
_NODISCARD virtual const std::vector<EnumDefinition*>& GetAllEnums() const = 0;
|
||||||
_NODISCARD virtual const std::vector<StructDefinition*>& GetAllStructs() const = 0;
|
_NODISCARD virtual const std::vector<StructDefinition*>& GetAllStructs() const = 0;
|
||||||
@ -38,6 +41,6 @@ public:
|
|||||||
_NODISCARD virtual const std::vector<FastFileBlock*>& GetAllFastFileBlocks() const = 0;
|
_NODISCARD virtual const std::vector<FastFileBlock*>& GetAllFastFileBlocks() const = 0;
|
||||||
|
|
||||||
_NODISCARD virtual DataDefinition* GetDataDefinitionByName(const std::string& name) const = 0;
|
_NODISCARD virtual DataDefinition* GetDataDefinitionByName(const std::string& name) const = 0;
|
||||||
_NODISCARD virtual StructureInformation* GetInformationFor(DefinitionWithMembers* definitionWithMembers) const = 0;
|
_NODISCARD virtual StructureInformation* GetInformationFor(const DefinitionWithMembers* definitionWithMembers) const = 0;
|
||||||
_NODISCARD virtual EnumMember* GetEnumMemberByName(const std::string& name) const = 0;
|
_NODISCARD virtual EnumMember* GetEnumMemberByName(const std::string& name) const = 0;
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
#include "InMemoryRepository.h"
|
#include "InMemoryRepository.h"
|
||||||
|
|
||||||
|
InMemoryRepository::InMemoryRepository()
|
||||||
|
: m_architecture(Architecture::UNKNOWN)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
InMemoryRepository::~InMemoryRepository()
|
InMemoryRepository::~InMemoryRepository()
|
||||||
{
|
{
|
||||||
for (auto* enumDefinition : m_enums)
|
for (auto* enumDefinition : m_enums)
|
||||||
@ -22,7 +27,7 @@ void InMemoryRepository::Add(std::unique_ptr<EnumDefinition> enumsDefinition)
|
|||||||
m_enums.push_back(raw);
|
m_enums.push_back(raw);
|
||||||
m_data_definitions_by_name[raw->m_name] = raw;
|
m_data_definitions_by_name[raw->m_name] = raw;
|
||||||
|
|
||||||
for(const auto& enumMember : raw->m_members)
|
for (const auto& enumMember : raw->m_members)
|
||||||
m_enum_members_by_name[enumMember->m_name] = enumMember.get();
|
m_enum_members_by_name[enumMember->m_name] = enumMember.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,6 +74,16 @@ void InMemoryRepository::SetGame(std::string gameName)
|
|||||||
m_game_name = std::move(gameName);
|
m_game_name = std::move(gameName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Architecture InMemoryRepository::GetArchitecture() const
|
||||||
|
{
|
||||||
|
return m_architecture;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InMemoryRepository::SetArchitecture(const Architecture architecture)
|
||||||
|
{
|
||||||
|
m_architecture = architecture;
|
||||||
|
}
|
||||||
|
|
||||||
const std::vector<EnumDefinition*>& InMemoryRepository::GetAllEnums() const
|
const std::vector<EnumDefinition*>& InMemoryRepository::GetAllEnums() const
|
||||||
{
|
{
|
||||||
return m_enums;
|
return m_enums;
|
||||||
@ -109,7 +124,7 @@ DataDefinition* InMemoryRepository::GetDataDefinitionByName(const std::string& n
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
StructureInformation* InMemoryRepository::GetInformationFor(DefinitionWithMembers* definitionWithMembers) const
|
StructureInformation* InMemoryRepository::GetInformationFor(const DefinitionWithMembers* definitionWithMembers) const
|
||||||
{
|
{
|
||||||
const auto foundEntry = m_structure_information_by_definition.find(definitionWithMembers);
|
const auto foundEntry = m_structure_information_by_definition.find(definitionWithMembers);
|
||||||
|
|
||||||
|
@ -14,11 +14,12 @@ class InMemoryRepository final : public IDataRepository
|
|||||||
std::vector<FastFileBlock*> m_fast_file_blocks;
|
std::vector<FastFileBlock*> m_fast_file_blocks;
|
||||||
std::map<std::string, DataDefinition*> m_data_definitions_by_name;
|
std::map<std::string, DataDefinition*> m_data_definitions_by_name;
|
||||||
std::map<std::string, EnumMember*> m_enum_members_by_name;
|
std::map<std::string, EnumMember*> m_enum_members_by_name;
|
||||||
std::map<DefinitionWithMembers*, StructureInformation*> m_structure_information_by_definition;
|
std::map<const DefinitionWithMembers*, StructureInformation*> m_structure_information_by_definition;
|
||||||
std::string m_game_name;
|
std::string m_game_name;
|
||||||
|
Architecture m_architecture;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InMemoryRepository() = default;
|
InMemoryRepository();
|
||||||
~InMemoryRepository() override;
|
~InMemoryRepository() override;
|
||||||
InMemoryRepository(const InMemoryRepository& other) = delete;
|
InMemoryRepository(const InMemoryRepository& other) = delete;
|
||||||
InMemoryRepository(InMemoryRepository&& other) noexcept = default;
|
InMemoryRepository(InMemoryRepository&& other) noexcept = default;
|
||||||
@ -34,6 +35,8 @@ public:
|
|||||||
|
|
||||||
_NODISCARD const std::string& GetGameName() const override;
|
_NODISCARD const std::string& GetGameName() const override;
|
||||||
void SetGame(std::string gameName) override;
|
void SetGame(std::string gameName) override;
|
||||||
|
Architecture GetArchitecture() const override;
|
||||||
|
void SetArchitecture(Architecture architecture) override;
|
||||||
|
|
||||||
_NODISCARD const std::vector<EnumDefinition*>& GetAllEnums() const override;
|
_NODISCARD const std::vector<EnumDefinition*>& GetAllEnums() const override;
|
||||||
_NODISCARD const std::vector<StructDefinition*>& GetAllStructs() const override;
|
_NODISCARD const std::vector<StructDefinition*>& GetAllStructs() const override;
|
||||||
@ -43,6 +46,6 @@ public:
|
|||||||
_NODISCARD const std::vector<FastFileBlock*>& GetAllFastFileBlocks() const override;
|
_NODISCARD const std::vector<FastFileBlock*>& GetAllFastFileBlocks() const override;
|
||||||
|
|
||||||
_NODISCARD DataDefinition* GetDataDefinitionByName(const std::string& name) const override;
|
_NODISCARD DataDefinition* GetDataDefinitionByName(const std::string& name) const override;
|
||||||
_NODISCARD StructureInformation* GetInformationFor(DefinitionWithMembers* definitionWithMembers) const override;
|
_NODISCARD StructureInformation* GetInformationFor(const DefinitionWithMembers* definitionWithMembers) const override;
|
||||||
_NODISCARD EnumMember* GetEnumMemberByName(const std::string& name) const override;
|
_NODISCARD EnumMember* GetEnumMemberByName(const std::string& name) const override;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user