Calculate size and alignment in post processor

This commit is contained in:
Jan
2021-02-19 16:23:16 +01:00
parent 1264be4274
commit 7c51c26255
48 changed files with 966 additions and 246 deletions

View File

@ -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);
});
}

View File

@ -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);

View File

@ -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(),

View File

@ -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)
{
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);
}

View File

@ -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;
};

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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;
}

View File

@ -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);
};

View File

@ -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!");
}
}

View File

@ -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();
};

View File

@ -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);
}

View File

@ -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;

View File

@ -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));
}

View File

@ -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()

View File

@ -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()

View File

@ -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);
});
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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);
});
}

View File

@ -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;
};

View File

@ -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;
}

View File

@ -0,0 +1,9 @@
#pragma once
#include "IPostProcessor.h"
class CreateStructureInformationPostProcessor final : public IPostProcessor
{
public:
bool PostProcess(IDataRepository* repository) override;
};

View File

@ -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;
};