From 6d44ed0568c9d5312cf04265e2e15f77cd0e4f3a Mon Sep 17 00:00:00 2001 From: Jan Laupetin Date: Sat, 15 Aug 2026 11:28:48 +0200 Subject: [PATCH] wip: multiple variants in zonecode --- .../MemberDeclarationModifierComputations.cpp | 6 +- .../MemberDeclarationModifierComputations.h | 2 +- .../Domain/Definition/BaseTypeDefinition.cpp | 4 +- .../Domain/Definition/BaseTypeDefinition.h | 4 +- .../Domain/Definition/DataDefinition.h | 6 +- .../Definition/DefinitionWithMembers.cpp | 8 +- .../Domain/Definition/DefinitionWithMembers.h | 8 +- .../Domain/Definition/EnumDefinition.cpp | 8 +- .../Domain/Definition/EnumDefinition.h | 4 +- .../Domain/Definition/ForwardDeclaration.cpp | 4 +- .../Domain/Definition/ForwardDeclaration.h | 4 +- .../Domain/Definition/TypeDeclaration.cpp | 12 +- .../Domain/Definition/TypeDeclaration.h | 9 +- .../Domain/Definition/TypedefDefinition.cpp | 9 +- .../Domain/Definition/TypedefDefinition.h | 4 +- .../Domain/Definition/Variable.cpp | 4 +- .../Domain/Definition/Variable.h | 2 +- .../Domain/{FastFile => }/FastFileBlock.cpp | 0 .../Domain/{FastFile => }/FastFileBlock.h | 0 .../Domain/GameVariant.cpp | 8 + src/ZoneCodeGeneratorLib/Domain/GameVariant.h | 16 ++ .../Domain/Information/MemberInformation.h | 2 +- .../Domain/Information/StructureInformation.h | 2 +- .../Domain/{Environment => }/WordSize.cpp | 0 .../Domain/{Environment => }/WordSize.h | 7 +- .../Generating/BaseRenderingContext.cpp | 8 +- .../Generating/BaseRenderingContext.h | 5 +- .../Generating/CodeGenerator.cpp | 57 ++++--- .../OncePerAssetRenderingContext.cpp | 12 +- .../Generating/OncePerAssetRenderingContext.h | 5 +- .../OncePerTemplateRenderingContext.cpp | 9 +- .../OncePerTemplateRenderingContext.h | 3 +- .../Templates/AssetStructTestsTemplate.cpp | 4 +- .../Templates/Internal/BaseTemplate.cpp | 10 +- .../Templates/Internal/BaseTemplate.h | 2 +- .../Generating/Templates/ZoneLoadTemplate.cpp | 33 ++-- .../Templates/ZoneWriteTemplate.cpp | 27 +-- .../Parsing/Commands/CommandsFileReader.cpp | 6 + .../Parsing/Commands/Impl/CommandsParser.cpp | 4 +- .../Commands/Impl/CommandsParserState.cpp | 4 +- .../Commands/Impl/CommandsParserState.h | 2 +- .../Commands/Sequence/SequenceVariant.cpp | 69 ++++++++ .../{SequenceWordSize.h => SequenceVariant.h} | 4 +- .../Commands/Sequence/SequenceWordSize.cpp | 39 ----- .../Header/Block/HeaderBlockStruct.cpp | 3 +- .../Parsing/Header/Block/HeaderBlockUnion.cpp | 3 +- .../CalculateSizeAndAlignPostProcessor.cpp | 158 ++++++++++-------- .../CrossPlatformStructurePostProcessor.cpp | 14 +- .../Persistence/IDataRepository.h | 9 +- .../InMemory/InMemoryRepository.cpp | 15 +- .../Persistence/InMemory/InMemoryRepository.h | 6 +- .../Printing/PrettyPrinter.cpp | 23 ++- .../Printing/PrettyPrinter.h | 1 + 53 files changed, 392 insertions(+), 276 deletions(-) rename src/ZoneCodeGeneratorLib/Domain/{FastFile => }/FastFileBlock.cpp (100%) rename src/ZoneCodeGeneratorLib/Domain/{FastFile => }/FastFileBlock.h (100%) create mode 100644 src/ZoneCodeGeneratorLib/Domain/GameVariant.cpp create mode 100644 src/ZoneCodeGeneratorLib/Domain/GameVariant.h rename src/ZoneCodeGeneratorLib/Domain/{Environment => }/WordSize.cpp (100%) rename src/ZoneCodeGeneratorLib/Domain/{Environment => }/WordSize.h (71%) create mode 100644 src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceVariant.cpp rename src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/{SequenceWordSize.h => SequenceVariant.h} (69%) delete mode 100644 src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceWordSize.cpp diff --git a/src/ZoneCodeGeneratorLib/Domain/Computations/MemberDeclarationModifierComputations.cpp b/src/ZoneCodeGeneratorLib/Domain/Computations/MemberDeclarationModifierComputations.cpp index 5f77f861..85ca0e3a 100644 --- a/src/ZoneCodeGeneratorLib/Domain/Computations/MemberDeclarationModifierComputations.cpp +++ b/src/ZoneCodeGeneratorLib/Domain/Computations/MemberDeclarationModifierComputations.cpp @@ -263,7 +263,7 @@ bool DeclarationModifierComputations::HasPointerModifier() const }); } -unsigned DeclarationModifierComputations::GetAlignment() const +unsigned DeclarationModifierComputations::GetAlignment(const WordSize wordSize) const { const auto following = GetFollowingDeclarationModifiers(); @@ -272,6 +272,6 @@ unsigned DeclarationModifierComputations::GetAlignment() const { return modifier->GetType() == DeclarationModifierType::POINTER; }) - ? m_information->m_member->GetAlignment() - : m_information->m_member->m_type_declaration->m_type->GetAlignment(); + ? m_information->m_member->GetAlignment(wordSize) + : m_information->m_member->m_type_declaration->m_type->GetAlignment(wordSize); } diff --git a/src/ZoneCodeGeneratorLib/Domain/Computations/MemberDeclarationModifierComputations.h b/src/ZoneCodeGeneratorLib/Domain/Computations/MemberDeclarationModifierComputations.h index 4f1e7e70..118840ed 100644 --- a/src/ZoneCodeGeneratorLib/Domain/Computations/MemberDeclarationModifierComputations.h +++ b/src/ZoneCodeGeneratorLib/Domain/Computations/MemberDeclarationModifierComputations.h @@ -28,7 +28,7 @@ public: [[nodiscard]] bool IsDynamicArray() const; [[nodiscard]] const IEvaluation* GetDynamicArraySizeEvaluation() const; [[nodiscard]] bool HasPointerModifier() const; - [[nodiscard]] unsigned GetAlignment() const; + [[nodiscard]] unsigned GetAlignment(WordSize wordSize) const; private: DeclarationModifierComputations(const MemberInformation* member, std::vector modifierIndices); diff --git a/src/ZoneCodeGeneratorLib/Domain/Definition/BaseTypeDefinition.cpp b/src/ZoneCodeGeneratorLib/Domain/Definition/BaseTypeDefinition.cpp index 8835fade..3efbc471 100644 --- a/src/ZoneCodeGeneratorLib/Domain/Definition/BaseTypeDefinition.cpp +++ b/src/ZoneCodeGeneratorLib/Domain/Definition/BaseTypeDefinition.cpp @@ -13,7 +13,7 @@ DataDefinitionType BaseTypeDefinition::GetType() const return DataDefinitionType::BASE_TYPE; } -unsigned BaseTypeDefinition::GetAlignment() const +unsigned BaseTypeDefinition::GetAlignment(const WordSize wordSize) const { return m_size; } @@ -23,7 +23,7 @@ bool BaseTypeDefinition::GetForceAlignment() const return false; } -unsigned BaseTypeDefinition::GetSize() const +unsigned BaseTypeDefinition::GetSize(const WordSize wordSize) const { return m_size; } diff --git a/src/ZoneCodeGeneratorLib/Domain/Definition/BaseTypeDefinition.h b/src/ZoneCodeGeneratorLib/Domain/Definition/BaseTypeDefinition.h index 9eb7a2b9..34104752 100644 --- a/src/ZoneCodeGeneratorLib/Domain/Definition/BaseTypeDefinition.h +++ b/src/ZoneCodeGeneratorLib/Domain/Definition/BaseTypeDefinition.h @@ -23,9 +23,9 @@ public: static const size_t ALL_BASE_TYPES_COUNT; [[nodiscard]] DataDefinitionType GetType() const override; - [[nodiscard]] unsigned GetAlignment() const override; + [[nodiscard]] unsigned GetAlignment(WordSize wordSize) const override; [[nodiscard]] bool GetForceAlignment() const override; - [[nodiscard]] unsigned GetSize() const override; + [[nodiscard]] unsigned GetSize(WordSize wordSize) const override; const unsigned m_size; diff --git a/src/ZoneCodeGeneratorLib/Domain/Definition/DataDefinition.h b/src/ZoneCodeGeneratorLib/Domain/Definition/DataDefinition.h index 8e702a7a..873e5d57 100644 --- a/src/ZoneCodeGeneratorLib/Domain/Definition/DataDefinition.h +++ b/src/ZoneCodeGeneratorLib/Domain/Definition/DataDefinition.h @@ -1,5 +1,7 @@ #pragma once +#include "Domain/WordSize.h" + #include enum class DataDefinitionType @@ -25,9 +27,9 @@ public: DataDefinition& operator=(DataDefinition&& other) noexcept = default; [[nodiscard]] virtual DataDefinitionType GetType() const = 0; - [[nodiscard]] virtual unsigned GetAlignment() const = 0; + [[nodiscard]] virtual unsigned GetAlignment(WordSize wordSize) const = 0; [[nodiscard]] virtual bool GetForceAlignment() const = 0; - [[nodiscard]] virtual unsigned GetSize() const = 0; + [[nodiscard]] virtual unsigned GetSize(WordSize wordSize) const = 0; [[nodiscard]] std::string GetFullName() const; diff --git a/src/ZoneCodeGeneratorLib/Domain/Definition/DefinitionWithMembers.cpp b/src/ZoneCodeGeneratorLib/Domain/Definition/DefinitionWithMembers.cpp index 1cc3df56..7ca4a408 100644 --- a/src/ZoneCodeGeneratorLib/Domain/Definition/DefinitionWithMembers.cpp +++ b/src/ZoneCodeGeneratorLib/Domain/Definition/DefinitionWithMembers.cpp @@ -11,11 +11,11 @@ DefinitionWithMembers::DefinitionWithMembers(std::string _namespace, std::string { } -unsigned DefinitionWithMembers::GetAlignment() const +unsigned DefinitionWithMembers::GetAlignment(const WordSize wordSize) const { assert(m_flags & FLAG_FIELDS_CALCULATED); - return m_alignment; + return m_alignment[std::to_underlying(wordSize)]; } bool DefinitionWithMembers::GetForceAlignment() const @@ -23,11 +23,11 @@ bool DefinitionWithMembers::GetForceAlignment() const return m_flags & FLAG_ALIGNMENT_FORCED; } -unsigned DefinitionWithMembers::GetSize() const +unsigned DefinitionWithMembers::GetSize(const WordSize wordSize) const { assert(m_flags & FLAG_FIELDS_CALCULATED); - return m_size; + return m_size[std::to_underlying(wordSize)]; } bool DefinitionWithMembers::IsAnonymous() const diff --git a/src/ZoneCodeGeneratorLib/Domain/Definition/DefinitionWithMembers.h b/src/ZoneCodeGeneratorLib/Domain/Definition/DefinitionWithMembers.h index 966a7a6d..4261d205 100644 --- a/src/ZoneCodeGeneratorLib/Domain/Definition/DefinitionWithMembers.h +++ b/src/ZoneCodeGeneratorLib/Domain/Definition/DefinitionWithMembers.h @@ -16,14 +16,14 @@ public: DefinitionWithMembers(std::string _namespace, std::string name, unsigned pack); - [[nodiscard]] unsigned GetAlignment() const override; + [[nodiscard]] unsigned GetAlignment(WordSize wordSize) const override; [[nodiscard]] bool GetForceAlignment() const override; - [[nodiscard]] unsigned GetSize() const override; + [[nodiscard]] unsigned GetSize(WordSize wordSize) const override; [[nodiscard]] bool IsAnonymous() const; unsigned m_flags; - unsigned m_size; - unsigned m_alignment; + unsigned m_size[WORD_SIZE_COUNT]; + unsigned m_alignment[WORD_SIZE_COUNT]; unsigned m_pack; std::vector> m_members; diff --git a/src/ZoneCodeGeneratorLib/Domain/Definition/EnumDefinition.cpp b/src/ZoneCodeGeneratorLib/Domain/Definition/EnumDefinition.cpp index 283309aa..e157a989 100644 --- a/src/ZoneCodeGeneratorLib/Domain/Definition/EnumDefinition.cpp +++ b/src/ZoneCodeGeneratorLib/Domain/Definition/EnumDefinition.cpp @@ -14,9 +14,9 @@ DataDefinitionType EnumDefinition::GetType() const return DataDefinitionType::ENUM; } -unsigned EnumDefinition::GetAlignment() const +unsigned EnumDefinition::GetAlignment(const WordSize wordSize) const { - return m_parent_type->GetAlignment(); + return m_parent_type->GetAlignment(wordSize); } bool EnumDefinition::GetForceAlignment() const @@ -24,9 +24,9 @@ bool EnumDefinition::GetForceAlignment() const return m_parent_type->GetForceAlignment(); } -unsigned EnumDefinition::GetSize() const +unsigned EnumDefinition::GetSize(const WordSize wordSize) const { - return m_parent_type->GetSize(); + return m_parent_type->GetSize(wordSize); } void EnumDefinition::AddEnumMember(EnumMember enumMember) diff --git a/src/ZoneCodeGeneratorLib/Domain/Definition/EnumDefinition.h b/src/ZoneCodeGeneratorLib/Domain/Definition/EnumDefinition.h index df45f951..04bff9c6 100644 --- a/src/ZoneCodeGeneratorLib/Domain/Definition/EnumDefinition.h +++ b/src/ZoneCodeGeneratorLib/Domain/Definition/EnumDefinition.h @@ -13,9 +13,9 @@ public: EnumDefinition(std::string _namespace, std::string name, const BaseTypeDefinition* parentType); [[nodiscard]] DataDefinitionType GetType() const override; - [[nodiscard]] unsigned GetAlignment() const override; + [[nodiscard]] unsigned GetAlignment(WordSize wordSize) const override; [[nodiscard]] bool GetForceAlignment() const override; - [[nodiscard]] unsigned GetSize() const override; + [[nodiscard]] unsigned GetSize(WordSize wordSize) const override; void AddEnumMember(EnumMember enumMember); diff --git a/src/ZoneCodeGeneratorLib/Domain/Definition/ForwardDeclaration.cpp b/src/ZoneCodeGeneratorLib/Domain/Definition/ForwardDeclaration.cpp index c5e472a7..4739edf9 100644 --- a/src/ZoneCodeGeneratorLib/Domain/Definition/ForwardDeclaration.cpp +++ b/src/ZoneCodeGeneratorLib/Domain/Definition/ForwardDeclaration.cpp @@ -12,7 +12,7 @@ DataDefinitionType ForwardDeclaration::GetType() const return DataDefinitionType::FORWARD_DECLARATION; } -unsigned ForwardDeclaration::GetAlignment() const +unsigned ForwardDeclaration::GetAlignment(const WordSize wordSize) const { return 0; } @@ -22,7 +22,7 @@ bool ForwardDeclaration::GetForceAlignment() const return false; } -unsigned ForwardDeclaration::GetSize() const +unsigned ForwardDeclaration::GetSize(const WordSize wordSize) const { return 0; } diff --git a/src/ZoneCodeGeneratorLib/Domain/Definition/ForwardDeclaration.h b/src/ZoneCodeGeneratorLib/Domain/Definition/ForwardDeclaration.h index c0c2a0f0..56b42bff 100644 --- a/src/ZoneCodeGeneratorLib/Domain/Definition/ForwardDeclaration.h +++ b/src/ZoneCodeGeneratorLib/Domain/Definition/ForwardDeclaration.h @@ -8,9 +8,9 @@ public: ForwardDeclaration(std::string _namespace, std::string name, DataDefinitionType type); [[nodiscard]] DataDefinitionType GetType() const override; - [[nodiscard]] unsigned GetAlignment() const override; + [[nodiscard]] unsigned GetAlignment(WordSize wordSize) const override; [[nodiscard]] bool GetForceAlignment() const override; - [[nodiscard]] unsigned GetSize() const override; + [[nodiscard]] unsigned GetSize(WordSize wordSize) const override; const DataDefinitionType m_forwarded_type; const DataDefinition* m_definition; diff --git a/src/ZoneCodeGeneratorLib/Domain/Definition/TypeDeclaration.cpp b/src/ZoneCodeGeneratorLib/Domain/Definition/TypeDeclaration.cpp index a7aeb157..c67a1265 100644 --- a/src/ZoneCodeGeneratorLib/Domain/Definition/TypeDeclaration.cpp +++ b/src/ZoneCodeGeneratorLib/Domain/Definition/TypeDeclaration.cpp @@ -10,22 +10,22 @@ TypeDeclaration::TypeDeclaration(const DataDefinition* type) m_type(type), m_custom_bit_size(0), m_flags(0), - m_size(0), - m_alignment(0) + m_size{}, + m_alignment{} { assert(m_type != nullptr); } -unsigned TypeDeclaration::GetSize() const +unsigned TypeDeclaration::GetSize(const WordSize wordSize) const { assert(m_flags & FLAG_FIELDS_CALCULATED); - return m_size; + return m_size[std::to_underlying(wordSize)]; } -unsigned TypeDeclaration::GetAlignment() const +unsigned TypeDeclaration::GetAlignment(const WordSize wordSize) const { assert(m_flags & FLAG_FIELDS_CALCULATED); - return m_alignment; + return m_alignment[std::to_underlying(wordSize)]; } bool TypeDeclaration::GetForceAlignment() const diff --git a/src/ZoneCodeGeneratorLib/Domain/Definition/TypeDeclaration.h b/src/ZoneCodeGeneratorLib/Domain/Definition/TypeDeclaration.h index 12f106d4..9835b003 100644 --- a/src/ZoneCodeGeneratorLib/Domain/Definition/TypeDeclaration.h +++ b/src/ZoneCodeGeneratorLib/Domain/Definition/TypeDeclaration.h @@ -2,6 +2,7 @@ #include "DataDefinition.h" #include "DeclarationModifier.h" +#include "Domain/WordSize.h" #include #include @@ -14,8 +15,8 @@ public: explicit TypeDeclaration(const DataDefinition* type); - [[nodiscard]] unsigned GetSize() const; - [[nodiscard]] unsigned GetAlignment() const; + [[nodiscard]] unsigned GetSize(WordSize wordSize) const; + [[nodiscard]] unsigned GetAlignment(WordSize wordSize) const; [[nodiscard]] bool GetForceAlignment() const; std::vector> m_declaration_modifiers; @@ -27,6 +28,6 @@ public: unsigned m_custom_bit_size; unsigned m_flags; - unsigned m_size; - unsigned m_alignment; + unsigned m_size[WORD_SIZE_COUNT]; + unsigned m_alignment[WORD_SIZE_COUNT]; }; diff --git a/src/ZoneCodeGeneratorLib/Domain/Definition/TypedefDefinition.cpp b/src/ZoneCodeGeneratorLib/Domain/Definition/TypedefDefinition.cpp index 916082ec..c0ebb8d0 100644 --- a/src/ZoneCodeGeneratorLib/Domain/Definition/TypedefDefinition.cpp +++ b/src/ZoneCodeGeneratorLib/Domain/Definition/TypedefDefinition.cpp @@ -13,13 +13,14 @@ DataDefinitionType TypedefDefinition::GetType() const return DataDefinitionType::TYPEDEF; } -unsigned TypedefDefinition::GetAlignment() const +unsigned TypedefDefinition::GetAlignment(WordSize wordSize) const { if (m_has_alignment_override) { return m_alignment_override; } - return m_type_declaration->GetAlignment(); + + return m_type_declaration->GetAlignment(wordSize); } bool TypedefDefinition::GetForceAlignment() const @@ -27,7 +28,7 @@ bool TypedefDefinition::GetForceAlignment() const return m_has_alignment_override || m_type_declaration->GetForceAlignment(); } -unsigned TypedefDefinition::GetSize() const +unsigned TypedefDefinition::GetSize(const WordSize wordSize) const { - return m_type_declaration->GetSize(); + return m_type_declaration->GetSize(wordSize); } diff --git a/src/ZoneCodeGeneratorLib/Domain/Definition/TypedefDefinition.h b/src/ZoneCodeGeneratorLib/Domain/Definition/TypedefDefinition.h index 55e62def..0518b42f 100644 --- a/src/ZoneCodeGeneratorLib/Domain/Definition/TypedefDefinition.h +++ b/src/ZoneCodeGeneratorLib/Domain/Definition/TypedefDefinition.h @@ -9,9 +9,9 @@ public: TypedefDefinition(std::string _namespace, std::string name, std::unique_ptr typeDeclaration); [[nodiscard]] DataDefinitionType GetType() const override; - [[nodiscard]] unsigned GetAlignment() const override; + [[nodiscard]] unsigned GetAlignment(WordSize wordSize) const override; [[nodiscard]] bool GetForceAlignment() const override; - [[nodiscard]] unsigned GetSize() const override; + [[nodiscard]] unsigned GetSize(WordSize wordSize) const override; bool m_has_alignment_override; unsigned m_alignment_override; diff --git a/src/ZoneCodeGeneratorLib/Domain/Definition/Variable.cpp b/src/ZoneCodeGeneratorLib/Domain/Definition/Variable.cpp index 526bba32..10ca9770 100644 --- a/src/ZoneCodeGeneratorLib/Domain/Definition/Variable.cpp +++ b/src/ZoneCodeGeneratorLib/Domain/Definition/Variable.cpp @@ -9,12 +9,12 @@ Variable::Variable(std::string name, std::unique_ptr typeDeclar { } -unsigned Variable::GetAlignment() const +unsigned Variable::GetAlignment(const WordSize wordSize) const { if (m_has_alignment_override) return m_alignment_override; - return m_type_declaration->GetAlignment(); + return m_type_declaration->GetAlignment(wordSize); } bool Variable::GetForceAlignment() const diff --git a/src/ZoneCodeGeneratorLib/Domain/Definition/Variable.h b/src/ZoneCodeGeneratorLib/Domain/Definition/Variable.h index 3a89f76b..a2117a6a 100644 --- a/src/ZoneCodeGeneratorLib/Domain/Definition/Variable.h +++ b/src/ZoneCodeGeneratorLib/Domain/Definition/Variable.h @@ -10,7 +10,7 @@ class Variable public: Variable(std::string name, std::unique_ptr typeDeclaration); - [[nodiscard]] unsigned GetAlignment() const; + [[nodiscard]] unsigned GetAlignment(WordSize wordSize) const; [[nodiscard]] bool GetForceAlignment() const; std::string m_name; diff --git a/src/ZoneCodeGeneratorLib/Domain/FastFile/FastFileBlock.cpp b/src/ZoneCodeGeneratorLib/Domain/FastFileBlock.cpp similarity index 100% rename from src/ZoneCodeGeneratorLib/Domain/FastFile/FastFileBlock.cpp rename to src/ZoneCodeGeneratorLib/Domain/FastFileBlock.cpp diff --git a/src/ZoneCodeGeneratorLib/Domain/FastFile/FastFileBlock.h b/src/ZoneCodeGeneratorLib/Domain/FastFileBlock.h similarity index 100% rename from src/ZoneCodeGeneratorLib/Domain/FastFile/FastFileBlock.h rename to src/ZoneCodeGeneratorLib/Domain/FastFileBlock.h diff --git a/src/ZoneCodeGeneratorLib/Domain/GameVariant.cpp b/src/ZoneCodeGeneratorLib/Domain/GameVariant.cpp new file mode 100644 index 00000000..c35787f1 --- /dev/null +++ b/src/ZoneCodeGeneratorLib/Domain/GameVariant.cpp @@ -0,0 +1,8 @@ +#include "GameVariant.h" + +GameVariant::GameVariant(std::string name, const WordSize wordSize, const std::endian endianness) + : m_name(std::move(name)), + m_word_size(wordSize), + m_endianness(endianness) +{ +} diff --git a/src/ZoneCodeGeneratorLib/Domain/GameVariant.h b/src/ZoneCodeGeneratorLib/Domain/GameVariant.h new file mode 100644 index 00000000..d7ed6323 --- /dev/null +++ b/src/ZoneCodeGeneratorLib/Domain/GameVariant.h @@ -0,0 +1,16 @@ +#pragma once + +#include "WordSize.h" + +#include +#include + +class GameVariant +{ +public: + GameVariant(std::string name, WordSize wordSize, std::endian endianness); + + std::string m_name; + WordSize m_word_size; + std::endian m_endianness; +}; diff --git a/src/ZoneCodeGeneratorLib/Domain/Information/MemberInformation.h b/src/ZoneCodeGeneratorLib/Domain/Information/MemberInformation.h index 841544c2..721d9608 100644 --- a/src/ZoneCodeGeneratorLib/Domain/Information/MemberInformation.h +++ b/src/ZoneCodeGeneratorLib/Domain/Information/MemberInformation.h @@ -2,7 +2,7 @@ #include "Domain/Definition/Variable.h" #include "Domain/Evaluation/IEvaluation.h" -#include "Domain/FastFile/FastFileBlock.h" +#include "Domain/FastFileBlock.h" #include "StructureInformation.h" #include "TypeInformation.h" diff --git a/src/ZoneCodeGeneratorLib/Domain/Information/StructureInformation.h b/src/ZoneCodeGeneratorLib/Domain/Information/StructureInformation.h index bc15daec..89bda578 100644 --- a/src/ZoneCodeGeneratorLib/Domain/Information/StructureInformation.h +++ b/src/ZoneCodeGeneratorLib/Domain/Information/StructureInformation.h @@ -3,7 +3,7 @@ #include "Domain/Definition/DefinitionWithMembers.h" #include "Domain/Definition/EnumMember.h" #include "Domain/Extension/CustomAction.h" -#include "Domain/FastFile/FastFileBlock.h" +#include "Domain/FastFileBlock.h" #include "MemberInformation.h" #include "TypeInformation.h" diff --git a/src/ZoneCodeGeneratorLib/Domain/Environment/WordSize.cpp b/src/ZoneCodeGeneratorLib/Domain/WordSize.cpp similarity index 100% rename from src/ZoneCodeGeneratorLib/Domain/Environment/WordSize.cpp rename to src/ZoneCodeGeneratorLib/Domain/WordSize.cpp diff --git a/src/ZoneCodeGeneratorLib/Domain/Environment/WordSize.h b/src/ZoneCodeGeneratorLib/Domain/WordSize.h similarity index 71% rename from src/ZoneCodeGeneratorLib/Domain/Environment/WordSize.h rename to src/ZoneCodeGeneratorLib/Domain/WordSize.h index d7a80b58..666fc7f0 100644 --- a/src/ZoneCodeGeneratorLib/Domain/Environment/WordSize.h +++ b/src/ZoneCodeGeneratorLib/Domain/WordSize.h @@ -1,13 +1,16 @@ #pragma once #include +#include enum class WordSize : std::uint8_t { - UNKNOWN, BITS_32, - BITS_64 + BITS_64, + + COUNT }; +static constexpr auto WORD_SIZE_COUNT = std::to_underlying(WordSize::COUNT); static constexpr WordSize OWN_WORD_SIZE = #if defined(ARCH_x86) diff --git a/src/ZoneCodeGeneratorLib/Generating/BaseRenderingContext.cpp b/src/ZoneCodeGeneratorLib/Generating/BaseRenderingContext.cpp index 5182aa54..147c5648 100644 --- a/src/ZoneCodeGeneratorLib/Generating/BaseRenderingContext.cpp +++ b/src/ZoneCodeGeneratorLib/Generating/BaseRenderingContext.cpp @@ -1,9 +1,15 @@ #include "BaseRenderingContext.h" -BaseRenderingContext::BaseRenderingContext(std::string game, const WordSize gameWordSize, std::vector fastFileBlocks) +BaseRenderingContext::BaseRenderingContext(std::string game, + const WordSize gameWordSize, + const std::endian endianness, + std::vector fastFileBlocks) : m_game(std::move(game)), m_word_size_mismatch(gameWordSize != OWN_WORD_SIZE), + m_word_size(gameWordSize), m_pointer_size(GetPointerSizeForWordSize(gameWordSize)), + m_endianness_mismatch(std::endian::native != endianness), + m_endianness(endianness), m_blocks(std::move(fastFileBlocks)), m_default_normal_block(nullptr), m_default_temp_block(nullptr) diff --git a/src/ZoneCodeGeneratorLib/Generating/BaseRenderingContext.h b/src/ZoneCodeGeneratorLib/Generating/BaseRenderingContext.h index 89f690c4..ed312aba 100644 --- a/src/ZoneCodeGeneratorLib/Generating/BaseRenderingContext.h +++ b/src/ZoneCodeGeneratorLib/Generating/BaseRenderingContext.h @@ -10,12 +10,15 @@ class BaseRenderingContext public: std::string m_game; bool m_word_size_mismatch; + WordSize m_word_size; unsigned m_pointer_size; + bool m_endianness_mismatch; + std::endian m_endianness; std::vector m_blocks; const FastFileBlock* m_default_normal_block; const FastFileBlock* m_default_temp_block; protected: - BaseRenderingContext(std::string game, WordSize gameWordSize, std::vector fastFileBlocks); + BaseRenderingContext(std::string game, WordSize gameWordSize, std::endian endianness, std::vector fastFileBlocks); }; diff --git a/src/ZoneCodeGeneratorLib/Generating/CodeGenerator.cpp b/src/ZoneCodeGeneratorLib/Generating/CodeGenerator.cpp index 71c403ea..65620f60 100644 --- a/src/ZoneCodeGeneratorLib/Generating/CodeGenerator.cpp +++ b/src/ZoneCodeGeneratorLib/Generating/CodeGenerator.cpp @@ -141,38 +141,41 @@ bool CodeGenerator::GenerateCode(const IDataRepository* repository) return false; } - for (auto* asset : assets) + for (auto* variant : repository->GetGameVariants()) { - auto context = OncePerAssetRenderingContext::BuildContext(repository, asset); - const auto result = GenerateCodeOncePerAsset(*context, foundTemplate->second.get()); - switch (result) + for (auto* asset : assets) { - case utils::TextFileCheckDirtyResult::OUTPUT_WRITTEN: - con::info("Successfully generated code for asset '{}' with preset '{}'", asset->m_definition->GetFullName(), foundTemplate->first); - break; - case utils::TextFileCheckDirtyResult::OUTPUT_WAS_UP_TO_DATE: - con::info("Code was up to date for asset '{}' with preset '{}'", asset->m_definition->GetFullName(), foundTemplate->first); - break; - case utils::TextFileCheckDirtyResult::FAILURE: - con::error("Failed to generate code for asset '{}' with preset '{}'", asset->m_definition->GetFullName(), foundTemplate->first); - return false; + auto context = OncePerAssetRenderingContext::BuildContext(repository, asset, variant); + const auto result = GenerateCodeOncePerAsset(*context, foundTemplate->second.get()); + switch (result) + { + case utils::TextFileCheckDirtyResult::OUTPUT_WRITTEN: + con::info("Successfully generated code for asset '{}' with preset '{}'", asset->m_definition->GetFullName(), foundTemplate->first); + break; + case utils::TextFileCheckDirtyResult::OUTPUT_WAS_UP_TO_DATE: + con::info("Code was up to date for asset '{}' with preset '{}'", asset->m_definition->GetFullName(), foundTemplate->first); + break; + case utils::TextFileCheckDirtyResult::FAILURE: + con::error("Failed to generate code for asset '{}' with preset '{}'", asset->m_definition->GetFullName(), foundTemplate->first); + return false; + } } - } - { - auto context = OncePerTemplateRenderingContext::BuildContext(repository); - const auto result = GenerateCodeOncePerTemplate(*context, foundTemplate->second.get()); - switch (result) { - case utils::TextFileCheckDirtyResult::OUTPUT_WRITTEN: - con::info("Successfully generated code with preset '{}'", foundTemplate->first); - break; - case utils::TextFileCheckDirtyResult::OUTPUT_WAS_UP_TO_DATE: - con::info("Code was up to date for preset '{}'", foundTemplate->first); - break; - case utils::TextFileCheckDirtyResult::FAILURE: - con::error("Failed to generate code with preset '{}'", foundTemplate->first); - return false; + auto context = OncePerTemplateRenderingContext::BuildContext(repository, variant); + const auto result = GenerateCodeOncePerTemplate(*context, foundTemplate->second.get()); + switch (result) + { + case utils::TextFileCheckDirtyResult::OUTPUT_WRITTEN: + con::info("Successfully generated code with preset '{}'", foundTemplate->first); + break; + case utils::TextFileCheckDirtyResult::OUTPUT_WAS_UP_TO_DATE: + con::info("Code was up to date for preset '{}'", foundTemplate->first); + break; + case utils::TextFileCheckDirtyResult::FAILURE: + con::error("Failed to generate code with preset '{}'", foundTemplate->first); + return false; + } } } } diff --git a/src/ZoneCodeGeneratorLib/Generating/OncePerAssetRenderingContext.cpp b/src/ZoneCodeGeneratorLib/Generating/OncePerAssetRenderingContext.cpp index 0c117c4f..0f70224a 100644 --- a/src/ZoneCodeGeneratorLib/Generating/OncePerAssetRenderingContext.cpp +++ b/src/ZoneCodeGeneratorLib/Generating/OncePerAssetRenderingContext.cpp @@ -18,8 +18,11 @@ RenderingUsedType::RenderingUsedType(const DataDefinition* type, StructureInform { } -OncePerAssetRenderingContext::OncePerAssetRenderingContext(std::string game, const WordSize gameWordSize, std::vector fastFileBlocks) - : BaseRenderingContext(std::move(game), gameWordSize, std::move(fastFileBlocks)), +OncePerAssetRenderingContext::OncePerAssetRenderingContext(std::string game, + const WordSize gameWordSize, + const std::endian endianness, + std::vector fastFileBlocks) + : BaseRenderingContext(std::move(game), gameWordSize, endianness, std::move(fastFileBlocks)), m_asset(nullptr), m_has_actions(false) { @@ -185,10 +188,11 @@ bool OncePerAssetRenderingContext::UsedTypeHasActions(const RenderingUsedType* u return false; } -std::unique_ptr OncePerAssetRenderingContext::BuildContext(const IDataRepository* repository, StructureInformation* asset) +std::unique_ptr + OncePerAssetRenderingContext::BuildContext(const IDataRepository* repository, StructureInformation* asset, const GameVariant* variant) { auto context = std::make_unique( - OncePerAssetRenderingContext(repository->GetGameName(), repository->GetWordSize(), repository->GetAllFastFileBlocks())); + OncePerAssetRenderingContext(repository->GetGameName(), variant->m_word_size, variant->m_endianness, repository->GetAllFastFileBlocks())); context->MakeAsset(repository, asset); context->CreateUsedTypeCollections(); diff --git a/src/ZoneCodeGeneratorLib/Generating/OncePerAssetRenderingContext.h b/src/ZoneCodeGeneratorLib/Generating/OncePerAssetRenderingContext.h index fc9d9201..5529ef0b 100644 --- a/src/ZoneCodeGeneratorLib/Generating/OncePerAssetRenderingContext.h +++ b/src/ZoneCodeGeneratorLib/Generating/OncePerAssetRenderingContext.h @@ -28,7 +28,8 @@ public: class OncePerAssetRenderingContext : public BaseRenderingContext { public: - static std::unique_ptr BuildContext(const IDataRepository* repository, StructureInformation* asset); + static std::unique_ptr + BuildContext(const IDataRepository* repository, StructureInformation* asset, const GameVariant* variant); StructureInformation* m_asset; @@ -38,7 +39,7 @@ public: bool m_has_actions; private: - OncePerAssetRenderingContext(std::string game, WordSize gameWordSize, std::vector fastFileBlocks); + OncePerAssetRenderingContext(std::string game, WordSize gameWordSize, std::endian endianness, std::vector fastFileBlocks); RenderingUsedType* AddUsedType(std::unique_ptr usedType); RenderingUsedType* GetBaseType(const IDataRepository* repository, MemberComputations* computations, RenderingUsedType* usedType); diff --git a/src/ZoneCodeGeneratorLib/Generating/OncePerTemplateRenderingContext.cpp b/src/ZoneCodeGeneratorLib/Generating/OncePerTemplateRenderingContext.cpp index c36e131a..f6d183da 100644 --- a/src/ZoneCodeGeneratorLib/Generating/OncePerTemplateRenderingContext.cpp +++ b/src/ZoneCodeGeneratorLib/Generating/OncePerTemplateRenderingContext.cpp @@ -6,9 +6,10 @@ OncePerTemplateRenderingContext::OncePerTemplateRenderingContext(std::string game, const WordSize gameWordSize, + const std::endian endianness, std::vector fastFileBlocks, std::vector assets) - : BaseRenderingContext(std::move(game), gameWordSize, std::move(fastFileBlocks)), + : BaseRenderingContext(std::move(game), gameWordSize, endianness, std::move(fastFileBlocks)), m_assets(std::move(assets)) { for (const auto* block : m_blocks) @@ -23,7 +24,7 @@ OncePerTemplateRenderingContext::OncePerTemplateRenderingContext(std::string gam } } -std::unique_ptr OncePerTemplateRenderingContext::BuildContext(const IDataRepository* repository) +std::unique_ptr OncePerTemplateRenderingContext::BuildContext(const IDataRepository* repository, const GameVariant* variant) { std::vector assetInformation; for (auto* info : repository->GetAllStructureInformation()) @@ -34,6 +35,6 @@ std::unique_ptr OncePerTemplateRenderingContext assetInformation.emplace_back(info); } - return std::make_unique( - OncePerTemplateRenderingContext(repository->GetGameName(), repository->GetWordSize(), repository->GetAllFastFileBlocks(), assetInformation)); + return std::make_unique(OncePerTemplateRenderingContext( + repository->GetGameName(), variant->m_word_size, variant->m_endianness, repository->GetAllFastFileBlocks(), assetInformation)); } diff --git a/src/ZoneCodeGeneratorLib/Generating/OncePerTemplateRenderingContext.h b/src/ZoneCodeGeneratorLib/Generating/OncePerTemplateRenderingContext.h index bfa5cf56..32ee4ead 100644 --- a/src/ZoneCodeGeneratorLib/Generating/OncePerTemplateRenderingContext.h +++ b/src/ZoneCodeGeneratorLib/Generating/OncePerTemplateRenderingContext.h @@ -9,13 +9,14 @@ class OncePerTemplateRenderingContext : public BaseRenderingContext { public: - static std::unique_ptr BuildContext(const IDataRepository* repository); + static std::unique_ptr BuildContext(const IDataRepository* repository, const GameVariant* variant); std::vector m_assets; private: OncePerTemplateRenderingContext(std::string game, WordSize gameWordSize, + std::endian endianness, std::vector fastFileBlocks, std::vector assets); }; diff --git a/src/ZoneCodeGeneratorLib/Generating/Templates/AssetStructTestsTemplate.cpp b/src/ZoneCodeGeneratorLib/Generating/Templates/AssetStructTestsTemplate.cpp index 0c2455b5..7e521f0b 100644 --- a/src/ZoneCodeGeneratorLib/Generating/Templates/AssetStructTestsTemplate.cpp +++ b/src/ZoneCodeGeneratorLib/Generating/Templates/AssetStructTestsTemplate.cpp @@ -70,8 +70,8 @@ namespace LINE("") - LINEF("REQUIRE({0}u == sizeof({1}));", structure->m_definition->GetSize(), structure->m_definition->GetFullName()) - LINEF("REQUIRE({0}u == alignof({1}));", structure->m_definition->GetAlignment(), structure->m_definition->GetFullName()) + LINEF("REQUIRE({0}u == sizeof({1}));", structure->m_definition->GetSize(m_env.m_word_size), structure->m_definition->GetFullName()) + LINEF("REQUIRE({0}u == alignof({1}));", structure->m_definition->GetAlignment(m_env.m_word_size), structure->m_definition->GetFullName()) m_intendation--; LINE("}") } diff --git a/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.cpp b/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.cpp index b2b266f8..9a66c1a3 100644 --- a/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.cpp +++ b/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.cpp @@ -256,12 +256,12 @@ void BaseTemplate::MakeEvaluationInternal(const IEvaluation* evaluation, std::os MakeOperandDynamic(dynamic_cast(evaluation), str); } -std::string BaseTemplate::MakeAllocAlignment(const StructureInformation& info) +std::string BaseTemplate::MakeAllocAlignment(const StructureInformation& info) const { if (info.m_alloc_alignment) return MakeEvaluation(info.m_alloc_alignment.get()); - return std::to_string(info.m_definition->GetAlignment()); + return std::to_string(info.m_definition->GetAlignment(m_env.m_word_size)); } std::string BaseTemplate::MakeEvaluation(const IEvaluation* evaluation) @@ -284,12 +284,12 @@ size_t BaseTemplate::SizeForDeclModifierLevel(const MemberInformation& memberInf { const auto& declModifiers = memberInfo.m_member->m_type_declaration->m_declaration_modifiers; if (declModifiers.empty()) - return memberInfo.m_member->m_type_declaration->GetSize(); + return memberInfo.m_member->m_type_declaration->GetSize(m_env.m_word_size); if (level == 0) - return memberInfo.m_member->m_type_declaration->GetSize(); + return memberInfo.m_member->m_type_declaration->GetSize(m_env.m_word_size); - size_t currentSize = memberInfo.m_member->m_type_declaration->m_type->GetSize(); + size_t currentSize = memberInfo.m_member->m_type_declaration->m_type->GetSize(m_env.m_word_size); const auto end = declModifiers.rbegin() + (declModifiers.size() - level); for (auto i = declModifiers.rbegin(); i != end; ++i) { diff --git a/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.h b/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.h index 9eeb3205..daad73ed 100644 --- a/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.h +++ b/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.h @@ -33,7 +33,7 @@ protected: static std::string MakeArrayIndices(const DeclarationModifierComputations& modifierComputations); static std::string MakeCustomActionCall(const CustomAction* action); static std::string MakeArrayCount(const ArrayDeclarationModifier* arrayModifier); - static std::string MakeAllocAlignment(const StructureInformation& info); + std::string MakeAllocAlignment(const StructureInformation& info) const; static std::string MakeEvaluation(const IEvaluation* evaluation); static bool ShouldGenerateFillMethod(const RenderingUsedType& type); diff --git a/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneLoadTemplate.cpp b/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneLoadTemplate.cpp index 3442e103..34e88814 100644 --- a/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneLoadTemplate.cpp +++ b/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneLoadTemplate.cpp @@ -397,14 +397,14 @@ namespace LINEF("FillStruct_{0}(fillAccessor.AtOffset({1} + i * {2}));", MakeSafeTypeName(memberInfo.m_member->m_type_declaration->m_type), OffsetForMemberModifier(memberInfo, modifier, nestedBaseOffset), - memberInfo.m_member->m_type_declaration->GetSize()) + memberInfo.m_member->m_type_declaration->GetSize(m_env.m_word_size)) } else { LINEF("fillAccessor.Fill({0}[i], {1} + i * {2});", MakeMemberAccess(&structInfo, &memberInfo, modifier), OffsetForMemberModifier(memberInfo, modifier, nestedBaseOffset), - memberInfo.m_member->m_type_declaration->GetSize()) + memberInfo.m_member->m_type_declaration->GetSize(m_env.m_word_size)) } m_intendation--; LINE("}") @@ -463,7 +463,7 @@ namespace LINEF("FillStruct_{0}(fillAccessor.AtOffset({1} + i * {2}));", MakeSafeTypeName(memberInfo.m_member->m_type_declaration->m_type), OffsetForMemberModifier(memberInfo, modifier, nestedBaseOffset), - memberInfo.m_member->m_type_declaration->m_type->GetSize()) + memberInfo.m_member->m_type_declaration->m_type->GetSize(m_env.m_word_size)) m_intendation--; LINE("}") } @@ -718,7 +718,7 @@ namespace if (memberComputations.HasDynamicArraySize()) { LINEF("const auto dynamicArrayEntries = static_cast({0});", MakeEvaluation(modifier.GetDynamicArraySizeEvaluation())) - LINEF("m_stream.AppendToFill(dynamicArrayEntries * {0});", member.m_member->m_type_declaration->m_type->GetSize()) + LINEF("m_stream.AppendToFill(dynamicArrayEntries * {0});", member.m_member->m_type_declaration->m_type->GetSize(m_env.m_word_size)) LINEF("return dynamicArrayEntries * sizeof({0}{1}) + offsetof({2}, {3});", MakeTypeDecl(member.m_member->m_type_declaration.get()), MakeFollowingReferences(modifier.GetAllDeclarationModifiers()), @@ -735,7 +735,7 @@ namespace } else { - LINEF("m_stream.AppendToFill({0});", member.m_member->m_type_declaration->GetSize()) + LINEF("m_stream.AppendToFill({0});", member.m_member->m_type_declaration->GetSize(m_env.m_word_size)) LINEF("return sizeof({0}{1}) + offsetof({2}, {3});", MakeTypeDecl(member.m_member->m_type_declaration.get()), MakeFollowingReferences(modifier.GetAllDeclarationModifiers()), @@ -888,7 +888,7 @@ namespace void PrintLoadPtrArrayMethod_Loading(const DataDefinition* def, const StructureInformation* info) const { - const auto alignment = info && def == info->m_definition ? MakeAllocAlignment(*info) : std::to_string(def->GetAlignment()); + const auto alignment = info && def == info->m_definition ? MakeAllocAlignment(*info) : std::to_string(def->GetAlignment(m_env.m_word_size)); if (info && !info->m_has_matching_cross_platform_structure && StructureComputations(info).GetDynamicMember()) { assert(def == info->m_definition); @@ -1043,7 +1043,7 @@ namespace LINE("{") m_intendation++; - LINEF("const auto arrayFill = m_stream.LoadWithFill({0} * count);", def->GetSize()) + LINEF("const auto arrayFill = m_stream.LoadWithFill({0} * count);", def->GetSize(m_env.m_word_size)) LINEF("auto* arrayStart = {0};", MakeTypeVarName(def)) LINEF("auto* var = {0};", MakeTypeVarName(def)) LINE("for (size_t index = 0; index < count; index++)") @@ -1051,7 +1051,7 @@ namespace m_intendation++; LINEF("{0} = var;", MakeTypeVarName(info->m_definition)) - LINEF("FillStruct_{0}(arrayFill.AtOffset(0 + {1} * index));", info->m_definition->m_name, def->GetSize()) + LINEF("FillStruct_{0}(arrayFill.AtOffset(0 + {1} * index));", info->m_definition->m_name, def->GetSize(m_env.m_word_size)) LINE("var++;") m_intendation--; @@ -1162,14 +1162,14 @@ namespace else if (member->m_type && !member->m_type->m_has_matching_cross_platform_structure) { LINEF("const auto fillArraySize = static_cast({0});", MakeEvaluation(modifier.GetArrayPointerCountEvaluation())) - LINEF("const auto fill = m_stream.LoadWithFill({0} * fillArraySize);", member->m_member->m_type_declaration->m_type->GetSize()) + LINEF("const auto fill = m_stream.LoadWithFill({0} * fillArraySize);", member->m_member->m_type_declaration->m_type->GetSize(m_env.m_word_size)) LINE("for (auto i = 0uz; i < fillArraySize; i++)") LINE("{") m_intendation++; LINEF("{0} = &{1}[i];", MakeTypeVarName(member->m_type->m_definition), MakeMemberAccess(info, member, modifier)) LINEF("FillStruct_{0}(fill.AtOffset(i * {1}));", MakeSafeTypeName(member->m_type->m_definition), - member->m_member->m_type_declaration->m_type->GetSize()) + member->m_member->m_type_declaration->m_type->GetSize(m_env.m_word_size)) m_intendation--; LINE("}") } @@ -1337,7 +1337,7 @@ namespace LINEF("{0} = {1};", MakeTypeVarName(member->m_member->m_type_declaration->m_type), MakeMemberAccess(info, member, modifier)) LINEF("FillStruct_{0}(m_stream.LoadWithFill({1}));", MakeSafeTypeName(member->m_member->m_type_declaration->m_type), - member->m_member->m_type_declaration->m_type->GetSize()) + member->m_member->m_type_declaration->m_type->GetSize(m_env.m_word_size)) } else { @@ -1460,7 +1460,7 @@ namespace } else { - LINEF("m_stream.Alloc({0});", modifier.GetAlignment()) + LINEF("m_stream.Alloc({0});", modifier.GetAlignment(m_env.m_word_size)) } LINEF("const auto allocSize = LoadDynamicFill_{0}(m_stream.LoadWithFill(0));", MakeSafeTypeName(member->m_type->m_definition)) @@ -1491,7 +1491,7 @@ namespace } else { - LINE_MIDDLEF("{0}", modifier.GetAlignment()) + LINE_MIDDLEF("{0}", modifier.GetAlignment(m_env.m_word_size)) } if (allocOutOfBlock && modifier.IsArrayPointer()) @@ -1617,7 +1617,7 @@ namespace if (loadType == MemberLoadType::POINTER_ARRAY) { LINE_MIDDLEF(".OrNulled({0}uz * ({1}), sizeof({2}{3}) * ({1}), m_memory)", - member->m_member->m_type_declaration->GetSize(), + member->m_member->m_type_declaration->GetSize(m_env.m_word_size), MakeEvaluation(modifier.GetPointerArrayCountEvaluation()), MakeTypeDecl(member->m_member->m_type_declaration.get()), MakeFollowingReferences(modifier.GetFollowingDeclarationModifiers())) @@ -1884,7 +1884,7 @@ namespace LINEF("m_stream.Load<{0}>({1}); // Size: {2}", info->m_definition->GetFullName(), MakeTypeVarName(info->m_definition), - info->m_definition->GetSize()) + info->m_definition->GetSize(m_env.m_word_size)) } else { @@ -1898,7 +1898,8 @@ namespace { if (dynamicMember == nullptr) { - LINEF("FillStruct_{0}(m_stream.LoadWithFill({1}));", MakeSafeTypeName(info->m_definition), info->m_definition->GetSize()) + LINEF( + "FillStruct_{0}(m_stream.LoadWithFill({1}));", MakeSafeTypeName(info->m_definition), info->m_definition->GetSize(m_env.m_word_size)) } else if (info->m_non_embedded_reference_exists) { diff --git a/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneWriteTemplate.cpp b/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneWriteTemplate.cpp index fd484bb4..02fb52f8 100644 --- a/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneWriteTemplate.cpp +++ b/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneWriteTemplate.cpp @@ -489,20 +489,21 @@ namespace LINEF("const auto fillArraySize = static_cast({0});", MakeEvaluation(modifier.GetArrayPointerCountEvaluation())) if (!computations.IsInRuntimeBlock()) { - LINEF("const auto fill = m_stream->WriteWithFill({0} * fillArraySize);", member->m_member->m_type_declaration->m_type->GetSize()) + LINEF("const auto fill = m_stream->WriteWithFill({0} * fillArraySize);", + member->m_member->m_type_declaration->m_type->GetSize(m_env.m_word_size)) LINE("for (auto i = 0uz; i < fillArraySize; i++)") LINE("{") m_intendation++; LINEF("{0} = &{1}[i];", MakeTypeVarName(member->m_type->m_definition), MakeMemberAccess(info, member, modifier)) LINEF("FillStruct_{0}(fill.AtOffset(i * {1}));", MakeSafeTypeName(member->m_type->m_definition), - member->m_member->m_type_declaration->m_type->GetSize()) + member->m_member->m_type_declaration->m_type->GetSize(m_env.m_word_size)) m_intendation--; LINE("}") } else { - LINEF("m_stream->IncBlockPos({0} * fillArraySize);", member->m_member->m_type_declaration->m_type->GetSize()) + LINEF("m_stream->IncBlockPos({0} * fillArraySize);", member->m_member->m_type_declaration->m_type->GetSize(m_env.m_word_size)) } } else @@ -626,7 +627,7 @@ namespace LINEF("{0} = {1};", MakeTypeVarName(member->m_member->m_type_declaration->m_type), MakeMemberAccess(info, member, modifier)) LINEF("FillStruct_{0}(m_stream->WriteWithFill({1}));", MakeSafeTypeName(member->m_member->m_type_declaration->m_type), - member->m_member->m_type_declaration->m_type->GetSize()) + member->m_member->m_type_declaration->m_type->GetSize(m_env.m_word_size)) } else { @@ -738,7 +739,7 @@ namespace { if (member->m_type && !member->m_type->m_has_matching_cross_platform_structure) { - LINE_MIDDLEF(", {0}", member->m_type->m_definition->GetSize()) + LINE_MIDDLEF(", {0}", member->m_type->m_definition->GetSize(m_env.m_word_size)) } LINE_MIDDLEF(", {0}", MakeEvaluation(modifier.GetArrayPointerCountEvaluation())) @@ -813,7 +814,7 @@ namespace } else { - LINEF("m_stream->Align({0});", modifier.GetAlignment()) + LINEF("m_stream->Align({0});", modifier.GetAlignment(m_env.m_word_size)) } WriteMember_InsertReuse(info, member, modifier, writeType); @@ -1115,7 +1116,7 @@ namespace MakeTypeWrittenVarName(info->m_definition), info->m_definition->GetFullName(), MakeTypeVarName(info->m_definition), - info->m_definition->GetSize()) + info->m_definition->GetSize(m_env.m_word_size)) } else { @@ -1132,7 +1133,7 @@ namespace LINE("{") m_intendation++; LINEF("const auto fillAccessor = m_stream->WriteWithFill({0});", - dynamicMember == nullptr ? info->m_definition->GetSize() : dynamicMember->m_member->m_offset) + dynamicMember == nullptr ? info->m_definition->GetSize(m_env.m_word_size) : dynamicMember->m_member->m_offset) LINEF("{0} = fillAccessor.Offset();", MakeTypeWrittenVarName(info->m_definition)) LINEF("FillStruct_{0}(fillAccessor);", MakeSafeTypeName(info->m_definition)) m_intendation--; @@ -1265,7 +1266,7 @@ namespace LINEF("FillStruct_{0}(fillAccessor.AtOffset({1} + i * {2}));", MakeSafeTypeName(memberInfo.m_member->m_type_declaration->m_type), OffsetForMemberModifier(memberInfo, modifier, nestedBaseOffset), - memberInfo.m_member->m_type_declaration->m_type->GetSize()) + memberInfo.m_member->m_type_declaration->m_type->GetSize(m_env.m_word_size)) m_intendation--; LINE("}") } @@ -1478,7 +1479,7 @@ namespace void PrintWritePtrArrayMethod_Loading(const DataDefinition* def, const StructureInformation* info, const bool reusable) const { - const auto alignment = info && def == info->m_definition ? MakeAllocAlignment(*info) : std::to_string(def->GetAlignment()); + const auto alignment = info && def == info->m_definition ? MakeAllocAlignment(*info) : std::to_string(def->GetAlignment(m_env.m_word_size)); LINEF("m_stream->Align({0});", alignment) if (reusable) @@ -1590,7 +1591,7 @@ namespace LINE("{") m_intendation++; - LINEF("const auto arrayFill = m_stream->WriteWithFill({0} * count);", def->GetSize()) + LINEF("const auto arrayFill = m_stream->WriteWithFill({0} * count);", def->GetSize(m_env.m_word_size)) LINEF("{0} = arrayFill.Offset();", MakeTypeWrittenVarName(def)) LINEF("auto* arrayStart = {0};", MakeTypeVarName(def)) LINEF("auto* var = {0};", MakeTypeVarName(def)) @@ -1599,7 +1600,7 @@ namespace m_intendation++; LINEF("{0} = var;", MakeTypeVarName(info->m_definition)) - LINEF("FillStruct_{0}(arrayFill.AtOffset(0 + {1} * index));", info->m_definition->m_name, def->GetSize()) + LINEF("FillStruct_{0}(arrayFill.AtOffset(0 + {1} * index));", info->m_definition->m_name, def->GetSize(m_env.m_word_size)) LINE("var++;") m_intendation--; @@ -1625,7 +1626,7 @@ namespace LINEF("{0} = varWritten;", MakeTypeWrittenVarName(info->m_definition)) LINEF("Write_{0}(false);", info->m_definition->m_name) LINE("var++;") - LINEF("varWritten.Inc({0});", def->GetSize()) + LINEF("varWritten.Inc({0});", def->GetSize(m_env.m_word_size)) m_intendation--; LINE("}") diff --git a/src/ZoneCodeGeneratorLib/Parsing/Commands/CommandsFileReader.cpp b/src/ZoneCodeGeneratorLib/Parsing/Commands/CommandsFileReader.cpp index a92a8614..a00d2799 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Commands/CommandsFileReader.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Commands/CommandsFileReader.cpp @@ -89,6 +89,12 @@ bool CommandsFileReader::ReadCommandsFile(IDataRepository* repository) const auto result = parser->Parse(); const auto end = std::chrono::steady_clock::now(); + if (repository->GetGameVariants().empty()) + { + con::error("Commands must specify at least one variant"); + return false; + } + con::debug("Processing commands took {}ms", std::chrono::duration_cast(end - start).count()); if (!result) diff --git a/src/ZoneCodeGeneratorLib/Parsing/Commands/Impl/CommandsParser.cpp b/src/ZoneCodeGeneratorLib/Parsing/Commands/Impl/CommandsParser.cpp index 80f93e37..c228adf7 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Commands/Impl/CommandsParser.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Commands/Impl/CommandsParser.cpp @@ -16,7 +16,7 @@ #include "Parsing/Commands/Sequence/SequenceSetBlock.h" #include "Parsing/Commands/Sequence/SequenceString.h" #include "Parsing/Commands/Sequence/SequenceUse.h" -#include "Parsing/Commands/Sequence/SequenceWordSize.h" +#include "Parsing/Commands/Sequence/SequenceVariant.h" CommandsParser::CommandsParser(CommandsLexer* lexer, IDataRepository* targetRepository) : AbstractParser(lexer, std::make_unique(targetRepository)), @@ -43,7 +43,7 @@ const std::vector& CommandsParser::GetTestsForState new SequenceSetBlock(), new SequenceString(), new SequenceUse(), - new SequenceWordSize(), + new SequenceVariant(), }); return tests; diff --git a/src/ZoneCodeGeneratorLib/Parsing/Commands/Impl/CommandsParserState.cpp b/src/ZoneCodeGeneratorLib/Parsing/Commands/Impl/CommandsParserState.cpp index 44ae6602..c5914a38 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Commands/Impl/CommandsParserState.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Commands/Impl/CommandsParserState.cpp @@ -74,9 +74,9 @@ void CommandsParserState::AddBlock(std::unique_ptr block) const m_repository->Add(std::move(block)); } -void CommandsParserState::SetWordSize(const WordSize wordSize) const +void CommandsParserState::AddGameVariant(std::string variantName, const WordSize wordSize, const std::endian endianness) const { - m_repository->SetWordSize(wordSize); + m_repository->AddGameVariant(std::make_unique(std::move(variantName), wordSize, endianness)); } void CommandsParserState::SetGame(std::string gameName) const diff --git a/src/ZoneCodeGeneratorLib/Parsing/Commands/Impl/CommandsParserState.h b/src/ZoneCodeGeneratorLib/Parsing/Commands/Impl/CommandsParserState.h index fdef5737..108fcf6f 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Commands/Impl/CommandsParserState.h +++ b/src/ZoneCodeGeneratorLib/Parsing/Commands/Impl/CommandsParserState.h @@ -13,8 +13,8 @@ public: [[nodiscard]] const IDataRepository* GetRepository() const; void AddBlock(std::unique_ptr block) const; - void SetWordSize(WordSize wordSize) const; void SetGame(std::string gameName) const; + void AddGameVariant(std::string variantName, WordSize wordSize, std::endian endianness) const; [[nodiscard]] StructureInformation* GetInUse() const; void SetInUse(StructureInformation* structure); diff --git a/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceVariant.cpp b/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceVariant.cpp new file mode 100644 index 00000000..f2d769b9 --- /dev/null +++ b/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceVariant.cpp @@ -0,0 +1,69 @@ +#include "SequenceVariant.h" + +#include "Parsing/Commands/Matcher/CommandsCommonMatchers.h" +#include "Parsing/Commands/Matcher/CommandsMatcherFactory.h" + +namespace +{ + static constexpr auto CAPTURE_VARIANT_NAME = 1; + static constexpr auto CAPTURE_WORD_SIZE = 2; + + static constexpr auto TAG_LITTLE_ENDIAN = 1; + static constexpr auto TAG_BIG_ENDIAN = 2; +} // namespace + +SequenceVariant::SequenceVariant() +{ + const CommandsMatcherFactory create(this); + + AddMatchers({ + create.Keyword("variant"), + create.Identifier().Capture(CAPTURE_VARIANT_NAME), + create.Integer().Capture(CAPTURE_WORD_SIZE), + create.Or({ + create.Keyword("le").Tag(TAG_LITTLE_ENDIAN), + create.Keyword("be").Tag(TAG_BIG_ENDIAN), + }), + create.Char(';'), + }); +} + +void SequenceVariant::ProcessMatch(CommandsParserState* state, SequenceResult& result) const +{ + std::string variantName = result.NextCapture(CAPTURE_VARIANT_NAME).IdentifierValue(); + + const auto& wordSizeToken = result.NextCapture(CAPTURE_WORD_SIZE); + WordSize wordSize; + switch (wordSizeToken.IntegerValue()) + { + case 32: + wordSize = WordSize::BITS_32; + break; + + case 64: + wordSize = WordSize::BITS_64; + break; + + default: + throw ParsingException(wordSizeToken.GetPos(), "Unknown word size"); + } + + std::endian endianness; + switch (result.NextTag()) + { + case TAG_LITTLE_ENDIAN: + endianness = std::endian::little; + break; + + case TAG_BIG_ENDIAN: + endianness = std::endian::big; + break; + + default: + assert(false); + endianness = std::endian::little; + break; + } + + state->AddGameVariant(std::move(variantName), wordSize, endianness); +} diff --git a/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceWordSize.h b/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceVariant.h similarity index 69% rename from src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceWordSize.h rename to src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceVariant.h index 33cf8a3f..dfbcf97d 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceWordSize.h +++ b/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceVariant.h @@ -2,10 +2,10 @@ #include "Parsing/Commands/Impl/CommandsParser.h" -class SequenceWordSize final : public CommandsParser::sequence_t +class SequenceVariant final : public CommandsParser::sequence_t { public: - SequenceWordSize(); + SequenceVariant(); protected: void ProcessMatch(CommandsParserState* state, SequenceResult& result) const override; diff --git a/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceWordSize.cpp b/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceWordSize.cpp deleted file mode 100644 index d6cfac60..00000000 --- a/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceWordSize.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "SequenceWordSize.h" - -#include "Parsing/Commands/Matcher/CommandsCommonMatchers.h" -#include "Parsing/Commands/Matcher/CommandsMatcherFactory.h" - -namespace -{ - static constexpr auto CAPTURE_WORD_SIZE = 1; -} - -SequenceWordSize::SequenceWordSize() -{ - const CommandsMatcherFactory create(this); - - AddMatchers({ - create.Keyword("wordsize"), - create.Integer().Capture(CAPTURE_WORD_SIZE), - create.Char(';'), - }); -} - -void SequenceWordSize::ProcessMatch(CommandsParserState* state, SequenceResult& result) const -{ - const auto& wordSizeToken = result.NextCapture(CAPTURE_WORD_SIZE); - - switch (wordSizeToken.IntegerValue()) - { - case 32: - state->SetWordSize(WordSize::BITS_32); - break; - - case 64: - state->SetWordSize(WordSize::BITS_64); - break; - - default: - throw ParsingException(wordSizeToken.GetPos(), "Unknown word size"); - } -} diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockStruct.cpp b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockStruct.cpp index b911206c..8c03d2ca 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockStruct.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockStruct.cpp @@ -68,7 +68,8 @@ void HeaderBlockStruct::OnClose(HeaderParserState* state) if (m_has_custom_align) { - structDefinition->m_alignment = static_cast(m_custom_alignment); + for (auto& alignment : structDefinition->m_alignment) + alignment = static_cast(m_custom_alignment); structDefinition->m_flags |= DefinitionWithMembers::FLAG_ALIGNMENT_FORCED; } diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockUnion.cpp b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockUnion.cpp index c2c649a2..fa1a3e5f 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockUnion.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockUnion.cpp @@ -68,7 +68,8 @@ void HeaderBlockUnion::OnClose(HeaderParserState* state) if (m_has_custom_align) { - unionDefinition->m_alignment = static_cast(m_custom_alignment); + for (auto& alignment : unionDefinition->m_alignment) + alignment = static_cast(m_custom_alignment); unionDefinition->m_flags |= DefinitionWithMembers::FLAG_ALIGNMENT_FORCED; } diff --git a/src/ZoneCodeGeneratorLib/Parsing/PostProcessing/CalculateSizeAndAlignPostProcessor.cpp b/src/ZoneCodeGeneratorLib/Parsing/PostProcessing/CalculateSizeAndAlignPostProcessor.cpp index e2677ddc..2a68d594 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/PostProcessing/CalculateSizeAndAlignPostProcessor.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/PostProcessing/CalculateSizeAndAlignPostProcessor.cpp @@ -11,10 +11,12 @@ namespace { - bool CalculateFieldsIfNecessary(IDataRepository* repository, const DataDefinition* definition); - bool CalculateFields(IDataRepository* repository, TypeDeclaration* declaration); + constexpr auto CLEAR_FLAGS_MASK = ~(DefinitionWithMembers::FLAG_FIELDS_CALCULATING | DefinitionWithMembers::FLAG_FIELDS_CALCULATED); - bool CalculateAlign(IDataRepository* repository, TypeDeclaration* declaration) + bool CalculateFieldsIfNecessary(IDataRepository* repository, const DataDefinition* definition, WordSize wordSize); + bool CalculateFields(IDataRepository* repository, TypeDeclaration* declaration, WordSize wordSize); + + bool CalculateAlign(IDataRepository* repository, TypeDeclaration* declaration, const WordSize wordSize) { auto hasPointerModifier = false; for (const auto& declarationModifier : declaration->m_declaration_modifiers) @@ -28,13 +30,14 @@ namespace if (hasPointerModifier) { - declaration->m_alignment = GetPointerSizeForWordSize(repository->GetWordSize()); + declaration->m_alignment[std::to_underlying(wordSize)] = GetPointerSizeForWordSize(wordSize); } else { - if (!CalculateFieldsIfNecessary(repository, declaration->m_type)) + if (!CalculateFieldsIfNecessary(repository, declaration->m_type, wordSize)) return false; - declaration->m_alignment = declaration->m_type->GetAlignment(); + + declaration->m_alignment[std::to_underlying(wordSize)] = declaration->m_type->GetAlignment(wordSize); if (declaration->m_type->GetForceAlignment()) declaration->m_flags |= TypeDeclaration::FLAG_ALIGNMENT_FORCED; } @@ -42,31 +45,32 @@ namespace return true; } - bool CalculateAlign(IDataRepository* repository, DefinitionWithMembers* definition) + bool CalculateAlign(IDataRepository* repository, DefinitionWithMembers* definition, const WordSize wordSize) { if (!definition->GetForceAlignment()) { - definition->m_alignment = 0; + auto& definitionAlignment = definition->m_alignment[std::to_underlying(wordSize)]; + definitionAlignment = 0; for (const auto& member : definition->m_members) { - if (!CalculateFields(repository, member->m_type_declaration.get())) + if (!CalculateFields(repository, member->m_type_declaration.get(), wordSize)) return false; - const auto memberAlignment = member->GetAlignment(); - definition->m_alignment = std::max(memberAlignment, definition->m_alignment); + const auto memberAlignment = member->GetAlignment(wordSize); + definitionAlignment = std::max(memberAlignment, definitionAlignment); } } return true; } - bool CalculateSize(IDataRepository* repository, TypeDeclaration* declaration) + bool CalculateSize(IDataRepository* repository, TypeDeclaration* declaration, const WordSize wordSize) { if (declaration->m_declaration_modifiers.empty()) { - if (!CalculateFieldsIfNecessary(repository, declaration->m_type)) + if (!CalculateFieldsIfNecessary(repository, declaration->m_type, wordSize)) return false; - declaration->m_size = declaration->m_type->GetSize(); + declaration->m_size[std::to_underlying(wordSize)] = declaration->m_type->GetSize(wordSize); } else { @@ -75,9 +79,9 @@ namespace // 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)) + if (!CalculateFieldsIfNecessary(repository, declaration->m_type, wordSize)) return false; - currentSize = declaration->m_type->GetSize(); + currentSize = declaration->m_type->GetSize(wordSize); } for (auto i = declaration->m_declaration_modifiers.size(); i > 0; i--) @@ -87,7 +91,7 @@ namespace switch (declarationModifier->GetType()) { case DeclarationModifierType::POINTER: - currentSize = GetPointerSizeForWordSize(repository->GetWordSize()); + currentSize = GetPointerSizeForWordSize(wordSize); break; case DeclarationModifierType::ARRAY: @@ -96,25 +100,26 @@ namespace } } - declaration->m_size = currentSize; + declaration->m_size[std::to_underlying(wordSize)] = currentSize; } return true; } - bool CalculateSize(IDataRepository* repository, StructDefinition* definition) + bool CalculateSize(IDataRepository* repository, StructDefinition* definition, const WordSize wordSize) { - definition->m_size = 0; + auto& definitionSize = definition->m_size[std::to_underlying(wordSize)]; + definitionSize = 0; auto currentBitOffset = 0u; for (const auto& member : definition->m_members) { - if (!CalculateFields(repository, member->m_type_declaration.get())) + if (!CalculateFields(repository, member->m_type_declaration.get(), wordSize)) return false; if (member->m_type_declaration->m_has_custom_bit_size) { - member->m_offset = definition->m_size + currentBitOffset / 8; + member->m_offset = definitionSize + currentBitOffset / 8; currentBitOffset += member->m_type_declaration->m_custom_bit_size; } else @@ -122,64 +127,66 @@ namespace if (currentBitOffset > 0) { currentBitOffset = utils::Align(currentBitOffset, 8u); - definition->m_size += currentBitOffset / 8; + definitionSize += currentBitOffset / 8; currentBitOffset = 0; } - definition->m_size = utils::Align(definition->m_size, - member->GetForceAlignment() ? member->GetAlignment() : std::min(member->GetAlignment(), definition->m_pack)); + definitionSize = + utils::Align(definitionSize, + member->GetForceAlignment() ? member->GetAlignment(wordSize) : std::min(member->GetAlignment(wordSize), definition->m_pack)); - member->m_offset = definition->m_size; + member->m_offset = definitionSize; - definition->m_size += member->m_type_declaration->GetSize(); + definitionSize += member->m_type_declaration->GetSize(wordSize); } } if (currentBitOffset > 0) { currentBitOffset = utils::Align(currentBitOffset, 8u); - definition->m_size += currentBitOffset / 8; + definitionSize += currentBitOffset / 8; } - definition->m_size = utils::Align(definition->m_size, definition->m_alignment); + definitionSize = utils::Align(definitionSize, definition->m_alignment[std::to_underlying(wordSize)]); return true; } - bool CalculateSize(IDataRepository* repository, UnionDefinition* definition) + bool CalculateSize(IDataRepository* repository, UnionDefinition* definition, const WordSize wordSize) { - definition->m_size = 0; + auto& definitionSize = definition->m_size[std::to_underlying(wordSize)]; + definitionSize = 0; for (const auto& member : definition->m_members) { - if (!CalculateFields(repository, member->m_type_declaration.get())) + if (!CalculateFields(repository, member->m_type_declaration.get(), wordSize)) return false; member->m_offset = 0; - const auto memberSize = member->m_type_declaration->GetSize(); - if (memberSize > definition->m_size) - definition->m_size = memberSize; + const auto memberSize = member->m_type_declaration->GetSize(wordSize); + if (memberSize > definitionSize) + definitionSize = memberSize; } - definition->m_size = utils::Align(definition->m_size, definition->m_alignment); + definitionSize = utils::Align(definitionSize, definition->m_alignment[std::to_underlying(wordSize)]); return true; } - bool CalculateFields(IDataRepository* repository, TypeDeclaration* declaration) + bool CalculateFields(IDataRepository* repository, TypeDeclaration* declaration, const WordSize wordSize) { if (declaration->m_flags & TypeDeclaration::FLAG_FIELDS_CALCULATED) return true; - if (!CalculateAlign(repository, declaration) || !CalculateSize(repository, declaration)) + if (!CalculateAlign(repository, declaration, wordSize) || !CalculateSize(repository, declaration, wordSize)) return false; declaration->m_flags |= TypeDeclaration::FLAG_FIELDS_CALCULATED; return true; } - bool CalculateFields(IDataRepository* repository, StructDefinition* structDefinition) + bool CalculateFields(IDataRepository* repository, StructDefinition* structDefinition, const WordSize wordSize) { if (structDefinition->m_flags & DefinitionWithMembers::FLAG_FIELDS_CALCULATED) return true; @@ -191,7 +198,7 @@ namespace structDefinition->m_flags |= DefinitionWithMembers::FLAG_FIELDS_CALCULATING; - if (!CalculateAlign(repository, structDefinition) || !CalculateSize(repository, structDefinition)) + if (!CalculateAlign(repository, structDefinition, wordSize) || !CalculateSize(repository, structDefinition, wordSize)) { return false; } @@ -202,7 +209,7 @@ namespace return true; } - bool CalculateFields(IDataRepository* repository, UnionDefinition* unionDefinition) + bool CalculateFields(IDataRepository* repository, UnionDefinition* unionDefinition, const WordSize wordSize) { if (unionDefinition->m_flags & DefinitionWithMembers::FLAG_FIELDS_CALCULATED) return true; @@ -214,7 +221,7 @@ namespace unionDefinition->m_flags |= DefinitionWithMembers::FLAG_FIELDS_CALCULATING; - if (!CalculateAlign(repository, unionDefinition) || !CalculateSize(repository, unionDefinition)) + if (!CalculateAlign(repository, unionDefinition, wordSize) || !CalculateSize(repository, unionDefinition, wordSize)) { return false; } @@ -225,56 +232,75 @@ namespace return true; } - bool CalculateFieldsIfNecessary(IDataRepository* repository, const DataDefinition* definition) + bool CalculateFieldsIfNecessary(IDataRepository* repository, const DataDefinition* definition, const WordSize wordSize) { 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(const_cast(definition))); + return CalculateFields(repository, dynamic_cast(const_cast(definition)), wordSize); } 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(const_cast(definition))); + return CalculateFields(repository, dynamic_cast(const_cast(definition)), wordSize); } 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(const_cast(definition))->m_type_declaration.get()); + return CalculateFields(repository, dynamic_cast(const_cast(definition))->m_type_declaration.get(), wordSize); } return true; } + + void ClearDefinitionFlags(DefinitionWithMembers& definition) + { + definition.m_flags &= CLEAR_FLAGS_MASK; + + for (const auto& member : definition.m_members) + member->m_type_declaration->m_flags &= CLEAR_FLAGS_MASK; + } + + void ClearDefinitionFlags(IDataRepository& repository) + { + for (auto* structDefinition : repository.GetAllStructs()) + ClearDefinitionFlags(*structDefinition); + + for (auto* unionDefinition : repository.GetAllUnions()) + ClearDefinitionFlags(*unionDefinition); + + for (auto* typedefDeclaration : repository.GetAllTypedefs()) + typedefDeclaration->m_type_declaration->m_flags &= CLEAR_FLAGS_MASK; + } } // namespace bool CalculateSizeAndAlignPostProcessor::PostProcess(IDataRepository* repository) { - if (repository->GetWordSize() == WordSize::UNKNOWN) + for (auto wordSizeNum = 0; wordSizeNum < WORD_SIZE_COUNT; wordSizeNum++) { - con::error("You must set a word size!"); - return false; - } + const auto wordSize = static_cast(wordSizeNum); + for (auto* structDefinition : repository->GetAllStructs()) + { + if (!CalculateFields(repository, structDefinition, wordSize)) + return false; + } - for (auto* structDefinition : repository->GetAllStructs()) - { - if (!CalculateFields(repository, structDefinition)) + for (auto* unionDefinition : repository->GetAllUnions()) + { + if (!CalculateFields(repository, unionDefinition, wordSize)) + return false; + } - return false; - } + for (auto* typedefDeclaration : repository->GetAllTypedefs()) + { + if (!CalculateFields(repository, typedefDeclaration->m_type_declaration.get(), wordSize)) + return false; + } - for (auto* unionDefinition : repository->GetAllUnions()) - { - if (!CalculateFields(repository, unionDefinition)) - - return false; - } - - for (auto* typedefDeclaration : repository->GetAllTypedefs()) - { - if (!CalculateFields(repository, typedefDeclaration->m_type_declaration.get())) - return false; + if (wordSizeNum + 1 < WORD_SIZE_COUNT) + ClearDefinitionFlags(*repository); } return true; diff --git a/src/ZoneCodeGeneratorLib/Parsing/PostProcessing/CrossPlatformStructurePostProcessor.cpp b/src/ZoneCodeGeneratorLib/Parsing/PostProcessing/CrossPlatformStructurePostProcessor.cpp index 299ec3b3..e44b45b0 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/PostProcessing/CrossPlatformStructurePostProcessor.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/PostProcessing/CrossPlatformStructurePostProcessor.cpp @@ -40,18 +40,10 @@ bool CrossPlatformStructurePostProcessor::PostProcess(IDataRepository* repositor { const auto& allInfos = repository->GetAllStructureInformation(); - if (repository->GetWordSize() == OWN_WORD_SIZE) + std::unordered_set visitedStructures; + for (const auto& info : allInfos) { - for (const auto& info : allInfos) - info->m_has_matching_cross_platform_structure = true; - } - else - { - std::unordered_set visitedStructures; - for (const auto& info : allInfos) - { - CalculateHasMatchingCrossPlatformStructure(visitedStructures, info); - } + CalculateHasMatchingCrossPlatformStructure(visitedStructures, info); } return true; diff --git a/src/ZoneCodeGeneratorLib/Persistence/IDataRepository.h b/src/ZoneCodeGeneratorLib/Persistence/IDataRepository.h index 0e82dd8b..3a719b79 100644 --- a/src/ZoneCodeGeneratorLib/Persistence/IDataRepository.h +++ b/src/ZoneCodeGeneratorLib/Persistence/IDataRepository.h @@ -4,9 +4,10 @@ #include "Domain/Definition/StructDefinition.h" #include "Domain/Definition/TypedefDefinition.h" #include "Domain/Definition/UnionDefinition.h" -#include "Domain/Environment/WordSize.h" -#include "Domain/FastFile/FastFileBlock.h" +#include "Domain/FastFileBlock.h" +#include "Domain/GameVariant.h" #include "Domain/Information/StructureInformation.h" +#include "Domain/WordSize.h" #include @@ -30,8 +31,8 @@ public: [[nodiscard]] virtual const std::string& GetGameName() const = 0; virtual void SetGame(std::string gameName) = 0; - [[nodiscard]] virtual WordSize GetWordSize() const = 0; - virtual void SetWordSize(WordSize wordSize) = 0; + [[nodiscard]] virtual const std::vector& GetGameVariants() const = 0; + virtual void AddGameVariant(std::unique_ptr gameVariant) = 0; [[nodiscard]] virtual const std::vector& GetAllEnums() const = 0; [[nodiscard]] virtual const std::vector& GetAllStructs() const = 0; diff --git a/src/ZoneCodeGeneratorLib/Persistence/InMemory/InMemoryRepository.cpp b/src/ZoneCodeGeneratorLib/Persistence/InMemory/InMemoryRepository.cpp index 44bcf1e4..f703d7a8 100644 --- a/src/ZoneCodeGeneratorLib/Persistence/InMemory/InMemoryRepository.cpp +++ b/src/ZoneCodeGeneratorLib/Persistence/InMemory/InMemoryRepository.cpp @@ -1,9 +1,6 @@ #include "InMemoryRepository.h" -InMemoryRepository::InMemoryRepository() - : m_word_size(WordSize::UNKNOWN) -{ -} +InMemoryRepository::InMemoryRepository() = default; InMemoryRepository::~InMemoryRepository() { @@ -19,6 +16,8 @@ InMemoryRepository::~InMemoryRepository() delete structureInformation; for (const auto* fastFileBlock : m_fast_file_blocks) delete fastFileBlock; + for (const auto* gameVariant : m_game_variants) + delete gameVariant; } void InMemoryRepository::Add(std::unique_ptr enumsDefinition) @@ -83,14 +82,14 @@ void InMemoryRepository::SetGame(std::string gameName) m_game_name = std::move(gameName); } -WordSize InMemoryRepository::GetWordSize() const +[[nodiscard]] const std::vector& InMemoryRepository::GetGameVariants() const { - return m_word_size; + return m_game_variants; } -void InMemoryRepository::SetWordSize(const WordSize wordSize) +void InMemoryRepository::AddGameVariant(std::unique_ptr gameVariant) { - m_word_size = wordSize; + m_game_variants.emplace_back(gameVariant.release()); } const std::vector& InMemoryRepository::GetAllEnums() const diff --git a/src/ZoneCodeGeneratorLib/Persistence/InMemory/InMemoryRepository.h b/src/ZoneCodeGeneratorLib/Persistence/InMemory/InMemoryRepository.h index 7b7d7b7b..e0f54abb 100644 --- a/src/ZoneCodeGeneratorLib/Persistence/InMemory/InMemoryRepository.h +++ b/src/ZoneCodeGeneratorLib/Persistence/InMemory/InMemoryRepository.h @@ -24,8 +24,8 @@ public: [[nodiscard]] const std::string& GetGameName() const override; void SetGame(std::string gameName) override; - [[nodiscard]] WordSize GetWordSize() const override; - void SetWordSize(WordSize wordSize) override; + [[nodiscard]] const std::vector& GetGameVariants() const override; + void AddGameVariant(std::unique_ptr gameVariant) override; [[nodiscard]] const std::vector& GetAllEnums() const override; [[nodiscard]] const std::vector& GetAllStructs() const override; @@ -54,5 +54,5 @@ private: std::unordered_map m_structure_information_by_definition; std::unordered_map m_type_information_by_definition; std::string m_game_name; - WordSize m_word_size; + std::vector m_game_variants; }; diff --git a/src/ZoneCodeGeneratorLib/Printing/PrettyPrinter.cpp b/src/ZoneCodeGeneratorLib/Printing/PrettyPrinter.cpp index 0254a588..8de32b02 100644 --- a/src/ZoneCodeGeneratorLib/Printing/PrettyPrinter.cpp +++ b/src/ZoneCodeGeneratorLib/Printing/PrettyPrinter.cpp @@ -183,6 +183,17 @@ void PrettyPrinter::PrintTypedefArrayOfPointers(TypedefDefinition* typedefDefini m_stream << "\n"; } +void PrettyPrinter::PrintSizeAndAlignment(DataDefinition& dataDefinition) const +{ + for (auto wordSizeNum = 0u; wordSizeNum < WORD_SIZE_COUNT; wordSizeNum++) + { + const auto wordSize = static_cast(wordSizeNum); + const auto bitWordSizeValue = GetPointerSizeForWordSize(wordSize) * 8; + m_stream << std::format(" Alignment ({}bit): {}\n", bitWordSizeValue, dataDefinition.GetAlignment(wordSize)); + m_stream << std::format(" Size ({}bit): {}\n", bitWordSizeValue, dataDefinition.GetSize(wordSize)); + } +} + void PrettyPrinter::PrintEnums() const { const auto& allEnums = m_repository->GetAllEnums(); @@ -191,8 +202,7 @@ void PrettyPrinter::PrintEnums() const for (auto* enumDefinition : allEnums) { m_stream << std::format(" Name: {}\n", enumDefinition->GetFullName()); - m_stream << std::format(" Alignment: {}\n", enumDefinition->GetAlignment()); - m_stream << std::format(" Size: {}\n", enumDefinition->GetSize()); + PrintSizeAndAlignment(*enumDefinition); for (const auto& enumMember : enumDefinition->m_members) { @@ -211,8 +221,7 @@ void PrettyPrinter::PrintStructs() const for (auto* structDefinition : allStructs) { m_stream << std::format(" Name: {}\n", structDefinition->GetFullName()); - m_stream << std::format(" Alignment: {}\n", structDefinition->GetAlignment()); - m_stream << std::format(" Size: {}\n", structDefinition->GetSize()); + PrintSizeAndAlignment(*structDefinition); for (const auto& variable : structDefinition->m_members) { @@ -231,8 +240,7 @@ void PrettyPrinter::PrintUnions() const for (auto* unionDefinition : allUnions) { m_stream << std::format(" Name: {}\n", unionDefinition->GetFullName()); - m_stream << std::format(" Alignment: {}\n", unionDefinition->GetAlignment()); - m_stream << std::format(" Size: {}\n", unionDefinition->GetSize()); + PrintSizeAndAlignment(*unionDefinition); for (const auto& variable : unionDefinition->m_members) { @@ -251,8 +259,7 @@ void PrettyPrinter::PrintTypedefs() const for (auto* typedefDefinition : allTypedefs) { m_stream << std::format(" Name: {}\n", typedefDefinition->GetFullName()); - m_stream << std::format(" Alignment: {}\n", typedefDefinition->GetAlignment()); - m_stream << std::format(" Size: {}\n", typedefDefinition->GetSize()); + PrintSizeAndAlignment(*typedefDefinition); const auto& declarationModifiers = typedefDefinition->m_type_declaration->m_declaration_modifiers; if (declarationModifiers.empty()) diff --git a/src/ZoneCodeGeneratorLib/Printing/PrettyPrinter.h b/src/ZoneCodeGeneratorLib/Printing/PrettyPrinter.h index 059db896..ece2fd00 100644 --- a/src/ZoneCodeGeneratorLib/Printing/PrettyPrinter.h +++ b/src/ZoneCodeGeneratorLib/Printing/PrettyPrinter.h @@ -18,6 +18,7 @@ private: void PrintVariable(Variable* variable) const; void PrintTypedefPointerToArray(TypedefDefinition* typedefDefinition) const; void PrintTypedefArrayOfPointers(TypedefDefinition* typedefDefinition) const; + void PrintSizeAndAlignment(DataDefinition& dataDefinition) const; void PrintEnums() const; void PrintStructs() const;