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 IW4;
|
||||
architecture x86;
|
||||
|
||||
// Game Assets
|
||||
asset PhysPreset ASSET_TYPE_PHYSPRESET;
|
||||
|
@ -1,5 +1,6 @@
|
||||
// Game: Black Ops 2 (T6)
|
||||
game T6;
|
||||
architecture x86;
|
||||
|
||||
// Game Assets
|
||||
asset PhysPreset ASSET_TYPE_PHYSPRESET;
|
||||
|
@ -36,27 +36,21 @@ DefinitionWithMembers::DefinitionWithMembers(std::string _namespace, std::string
|
||||
|
||||
unsigned DefinitionWithMembers::GetAlignment() const
|
||||
{
|
||||
assert(m_flags & FLAG_ALIGNMENT_CALCULATED);
|
||||
/*if ((m_flags & FLAG_ALIGNMENT_CALCULATED) == 0)
|
||||
CalculateAlignment();*/
|
||||
assert(m_flags & FLAG_FIELDS_CALCULATED);
|
||||
|
||||
return m_alignment;
|
||||
}
|
||||
|
||||
bool DefinitionWithMembers::GetForceAlignment() const
|
||||
{
|
||||
assert(m_flags & FLAG_ALIGNMENT_CALCULATED);
|
||||
/*if ((m_flags & FLAG_ALIGNMENT_CALCULATED) == 0)
|
||||
CalculateAlignment();*/
|
||||
assert(m_flags & FLAG_FIELDS_CALCULATED);
|
||||
|
||||
return m_flags & FLAG_ALIGNMENT_FORCED;
|
||||
}
|
||||
|
||||
unsigned DefinitionWithMembers::GetSize() const
|
||||
{
|
||||
assert(m_flags & FLAG_SIZE_CALCULATED);
|
||||
/*if ((m_flags & FLAG_SIZE_CALCULATED) == 0)
|
||||
CalculateSize();*/
|
||||
assert(m_flags & FLAG_FIELDS_CALCULATED);
|
||||
|
||||
return m_size;
|
||||
}
|
||||
|
@ -9,17 +9,14 @@
|
||||
class DefinitionWithMembers : public DataDefinition
|
||||
{
|
||||
public:
|
||||
static constexpr int FLAG_SIZE_CALCULATED = 1 << 0;
|
||||
static constexpr int FLAG_ALIGNMENT_CALCULATED = 1 << 1;
|
||||
static constexpr int FLAG_FIELDS_CALCULATED = 1 << 0;
|
||||
static constexpr int FLAG_FIELDS_CALCULATING = 1 << 1;
|
||||
static constexpr int FLAG_ALIGNMENT_FORCED = 1 << 2;
|
||||
|
||||
unsigned m_flags;
|
||||
unsigned m_size;
|
||||
unsigned m_alignment;
|
||||
|
||||
/*virtual void CalculateSize() = 0;
|
||||
void CalculateAlignment();*/
|
||||
|
||||
bool m_has_alignment_override;
|
||||
bool m_anonymous;
|
||||
|
||||
|
@ -1,43 +1,5 @@
|
||||
#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)
|
||||
: DefinitionWithMembers(std::move(_namespace), std::move(name), pack)
|
||||
{
|
||||
|
@ -4,9 +4,6 @@
|
||||
|
||||
class StructDefinition final : public DefinitionWithMembers
|
||||
{
|
||||
//protected:
|
||||
// void CalculateSize() override;
|
||||
|
||||
public:
|
||||
StructDefinition(std::string _namespace, std::string name, int pack);
|
||||
|
||||
|
@ -16,75 +16,20 @@ TypeDeclaration::TypeDeclaration(const DataDefinition* type)
|
||||
assert(m_type != nullptr);
|
||||
}
|
||||
|
||||
void TypeDeclaration::CalculateSize()
|
||||
unsigned TypeDeclaration::GetSize() const
|
||||
{
|
||||
auto currentSize = m_type->GetSize();
|
||||
|
||||
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();
|
||||
|
||||
assert(m_flags & FLAG_FIELDS_CALCULATED);
|
||||
return m_size;
|
||||
}
|
||||
|
||||
unsigned TypeDeclaration::GetAlignment()
|
||||
unsigned TypeDeclaration::GetAlignment() const
|
||||
{
|
||||
if ((m_flags & FLAG_ALIGNMENT_CALCULATED) == 0)
|
||||
CalculateAlignment();
|
||||
|
||||
assert(m_flags & FLAG_FIELDS_CALCULATED);
|
||||
return m_alignment;
|
||||
}
|
||||
|
||||
bool TypeDeclaration::GetForceAlignment()
|
||||
bool TypeDeclaration::GetForceAlignment() const
|
||||
{
|
||||
if ((m_flags & FLAG_ALIGNMENT_CALCULATED) == 0)
|
||||
CalculateAlignment();
|
||||
|
||||
assert(m_flags & FLAG_FIELDS_CALCULATED);
|
||||
return m_flags & FLAG_ALIGNMENT_FORCED;
|
||||
}
|
||||
|
@ -1,26 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
|
||||
#include "Utils/ClassUtils.h"
|
||||
#include "DataDefinition.h"
|
||||
#include "DeclarationModifier.h"
|
||||
|
||||
class TypeDeclaration
|
||||
{
|
||||
static constexpr unsigned POINTER_SIZE = sizeof(uint32_t); // TODO: Change this to support 64bit
|
||||
static constexpr int FLAG_SIZE_CALCULATED = 1 << 0;
|
||||
static constexpr int FLAG_ALIGNMENT_CALCULATED = 1 << 1;
|
||||
static constexpr int FLAG_ALIGNMENT_FORCED = 1 << 2;
|
||||
public:
|
||||
static constexpr int FLAG_FIELDS_CALCULATED = 1 << 0;
|
||||
static constexpr int FLAG_ALIGNMENT_FORCED = 1 << 1;
|
||||
|
||||
unsigned m_flags;
|
||||
unsigned m_size;
|
||||
unsigned m_alignment;
|
||||
|
||||
void CalculateSize();
|
||||
void CalculateAlignment();
|
||||
|
||||
public:
|
||||
explicit TypeDeclaration(const DataDefinition* type);
|
||||
|
||||
bool m_is_const;
|
||||
@ -31,7 +27,7 @@ public:
|
||||
|
||||
std::vector<std::unique_ptr<DeclarationModifier>> m_declaration_modifiers;
|
||||
|
||||
unsigned GetSize();
|
||||
unsigned GetAlignment();
|
||||
bool GetForceAlignment();
|
||||
_NODISCARD unsigned GetSize() const;
|
||||
_NODISCARD unsigned GetAlignment() const;
|
||||
_NODISCARD bool GetForceAlignment() const;
|
||||
};
|
||||
|
@ -1,23 +1,5 @@
|
||||
#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)
|
||||
: 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)
|
||||
return m_alignment_override;
|
||||
@ -16,7 +16,7 @@ unsigned Variable::GetAlignment()
|
||||
return m_type_declaration->GetAlignment();
|
||||
}
|
||||
|
||||
bool Variable::GetForceAlignment()
|
||||
bool Variable::GetForceAlignment() const
|
||||
{
|
||||
return m_has_alignment_override || m_type_declaration->GetForceAlignment();
|
||||
}
|
||||
|
@ -15,6 +15,6 @@ public:
|
||||
|
||||
Variable(std::string name, std::unique_ptr<TypeDeclaration> typeDeclaration);
|
||||
|
||||
unsigned GetAlignment();
|
||||
bool GetForceAlignment();
|
||||
unsigned GetAlignment() const;
|
||||
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
|
||||
{
|
||||
return EvaluationType::OPERAND_DYNAMIC;
|
||||
|
@ -14,6 +14,7 @@ public:
|
||||
std::vector<std::unique_ptr<IEvaluation>> m_array_indices;
|
||||
|
||||
explicit OperandDynamic(StructureInformation* structure);
|
||||
OperandDynamic(StructureInformation* structure, std::vector<MemberInformation*> referencedMemberChain, std::vector<std::unique_ptr<IEvaluation>> arrayIndices);
|
||||
|
||||
_NODISCARD EvaluationType GetType() const override;
|
||||
_NODISCARD bool IsStatic() const override;
|
||||
|
@ -6,8 +6,8 @@ OperandStatic::OperandStatic(const int value)
|
||||
{
|
||||
}
|
||||
|
||||
OperandStatic::OperandStatic(const int value, EnumMember* enumMember)
|
||||
: m_value(value),
|
||||
OperandStatic::OperandStatic(EnumMember* enumMember)
|
||||
: m_value(enumMember->m_value),
|
||||
m_enum_member(enumMember)
|
||||
{
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ public:
|
||||
EnumMember* const m_enum_member;
|
||||
|
||||
explicit OperandStatic(int value);
|
||||
OperandStatic(int value, EnumMember* enumMember);
|
||||
explicit OperandStatic(EnumMember* enumMember);
|
||||
|
||||
_NODISCARD EvaluationType GetType() 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
|
||||
{
|
||||
return EvaluationType::OPERATION;
|
||||
|
@ -14,6 +14,7 @@ public:
|
||||
std::unique_ptr<IEvaluation> m_operand2;
|
||||
|
||||
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 bool IsStatic() const override;
|
||||
|
@ -73,7 +73,7 @@ const OperationType* const OperationType::OPERATION_GREATER_THAN
|
||||
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)
|
||||
{
|
||||
return op1 >= op2 ? 1 : 0;
|
||||
@ -85,7 +85,7 @@ const OperationType* const OperationType::OPERATION_LESS_THAN
|
||||
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)
|
||||
{
|
||||
return op1 <= op2 ? 1 : 0;
|
||||
@ -97,7 +97,7 @@ const OperationType* const OperationType::OPERATION_EQUALS
|
||||
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)
|
||||
{
|
||||
return op1 != op2 ? 1 : 0;
|
||||
@ -129,11 +129,11 @@ const OperationType* const OperationType::ALL_OPERATION_TYPES[]
|
||||
OPERATION_SHIFT_LEFT,
|
||||
OPERATION_SHIFT_RIGHT,
|
||||
OPERATION_GREATER_THAN,
|
||||
OPERATION_GREATER_EQUALS_THAN,
|
||||
OPERATION_GREATER_EQUAL_THAN,
|
||||
OPERATION_LESS_THAN,
|
||||
OPERATION_LESS_EQUALS_THAN,
|
||||
OPERATION_LESS_EQUAL_THAN,
|
||||
OPERATION_EQUALS,
|
||||
OPERATION_NOT_EQUALS,
|
||||
OPERATION_NOT_EQUAL,
|
||||
OPERATION_AND,
|
||||
OPERATION_OR
|
||||
};
|
||||
|
@ -40,11 +40,11 @@ public:
|
||||
static const OperationType* const OPERATION_SHIFT_LEFT;
|
||||
static const OperationType* const OPERATION_SHIFT_RIGHT;
|
||||
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_EQUALS_THAN;
|
||||
static const OperationType* const OPERATION_LESS_EQUAL_THAN;
|
||||
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_OR;
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "CommandsFileReader.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
|
||||
@ -9,12 +10,14 @@
|
||||
#include "Parsing/Impl/DefinesStreamProxy.h"
|
||||
#include "Parsing/Impl/IncludingStreamProxy.h"
|
||||
#include "Parsing/Impl/ParserFilesystemStream.h"
|
||||
#include "Parsing/PostProcessing/CalculateSizeAndAlignPostProcessor.h"
|
||||
|
||||
CommandsFileReader::CommandsFileReader(const ZoneCodeGeneratorArguments* args, std::string filename)
|
||||
: m_args(args),
|
||||
m_filename(std::move(filename)),
|
||||
m_stream(nullptr)
|
||||
{
|
||||
SetupPostProcessors();
|
||||
}
|
||||
|
||||
bool CommandsFileReader::OpenBaseStream()
|
||||
@ -45,6 +48,11 @@ void CommandsFileReader::SetupStreamProxies()
|
||||
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)
|
||||
{
|
||||
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();
|
||||
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 "Parsing/IParserLineStream.h"
|
||||
#include "Parsing/PostProcessing/IPostProcessor.h"
|
||||
#include "Persistence/IDataRepository.h"
|
||||
|
||||
class CommandsFileReader
|
||||
@ -17,8 +18,11 @@ class CommandsFileReader
|
||||
std::vector<std::unique_ptr<IParserLineStream>> m_open_streams;
|
||||
IParserLineStream* m_stream;
|
||||
|
||||
std::vector<std::unique_ptr<IPostProcessor>> m_post_processors;
|
||||
|
||||
bool OpenBaseStream();
|
||||
void SetupStreamProxies();
|
||||
void SetupPostProcessors();
|
||||
|
||||
public:
|
||||
explicit CommandsFileReader(const ZoneCodeGeneratorArguments* args, std::string filename);
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "CommandsParser.h"
|
||||
|
||||
#include "Parsing/Commands/Sequence/SequenceAction.h"
|
||||
#include "Parsing/Commands/Sequence/SequenceArchitecture.h"
|
||||
#include "Parsing/Commands/Sequence/SequenceArrayCount.h"
|
||||
#include "Parsing/Commands/Sequence/SequenceArraySize.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({
|
||||
new SequenceAction(),
|
||||
new SequenceArchitecture(),
|
||||
new SequenceArrayCount(),
|
||||
new SequenceArraySize(),
|
||||
new SequenceAsset(),
|
||||
|
@ -16,6 +16,11 @@ void CommandsParserState::AddBlock(std::unique_ptr<FastFileBlock> block) const
|
||||
m_repository->Add(std::move(block));
|
||||
}
|
||||
|
||||
void CommandsParserState::SetArchitecture(const Architecture architecture) const
|
||||
{
|
||||
m_repository->SetArchitecture(architecture);
|
||||
}
|
||||
|
||||
void CommandsParserState::SetGame(std::string gameName) const
|
||||
{
|
||||
m_repository->SetGame(std::move(gameName));
|
||||
@ -31,12 +36,105 @@ void CommandsParserState::SetInUse(StructureInformation* 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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
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:
|
||||
explicit CommandsParserState(IDataRepository* repository);
|
||||
|
||||
_NODISCARD const IDataRepository* GetRepository() const;
|
||||
|
||||
void AddBlock(std::unique_ptr<FastFileBlock> block) const;
|
||||
void SetArchitecture(Architecture architecture) const;
|
||||
void SetGame(std::string gameName) const;
|
||||
|
||||
_NODISCARD StructureInformation* GetInUse() const;
|
||||
void SetInUse(StructureInformation* structure);
|
||||
|
||||
bool GetMembersFromParts(const std::string& typeNameValue, StructureInformation* baseType, std::vector<MemberInformation*>& members);
|
||||
bool GetTypenameAndMembersFromParts(const std::string& typeNameValue, StructureInformation*& structure, std::vector<MemberInformation*>& members);
|
||||
bool GetMembersFromTypename(const std::string& typeNameValue, StructureInformation* baseType, std::vector<MemberInformation*>& members) const;
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
: m_pos(pos),
|
||||
m_type(type),
|
||||
@ -201,3 +208,9 @@ std::string& CommandsParserValue::TypeNameValue() const
|
||||
assert(m_type == CommandsParserValueType::TYPE_NAME);
|
||||
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 "Domain/Evaluation/OperationType.h"
|
||||
#include "Parsing/IParserValue.h"
|
||||
#include "Utils/ClassUtils.h"
|
||||
#include "Parsing/TokenPos.h"
|
||||
@ -43,6 +45,7 @@ enum class CommandsParserValueType
|
||||
|
||||
// Parser created
|
||||
TYPE_NAME,
|
||||
OPERATION_TYPE,
|
||||
|
||||
// End
|
||||
MAX
|
||||
@ -60,6 +63,7 @@ public:
|
||||
int int_value;
|
||||
double double_value;
|
||||
std::string* string_value;
|
||||
const OperationType* op_type_value;
|
||||
} m_value;
|
||||
|
||||
static CommandsParserValue Invalid(TokenPos pos);
|
||||
@ -78,6 +82,7 @@ public:
|
||||
static CommandsParserValue String(TokenPos pos, std::string* stringValue);
|
||||
static CommandsParserValue Identifier(TokenPos pos, std::string* identifier);
|
||||
static CommandsParserValue TypeName(TokenPos pos, std::string* typeName);
|
||||
static CommandsParserValue OpType(TokenPos pos, const OperationType* operationType);
|
||||
|
||||
private:
|
||||
CommandsParserValue(TokenPos pos, CommandsParserValueType type);
|
||||
@ -99,4 +104,5 @@ public:
|
||||
_NODISCARD std::string& IdentifierValue() const;
|
||||
_NODISCARD size_t IdentifierHash() const;
|
||||
_NODISCARD std::string& TypeNameValue() const;
|
||||
_NODISCARD const OperationType* OpTypeValue() const;
|
||||
};
|
@ -1,8 +1,13 @@
|
||||
#include "CommandsCommonMatchers.h"
|
||||
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#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)
|
||||
{
|
||||
@ -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_ADD = std::numeric_limits<int>::max() - 2;
|
||||
static constexpr int TAG_MINUS = std::numeric_limits<int>::max() - 3;
|
||||
static constexpr int TAG_MULTIPLY = std::numeric_limits<int>::max() - 4;
|
||||
static constexpr int TAG_DIVIDE = std::numeric_limits<int>::max() - 5;
|
||||
static constexpr int TAG_REMAINDER = std::numeric_limits<int>::max() - 6;
|
||||
static constexpr int TAG_BITWISE_AND = std::numeric_limits<int>::max() - 7;
|
||||
static constexpr int TAG_BITWISE_XOR = std::numeric_limits<int>::max() - 8;
|
||||
static constexpr int TAG_BITWISE_OR = std::numeric_limits<int>::max() - 9;
|
||||
static constexpr int TAG_SHIFT_LEFT = 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 TAG_OPERAND = std::numeric_limits<int>::max() - 1;
|
||||
static constexpr int TAG_OPERAND_TYPENAME = std::numeric_limits<int>::max() - 2;
|
||||
static constexpr int TAG_OPERAND_ARRAY = std::numeric_limits<int>::max() - 3;
|
||||
static constexpr int TAG_OPERAND_ARRAY_END = std::numeric_limits<int>::max() - 4;
|
||||
static constexpr int TAG_OPERAND_INTEGER = std::numeric_limits<int>::max() - 5;
|
||||
static constexpr int TAG_EVALUATION_NOT = std::numeric_limits<int>::max() - 6;
|
||||
static constexpr int TAG_EVALUATION_PARENTHESIS = std::numeric_limits<int>::max() - 7;
|
||||
static constexpr int TAG_EVALUATION_PARENTHESIS_END = std::numeric_limits<int>::max() - 8;
|
||||
static constexpr int TAG_EVALUATION = std::numeric_limits<int>::max() - 9;
|
||||
static constexpr int TAG_EVALUATION_OPERATION = std::numeric_limits<int>::max() - 10;
|
||||
|
||||
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_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);
|
||||
|
||||
@ -133,44 +118,97 @@ std::unique_ptr<CommandsCommonMatchers::matcher_t> CommandsCommonMatchers::Opera
|
||||
}).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);
|
||||
|
||||
return create.Or({
|
||||
create.And({
|
||||
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),
|
||||
create.Integer().Tag(TAG_OPERAND_INTEGER).Capture(CAPTURE_OPERAND_INTEGER),
|
||||
create.FloatingPoint().Tag(TAG_OPERAND_FLOATING_POINT).Capture(CAPTURE_OPERAND_FLOATING_POINT)
|
||||
create.Integer().Tag(TAG_OPERAND_INTEGER).Capture(CAPTURE_OPERAND_INTEGER)
|
||||
}).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);
|
||||
|
||||
return create.Or({
|
||||
create.Char('+').Tag(TAG_ADD),
|
||||
create.Char('-').Tag(TAG_MINUS),
|
||||
create.Char('*').Tag(TAG_MULTIPLY),
|
||||
create.Char('/').Tag(TAG_DIVIDE),
|
||||
create.Char('%').Tag(TAG_REMAINDER),
|
||||
create.Char('&').Tag(TAG_BITWISE_AND),
|
||||
create.Char('^').Tag(TAG_BITWISE_XOR),
|
||||
create.Char('|').Tag(TAG_BITWISE_OR),
|
||||
create.Type(CommandsParserValueType::SHIFT_LEFT).Tag(TAG_SHIFT_LEFT),
|
||||
create.Type(CommandsParserValueType::SHIFT_RIGHT).Tag(TAG_SHIFT_RIGHT),
|
||||
create.Char('>').Tag(TAG_GREATER_THAN),
|
||||
create.Type(CommandsParserValueType::GREATER_EQUAL).Tag(TAG_GREATER_EQUAL),
|
||||
create.Char('<').Tag(TAG_LESS_THAN),
|
||||
create.Type(CommandsParserValueType::LESS_EQUAL).Tag(TAG_LESS_EQUAL),
|
||||
create.Type(CommandsParserValueType::EQUALS).Tag(TAG_EQUALS),
|
||||
create.Type(CommandsParserValueType::NOT_EQUAL).Tag(TAG_NOT_EQUAL),
|
||||
create.Type(CommandsParserValueType::LOGICAL_AND).Tag(TAG_LOGICAL_AND),
|
||||
create.Type(CommandsParserValueType::LOGICAL_OR).Tag(TAG_LOGICAL_OR)
|
||||
}).Tag(TAG_OPERATION_TYPE);
|
||||
create.Char('+').Transform([](CommandsMatcherFactory::token_list_t& values)
|
||||
{
|
||||
return CommandsParserValue::OpType(values[0].get().GetPos(), OperationType::OPERATION_ADD);
|
||||
}),
|
||||
create.Char('-').Transform([](CommandsMatcherFactory::token_list_t& values)
|
||||
{
|
||||
return CommandsParserValue::OpType(values[0].get().GetPos(), OperationType::OPERATION_SUBTRACT);
|
||||
}),
|
||||
create.Char('*').Transform([](CommandsMatcherFactory::token_list_t& values)
|
||||
{
|
||||
return CommandsParserValue::OpType(values[0].get().GetPos(), OperationType::OPERATION_MULTIPLY);
|
||||
}),
|
||||
create.Char('/').Transform([](CommandsMatcherFactory::token_list_t& values)
|
||||
{
|
||||
return CommandsParserValue::OpType(values[0].get().GetPos(), OperationType::OPERATION_DIVIDE);
|
||||
}),
|
||||
create.Char('%').Transform([](CommandsMatcherFactory::token_list_t& values)
|
||||
{
|
||||
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)
|
||||
@ -185,21 +223,123 @@ std::unique_ptr<CommandsCommonMatchers::matcher_t> CommandsCommonMatchers::Evalu
|
||||
create.Label(LABEL_EVALUATION),
|
||||
create.Char(')').Tag(TAG_EVALUATION_PARENTHESIS_END)
|
||||
}).Tag(TAG_EVALUATION_PARENTHESIS),
|
||||
Operand(labelSupplier)
|
||||
ParseOperand(labelSupplier)
|
||||
}),
|
||||
create.Optional(create.And({
|
||||
OperationType(labelSupplier),
|
||||
ParseOperationType(labelSupplier),
|
||||
create.Label(LABEL_EVALUATION)
|
||||
})).Tag(TAG_EVALUATION_OPERATION)
|
||||
}).Tag(TAG_EVALUATION_OPERATION))
|
||||
}).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)
|
||||
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;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <memory>
|
||||
|
||||
#include "Domain/Evaluation/IEvaluation.h"
|
||||
#include "Domain/Evaluation/OperationType.h"
|
||||
#include "Parsing/Commands/Impl/CommandsParserState.h"
|
||||
#include "Parsing/Commands/Impl/CommandsParserValue.h"
|
||||
#include "Parsing/Matcher/AbstractMatcher.h"
|
||||
@ -24,11 +25,15 @@ public:
|
||||
static std::unique_ptr<matcher_t> ArrayDef(const supplier_t* labelSupplier);
|
||||
|
||||
private:
|
||||
static std::unique_ptr<matcher_t> OperandArray(const supplier_t* labelSupplier);
|
||||
static std::unique_ptr<matcher_t> Operand(const supplier_t* labelSupplier);
|
||||
static std::unique_ptr<matcher_t> OperationType(const supplier_t* labelSupplier);
|
||||
static std::unique_ptr<matcher_t> ParseOperandArray(const supplier_t* labelSupplier);
|
||||
static std::unique_ptr<matcher_t> ParseOperand(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:
|
||||
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 "Domain/Definition/ArrayDeclarationModifier.h"
|
||||
#include "Parsing/Commands/Matcher/CommandsMatcherFactory.h"
|
||||
#include "Parsing/Commands/Matcher/CommandsCommonMatchers.h"
|
||||
|
||||
@ -13,11 +15,38 @@ SequenceArrayCount::SequenceArrayCount()
|
||||
create.Keyword("set"),
|
||||
create.Keyword("arraycount"),
|
||||
create.Label(CommandsCommonMatchers::LABEL_TYPENAME).Capture(CAPTURE_TYPE),
|
||||
create.Label(CommandsCommonMatchers::LABEL_EVALUATION).Capture(CAPTURE_EVALUATION),
|
||||
create.Label(CommandsCommonMatchers::LABEL_EVALUATION),
|
||||
create.Char(';')
|
||||
});
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
static constexpr auto CAPTURE_TYPE = 1;
|
||||
static constexpr auto CAPTURE_EVALUATION = 2;
|
||||
|
||||
protected:
|
||||
void ProcessMatch(CommandsParserState* state, SequenceResult<CommandsParserValue>& result) const override;
|
||||
|
@ -17,4 +17,14 @@ SequenceUse::SequenceUse()
|
||||
|
||||
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()
|
||||
{
|
||||
return !m_is_typedef && !m_variable_name.empty();
|
||||
return true;
|
||||
}
|
||||
|
||||
DataDefinition* HeaderBlockStruct::GetVariableType()
|
||||
|
@ -102,7 +102,7 @@ void HeaderBlockUnion::SetBlockName(const TokenPos& nameTokenPos, std::string na
|
||||
|
||||
bool HeaderBlockUnion::IsDefiningVariable()
|
||||
{
|
||||
return !m_is_typedef && !m_variable_name.empty();
|
||||
return true;
|
||||
}
|
||||
|
||||
DataDefinition* HeaderBlockUnion::GetVariableType()
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "HeaderFileReader.h"
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
|
||||
@ -11,6 +11,9 @@
|
||||
#include "Parsing/Impl/IncludingStreamProxy.h"
|
||||
#include "Parsing/Impl/PackDefinitionStreamProxy.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)
|
||||
: m_args(args),
|
||||
@ -18,6 +21,7 @@ HeaderFileReader::HeaderFileReader(const ZoneCodeGeneratorArguments* args, std::
|
||||
m_pack_value_supplier(nullptr),
|
||||
m_stream(nullptr)
|
||||
{
|
||||
SetupPostProcessors();
|
||||
}
|
||||
|
||||
bool HeaderFileReader::OpenBaseStream()
|
||||
@ -51,6 +55,13 @@ void HeaderFileReader::SetupStreamProxies()
|
||||
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)
|
||||
{
|
||||
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 start = std::chrono::steady_clock::now();
|
||||
const auto result = parser->Parse();
|
||||
auto result = parser->Parse();
|
||||
if (result)
|
||||
parser->SaveToRepository(repository);
|
||||
result = parser->SaveToRepository(repository);
|
||||
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;
|
||||
|
||||
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 "Parsing/IPackValueSupplier.h"
|
||||
#include "Parsing/IParserLineStream.h"
|
||||
#include "Parsing/PostProcessing/IPostProcessor.h"
|
||||
#include "Persistence/IDataRepository.h"
|
||||
|
||||
class HeaderFileReader
|
||||
@ -19,8 +20,11 @@ class HeaderFileReader
|
||||
const IPackValueSupplier* m_pack_value_supplier;
|
||||
IParserLineStream* m_stream;
|
||||
|
||||
std::vector<std::unique_ptr<IPostProcessor>> m_post_processors;
|
||||
|
||||
bool OpenBaseStream();
|
||||
void SetupStreamProxies();
|
||||
void SetupPostProcessors();
|
||||
|
||||
public:
|
||||
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/TypedefDefinition.h"
|
||||
#include "Domain/Definition/UnionDefinition.h"
|
||||
#include "Domain/Environment/Architecture.h"
|
||||
#include "Domain/Information/StructureInformation.h"
|
||||
#include "Domain/FastFile/FastFileBlock.h"
|
||||
|
||||
@ -29,6 +30,8 @@ public:
|
||||
|
||||
_NODISCARD virtual const std::string& GetGameName() const = 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<StructDefinition*>& GetAllStructs() const = 0;
|
||||
@ -38,6 +41,6 @@ public:
|
||||
_NODISCARD virtual const std::vector<FastFileBlock*>& GetAllFastFileBlocks() 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;
|
||||
};
|
||||
|
@ -1,5 +1,10 @@
|
||||
#include "InMemoryRepository.h"
|
||||
|
||||
InMemoryRepository::InMemoryRepository()
|
||||
: m_architecture(Architecture::UNKNOWN)
|
||||
{
|
||||
}
|
||||
|
||||
InMemoryRepository::~InMemoryRepository()
|
||||
{
|
||||
for (auto* enumDefinition : m_enums)
|
||||
@ -22,7 +27,7 @@ void InMemoryRepository::Add(std::unique_ptr<EnumDefinition> enumsDefinition)
|
||||
m_enums.push_back(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();
|
||||
}
|
||||
|
||||
@ -69,6 +74,16 @@ void InMemoryRepository::SetGame(std::string 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
|
||||
{
|
||||
return m_enums;
|
||||
@ -109,7 +124,7 @@ DataDefinition* InMemoryRepository::GetDataDefinitionByName(const std::string& n
|
||||
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);
|
||||
|
||||
|
@ -14,11 +14,12 @@ class InMemoryRepository final : public IDataRepository
|
||||
std::vector<FastFileBlock*> m_fast_file_blocks;
|
||||
std::map<std::string, DataDefinition*> m_data_definitions_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;
|
||||
Architecture m_architecture;
|
||||
|
||||
public:
|
||||
InMemoryRepository() = default;
|
||||
InMemoryRepository();
|
||||
~InMemoryRepository() override;
|
||||
InMemoryRepository(const InMemoryRepository& other) = delete;
|
||||
InMemoryRepository(InMemoryRepository&& other) noexcept = default;
|
||||
@ -34,6 +35,8 @@ public:
|
||||
|
||||
_NODISCARD const std::string& GetGameName() const 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<StructDefinition*>& GetAllStructs() const override;
|
||||
@ -43,6 +46,6 @@ public:
|
||||
_NODISCARD const std::vector<FastFileBlock*>& GetAllFastFileBlocks() 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;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user