From fb55cdb468c59889f6db8eb9f54cfdc8abf95408 Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 18 Feb 2021 21:55:13 +0100 Subject: [PATCH] parse struct and union sequences --- .../Domain/Definition/DeclarationModifier.h | 4 ++ .../Domain/Definition/DefinitionWithMembers.h | 2 +- .../Domain/Definition/TypeDeclaration.cpp | 6 +- .../Domain/Definition/Variable.cpp | 8 +++ .../Domain/Definition/Variable.h | 2 + .../Header/Block/HeaderBlockStruct.cpp | 70 +++++++++++++++++++ .../Parsing/Header/Block/HeaderBlockStruct.h | 28 +++++++- .../Parsing/Header/Block/HeaderBlockUnion.cpp | 70 +++++++++++++++++++ .../Parsing/Header/Block/HeaderBlockUnion.h | 22 +++++- .../Parsing/Header/HeaderFileReader.cpp | 2 +- .../Parsing/Header/HeaderFileReader.h | 2 +- .../Parsing/Header/Impl/HeaderParser.cpp | 4 +- .../Parsing/Header/Impl/HeaderParser.h | 3 +- .../Parsing/Header/Impl/HeaderParserState.cpp | 4 +- .../Parsing/Header/Impl/HeaderParserState.h | 4 +- .../Header/Sequence/SequenceStruct.cpp | 33 ++++++++- .../Parsing/Header/Sequence/SequenceUnion.cpp | 33 ++++++++- .../Parsing/IPackValueSupplier.h | 2 +- .../Impl/PackDefinitionStreamProxy.cpp | 2 +- .../Parsing/Impl/PackDefinitionStreamProxy.h | 2 +- src/ZoneCodeGeneratorLib/Utils/NameUtils.cpp | 17 +++++ src/ZoneCodeGeneratorLib/Utils/NameUtils.h | 9 +++ .../Utils/NamespaceBuilder.cpp | 5 ++ .../Utils/NamespaceBuilder.h | 1 + 24 files changed, 316 insertions(+), 19 deletions(-) create mode 100644 src/ZoneCodeGeneratorLib/Utils/NameUtils.cpp create mode 100644 src/ZoneCodeGeneratorLib/Utils/NameUtils.h diff --git a/src/ZoneCodeGeneratorLib/Domain/Definition/DeclarationModifier.h b/src/ZoneCodeGeneratorLib/Domain/Definition/DeclarationModifier.h index 4c3b27fd..f34dda33 100644 --- a/src/ZoneCodeGeneratorLib/Domain/Definition/DeclarationModifier.h +++ b/src/ZoneCodeGeneratorLib/Domain/Definition/DeclarationModifier.h @@ -13,6 +13,10 @@ class DeclarationModifier public: DeclarationModifier() = default; virtual ~DeclarationModifier() = default; + DeclarationModifier(const DeclarationModifier& other) = default; + DeclarationModifier(DeclarationModifier&& other) noexcept = default; + DeclarationModifier& operator=(const DeclarationModifier& other) = default; + DeclarationModifier& operator=(DeclarationModifier&& other) noexcept = default; _NODISCARD virtual DeclarationModifierType GetType() const = 0; }; \ No newline at end of file diff --git a/src/ZoneCodeGeneratorLib/Domain/Definition/DefinitionWithMembers.h b/src/ZoneCodeGeneratorLib/Domain/Definition/DefinitionWithMembers.h index e5cc8934..0791f5e3 100644 --- a/src/ZoneCodeGeneratorLib/Domain/Definition/DefinitionWithMembers.h +++ b/src/ZoneCodeGeneratorLib/Domain/Definition/DefinitionWithMembers.h @@ -26,7 +26,7 @@ public: const unsigned m_pack; unsigned m_alignment_override; - std::vector> m_members; + std::vector> m_members; DefinitionWithMembers(std::string _namespace, std::string name, unsigned pack); diff --git a/src/ZoneCodeGeneratorLib/Domain/Definition/TypeDeclaration.cpp b/src/ZoneCodeGeneratorLib/Domain/Definition/TypeDeclaration.cpp index cb11e1ef..79103216 100644 --- a/src/ZoneCodeGeneratorLib/Domain/Definition/TypeDeclaration.cpp +++ b/src/ZoneCodeGeneratorLib/Domain/Definition/TypeDeclaration.cpp @@ -20,11 +20,11 @@ void TypeDeclaration::CalculateSize() { auto currentSize = m_type->GetSize(); - for(auto i = m_declaration_modifiers.size(); i > 0; i--) + for (auto i = m_declaration_modifiers.size(); i > 0; i--) { const auto& declarationModifier = m_declaration_modifiers[i - 1]; - - switch(declarationModifier->GetType()) + + switch (declarationModifier->GetType()) { case DeclarationModifierType::POINTER: currentSize = POINTER_SIZE; diff --git a/src/ZoneCodeGeneratorLib/Domain/Definition/Variable.cpp b/src/ZoneCodeGeneratorLib/Domain/Definition/Variable.cpp index ee5ec7e5..b8e78244 100644 --- a/src/ZoneCodeGeneratorLib/Domain/Definition/Variable.cpp +++ b/src/ZoneCodeGeneratorLib/Domain/Definition/Variable.cpp @@ -1,5 +1,13 @@ #include "Variable.h" +Variable::Variable(std::string name, std::unique_ptr typeDeclaration) + : m_name(std::move(name)), + m_has_alignment_override(false), + m_alignment_override(0), + m_type_declaration(std::move(typeDeclaration)) +{ +} + unsigned Variable::GetAlignment() { if (m_has_alignment_override) diff --git a/src/ZoneCodeGeneratorLib/Domain/Definition/Variable.h b/src/ZoneCodeGeneratorLib/Domain/Definition/Variable.h index b13c405b..4e8016c5 100644 --- a/src/ZoneCodeGeneratorLib/Domain/Definition/Variable.h +++ b/src/ZoneCodeGeneratorLib/Domain/Definition/Variable.h @@ -13,6 +13,8 @@ public: unsigned m_alignment_override; std::unique_ptr m_type_declaration; + Variable(std::string name, std::unique_ptr typeDeclaration); + unsigned GetAlignment(); bool GetForceAlignment(); }; diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockStruct.cpp b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockStruct.cpp index e5668cbe..9be57232 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockStruct.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockStruct.cpp @@ -5,6 +5,16 @@ #include "Parsing/Header/Sequence/SequenceStruct.h" #include "Parsing/Header/Sequence/SequenceUnion.h" #include "Parsing/Header/Sequence/SequenceVariable.h" +#include "Utils/NameUtils.h" + +HeaderBlockStruct::HeaderBlockStruct(std::string name, const bool isTypedef) + : m_type_name(std::move(name)), + m_struct_definition(nullptr), + m_custom_alignment(0), + m_is_typedef(isTypedef), + m_has_custom_align(false) +{ +} HeaderBlockType HeaderBlockStruct::GetType() { @@ -26,17 +36,77 @@ const std::vector& HeaderBlockStruct::GetTestsForBloc void HeaderBlockStruct::OnOpen(HeaderParserState* state) { + m_namespace = state->m_namespace.ToString(); + + if (!m_type_name.empty()) + state->m_namespace.Push(m_type_name); } void HeaderBlockStruct::OnClose(HeaderParserState* state) { + if (!m_type_name.empty()) + state->m_namespace.Pop(); + + auto isAnonymous = false; + auto typeName = m_type_name; + if(typeName.empty()) + { + isAnonymous = true; + typeName = NameUtils::GenerateRandomName(); + } + + auto structDefinition = std::make_unique(m_namespace, std::move(typeName), state->m_pack_value_supplier->GetCurrentPack()); + m_struct_definition = structDefinition.get(); + + if (isAnonymous) + structDefinition->m_anonymous = true; + + for (auto& member : m_members) + structDefinition->m_members.emplace_back(std::move(member)); + + state->AddDataType(std::move(structDefinition)); + + if (m_is_typedef) + state->AddDataType(std::make_unique(m_namespace, m_variable_name, std::make_unique(m_struct_definition))); } void HeaderBlockStruct::OnChildBlockClose(HeaderParserState* state, IHeaderBlock* block) { } +void HeaderBlockStruct::AddVariable(std::shared_ptr variable) +{ + m_members.emplace_back(std::move(variable)); +} + +void HeaderBlockStruct::SetCustomAlignment(const int alignment) +{ + m_has_custom_align = true; + m_custom_alignment = alignment; +} + +void HeaderBlockStruct::Inherit(const StructDefinition* parentStruct) +{ + for(const auto& parentMember : parentStruct->m_members) + AddVariable(parentMember); +} + void HeaderBlockStruct::SetBlockName(const TokenPos& nameTokenPos, std::string name) { m_variable_name = std::move(name); } + +bool HeaderBlockStruct::IsDefiningVariable() +{ + return !m_is_typedef && !m_variable_name.empty(); +} + +DataDefinition* HeaderBlockStruct::GetVariableType() +{ + return m_struct_definition; +} + +std::string HeaderBlockStruct::GetVariableName() +{ + return m_variable_name; +} diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockStruct.h b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockStruct.h index d9487759..fabbfa25 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockStruct.h +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockStruct.h @@ -1,18 +1,42 @@ #pragma once +#include + #include "IHeaderBlock.h" #include "IHeaderBlockNameHolder.h" +#include "IHeaderBlockVariableDefining.h" +#include "Domain/Definition/StructDefinition.h" +#include "Domain/Definition/Variable.h" -class HeaderBlockStruct final : public IHeaderBlock, public IHeaderBlockNameHolder +class HeaderBlockStruct final : public IHeaderBlock, public IHeaderBlockNameHolder, public IHeaderBlockVariableDefining { + std::string m_namespace; + std::string m_type_name; + std::vector> m_members; + StructDefinition* m_struct_definition; + + int m_custom_alignment; + + bool m_is_typedef; + bool m_has_custom_align; + std::string m_variable_name; public: + HeaderBlockStruct(std::string name, bool isTypedef); + HeaderBlockType GetType() override; const std::vector& GetTestsForBlock() override; void OnOpen(HeaderParserState* state) override; void OnClose(HeaderParserState* state) override; void OnChildBlockClose(HeaderParserState* state, IHeaderBlock* block) override; - + + void AddVariable(std::shared_ptr variable); + void SetCustomAlignment(int alignment); + void Inherit(const StructDefinition* parentStruct); + void SetBlockName(const TokenPos& nameTokenPos, std::string name) override; + bool IsDefiningVariable() override; + DataDefinition* GetVariableType() override; + std::string GetVariableName() override; }; diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockUnion.cpp b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockUnion.cpp index 99fedd04..df7f4179 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockUnion.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockUnion.cpp @@ -5,6 +5,16 @@ #include "Parsing/Header/Sequence/SequenceStruct.h" #include "Parsing/Header/Sequence/SequenceUnion.h" #include "Parsing/Header/Sequence/SequenceVariable.h" +#include "Utils/NameUtils.h" + +HeaderBlockUnion::HeaderBlockUnion(std::string name, const bool isTypedef) + : m_type_name(std::move(name)), + m_union_definition(nullptr), + m_custom_alignment(0), + m_is_typedef(isTypedef), + m_has_custom_align(false) +{ +} HeaderBlockType HeaderBlockUnion::GetType() { @@ -26,17 +36,77 @@ const std::vector& HeaderBlockUnion::GetTestsForBlock void HeaderBlockUnion::OnOpen(HeaderParserState* state) { + m_namespace = state->m_namespace.ToString(); + + if (!m_type_name.empty()) + state->m_namespace.Push(m_type_name); } void HeaderBlockUnion::OnClose(HeaderParserState* state) { + if (!m_type_name.empty()) + state->m_namespace.Pop(); + + auto isAnonymous = false; + auto typeName = m_type_name; + if (typeName.empty()) + { + isAnonymous = true; + typeName = NameUtils::GenerateRandomName(); + } + + auto unionDefinition = std::make_unique(m_namespace, std::move(typeName), state->m_pack_value_supplier->GetCurrentPack()); + m_union_definition = unionDefinition.get(); + + if (isAnonymous) + unionDefinition->m_anonymous = true; + + for (auto& member : m_members) + unionDefinition->m_members.emplace_back(std::move(member)); + + state->AddDataType(std::move(unionDefinition)); + + if (m_is_typedef) + state->AddDataType(std::make_unique(m_namespace, m_variable_name, std::make_unique(m_union_definition))); } void HeaderBlockUnion::OnChildBlockClose(HeaderParserState* state, IHeaderBlock* block) { } +void HeaderBlockUnion::AddVariable(std::shared_ptr variable) +{ + m_members.emplace_back(std::move(variable)); +} + +void HeaderBlockUnion::SetCustomAlignment(const int alignment) +{ + m_has_custom_align = true; + m_custom_alignment = alignment; +} + +void HeaderBlockUnion::Inherit(const StructDefinition* parentStruct) +{ + for (const auto& parentMember : parentStruct->m_members) + AddVariable(parentMember); +} + void HeaderBlockUnion::SetBlockName(const TokenPos& nameTokenPos, std::string name) { m_variable_name = std::move(name); } + +bool HeaderBlockUnion::IsDefiningVariable() +{ + return !m_is_typedef && !m_variable_name.empty(); +} + +DataDefinition* HeaderBlockUnion::GetVariableType() +{ + return m_union_definition; +} + +std::string HeaderBlockUnion::GetVariableName() +{ + return m_variable_name; +} diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockUnion.h b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockUnion.h index ab6dc86f..6db46585 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockUnion.h +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockUnion.h @@ -2,17 +2,37 @@ #include "IHeaderBlock.h" #include "IHeaderBlockNameHolder.h" +#include "IHeaderBlockVariableDefining.h" -class HeaderBlockUnion final : public IHeaderBlock, public IHeaderBlockNameHolder +class HeaderBlockUnion final : public IHeaderBlock, public IHeaderBlockNameHolder, public IHeaderBlockVariableDefining { + std::string m_namespace; + std::string m_type_name; + std::vector> m_members; + UnionDefinition* m_union_definition; + + int m_custom_alignment; + + bool m_is_typedef; + bool m_has_custom_align; + std::string m_variable_name; public: + HeaderBlockUnion(std::string name, bool isTypedef); + HeaderBlockType GetType() override; const std::vector& GetTestsForBlock() override; void OnOpen(HeaderParserState* state) override; void OnClose(HeaderParserState* state) override; void OnChildBlockClose(HeaderParserState* state, IHeaderBlock* block) override; + + void AddVariable(std::shared_ptr variable); + void SetCustomAlignment(int alignment); + void Inherit(const StructDefinition* parentStruct); void SetBlockName(const TokenPos& nameTokenPos, std::string name) override; + bool IsDefiningVariable() override; + DataDefinition* GetVariableType() override; + std::string GetVariableName() override; }; diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/HeaderFileReader.cpp b/src/ZoneCodeGeneratorLib/Parsing/Header/HeaderFileReader.cpp index 988898a8..a4ca4e21 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/HeaderFileReader.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/HeaderFileReader.cpp @@ -61,7 +61,7 @@ bool HeaderFileReader::ReadHeaderFile(IDataRepository* repository) SetupStreamProxies(); const auto lexer = std::make_unique(m_stream); - const auto parser = std::make_unique(lexer.get()); + const auto parser = std::make_unique(lexer.get(), m_pack_value_supplier); const auto start = std::chrono::steady_clock::now(); const auto result = parser->Parse(); diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/HeaderFileReader.h b/src/ZoneCodeGeneratorLib/Parsing/Header/HeaderFileReader.h index bd9e848d..2dded170 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/HeaderFileReader.h +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/HeaderFileReader.h @@ -16,7 +16,7 @@ class HeaderFileReader std::string m_filename; std::vector> m_open_streams; - IPackValueSupplier* m_pack_value_supplier; + const IPackValueSupplier* m_pack_value_supplier; IParserLineStream* m_stream; bool OpenBaseStream(); diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParser.cpp b/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParser.cpp index 31d3c3ac..eab8926a 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParser.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParser.cpp @@ -2,8 +2,8 @@ #include "Parsing/Header/Sequence/SequenceNamespace.h" -HeaderParser::HeaderParser(HeaderLexer* lexer) - : AbstractParser(lexer, std::make_unique()) +HeaderParser::HeaderParser(HeaderLexer* lexer, const IPackValueSupplier* packValueSupplier) + : AbstractParser(lexer, std::make_unique(packValueSupplier)) { auto sequenceNamespace = std::make_unique(); } diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParser.h b/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParser.h index 1e17019d..12aa5ad5 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParser.h +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParser.h @@ -2,6 +2,7 @@ #include "HeaderLexer.h" #include "HeaderParserState.h" +#include "Parsing/IPackValueSupplier.h" #include "Parsing/Impl/AbstractParser.h" #include "Persistence/IDataRepository.h" @@ -11,7 +12,7 @@ protected: const std::vector& GetTestsForState() override; public: - explicit HeaderParser(HeaderLexer* lexer); + HeaderParser(HeaderLexer* lexer, const IPackValueSupplier* packValueSupplier); void SaveToRepository(IDataRepository* repository) const; }; diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParserState.cpp b/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParserState.cpp index c5004984..cca891ea 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParserState.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParserState.cpp @@ -3,7 +3,9 @@ #include "Domain/Definition/EnumDefinition.h" #include "Parsing/Header/Block/HeaderBlockNone.h" -HeaderParserState::HeaderParserState() +HeaderParserState::HeaderParserState(const IPackValueSupplier* packValueSupplier) + : m_pack_value_supplier(packValueSupplier) + { m_blocks.push(std::make_unique()); diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParserState.h b/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParserState.h index 8ac59773..d71079e6 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParserState.h +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParserState.h @@ -9,6 +9,7 @@ #include "Domain/Definition/DataDefinition.h" #include "Domain/Definition/EnumMember.h" #include "Domain/Definition/ForwardDeclaration.h" +#include "Parsing/IPackValueSupplier.h" #include "Utils/NamespaceBuilder.h" #include "Parsing/Header/Block/IHeaderBlock.h" #include "Persistence/IDataRepository.h" @@ -27,9 +28,10 @@ class HeaderParserState void AddBaseDataType(const BaseTypeDefinition* baseType); public: + const IPackValueSupplier* const m_pack_value_supplier; NamespaceBuilder m_namespace; - HeaderParserState(); + explicit HeaderParserState(const IPackValueSupplier* packValueSupplier); _NODISCARD IHeaderBlock* GetBlock() const; void PushBlock(std::unique_ptr block); diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Sequence/SequenceStruct.cpp b/src/ZoneCodeGeneratorLib/Parsing/Header/Sequence/SequenceStruct.cpp index fc7e0b2e..1a89ee04 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Sequence/SequenceStruct.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Sequence/SequenceStruct.cpp @@ -26,5 +26,36 @@ SequenceStruct::SequenceStruct() void SequenceStruct::ProcessMatch(HeaderParserState* state, SequenceResult& result) const { - state->PushBlock(std::make_unique()); + auto isTypedef = result.PeekAndRemoveIfTag(TAG_TYPEDEF) == TAG_TYPEDEF; + std::string name; + + if (result.HasNextCapture(CAPTURE_NAME)) + name = result.NextCapture(CAPTURE_NAME).IdentifierValue(); + + auto structBlock = std::make_unique(std::move(name), isTypedef); + + if (result.HasNextCapture(CAPTURE_ALIGN)) + structBlock->SetCustomAlignment(result.NextCapture(CAPTURE_ALIGN).IntegerValue()); + + if(result.HasNextCapture(CAPTURE_PARENT_TYPE)) + { + const auto& parentTypeToken = result.NextCapture(CAPTURE_PARENT_TYPE); + const auto* parentDefinition = state->FindType(parentTypeToken.TypeNameValue()); + + if(parentDefinition == nullptr && !state->m_namespace.IsEmpty()) + { + const auto fullTypeName = NamespaceBuilder::Combine(state->m_namespace.ToString(), parentTypeToken.TypeNameValue()); + parentDefinition = state->FindType(fullTypeName); + } + + if (parentDefinition == nullptr) + throw ParsingException(parentTypeToken.GetPos(), "Cannot find specified parent type"); + + if(parentDefinition->GetType() != DataDefinitionType::STRUCT) + throw ParsingException(parentTypeToken.GetPos(), "Parent type must be a struct"); + + structBlock->Inherit(dynamic_cast(parentDefinition)); + } + + state->PushBlock(std::move(structBlock)); } diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Sequence/SequenceUnion.cpp b/src/ZoneCodeGeneratorLib/Parsing/Header/Sequence/SequenceUnion.cpp index 081de0f7..a2fe83da 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Sequence/SequenceUnion.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Sequence/SequenceUnion.cpp @@ -26,5 +26,36 @@ SequenceUnion::SequenceUnion() void SequenceUnion::ProcessMatch(HeaderParserState* state, SequenceResult& result) const { - state->PushBlock(std::make_unique()); + auto isTypedef = result.PeekAndRemoveIfTag(TAG_TYPEDEF) == TAG_TYPEDEF; + std::string name; + + if (result.HasNextCapture(CAPTURE_NAME)) + name = result.NextCapture(CAPTURE_NAME).IdentifierValue(); + + auto unionBlock = std::make_unique(std::move(name), isTypedef); + + if (result.HasNextCapture(CAPTURE_ALIGN)) + unionBlock->SetCustomAlignment(result.NextCapture(CAPTURE_ALIGN).IntegerValue()); + + if (result.HasNextCapture(CAPTURE_PARENT_TYPE)) + { + const auto& parentTypeToken = result.NextCapture(CAPTURE_PARENT_TYPE); + const auto* parentDefinition = state->FindType(parentTypeToken.TypeNameValue()); + + if (parentDefinition == nullptr && !state->m_namespace.IsEmpty()) + { + const auto fullTypeName = NamespaceBuilder::Combine(state->m_namespace.ToString(), parentTypeToken.TypeNameValue()); + parentDefinition = state->FindType(fullTypeName); + } + + if (parentDefinition == nullptr) + throw ParsingException(parentTypeToken.GetPos(), "Cannot find specified parent type"); + + if (parentDefinition->GetType() != DataDefinitionType::STRUCT) + throw ParsingException(parentTypeToken.GetPos(), "Parent type must be a struct"); + + unionBlock->Inherit(dynamic_cast(parentDefinition)); + } + + state->PushBlock(std::move(unionBlock)); } diff --git a/src/ZoneCodeGeneratorLib/Parsing/IPackValueSupplier.h b/src/ZoneCodeGeneratorLib/Parsing/IPackValueSupplier.h index 6edde9fb..d023011c 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/IPackValueSupplier.h +++ b/src/ZoneCodeGeneratorLib/Parsing/IPackValueSupplier.h @@ -10,5 +10,5 @@ public: IPackValueSupplier& operator=(const IPackValueSupplier& other) = default; IPackValueSupplier& operator=(IPackValueSupplier&& other) noexcept = default; - virtual int GetCurrentPack() = 0; + virtual int GetCurrentPack() const = 0; }; \ No newline at end of file diff --git a/src/ZoneCodeGeneratorLib/Parsing/Impl/PackDefinitionStreamProxy.cpp b/src/ZoneCodeGeneratorLib/Parsing/Impl/PackDefinitionStreamProxy.cpp index 8694f9f7..8bb67127 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Impl/PackDefinitionStreamProxy.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Impl/PackDefinitionStreamProxy.cpp @@ -86,7 +86,7 @@ bool PackDefinitionStreamProxy::Eof() const return m_stream->Eof(); } -int PackDefinitionStreamProxy::GetCurrentPack() +int PackDefinitionStreamProxy::GetCurrentPack() const { return m_current_pack.empty() ? DEFAULT_PACK : m_current_pack.top(); } diff --git a/src/ZoneCodeGeneratorLib/Parsing/Impl/PackDefinitionStreamProxy.h b/src/ZoneCodeGeneratorLib/Parsing/Impl/PackDefinitionStreamProxy.h index fd50b61b..ded7249e 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Impl/PackDefinitionStreamProxy.h +++ b/src/ZoneCodeGeneratorLib/Parsing/Impl/PackDefinitionStreamProxy.h @@ -31,5 +31,5 @@ public: _NODISCARD bool IsOpen() const override; _NODISCARD bool Eof() const override; - int GetCurrentPack() override; + int GetCurrentPack() const override; }; diff --git a/src/ZoneCodeGeneratorLib/Utils/NameUtils.cpp b/src/ZoneCodeGeneratorLib/Utils/NameUtils.cpp new file mode 100644 index 00000000..3c282d8f --- /dev/null +++ b/src/ZoneCodeGeneratorLib/Utils/NameUtils.cpp @@ -0,0 +1,17 @@ +#include "NameUtils.h" + +#include +#include + +std::string NameUtils::GenerateRandomName() +{ + static constexpr auto ALPHABET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + std::ostringstream str; + + std::random_device random; + + for (auto i = 0u; i < 32u; i++) + str << ALPHABET[random() % std::char_traits::length(ALPHABET)]; + + return str.str(); +} diff --git a/src/ZoneCodeGeneratorLib/Utils/NameUtils.h b/src/ZoneCodeGeneratorLib/Utils/NameUtils.h new file mode 100644 index 00000000..355f1952 --- /dev/null +++ b/src/ZoneCodeGeneratorLib/Utils/NameUtils.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +class NameUtils +{ +public: + static std::string GenerateRandomName(); +}; diff --git a/src/ZoneCodeGeneratorLib/Utils/NamespaceBuilder.cpp b/src/ZoneCodeGeneratorLib/Utils/NamespaceBuilder.cpp index 211daba0..572be332 100644 --- a/src/ZoneCodeGeneratorLib/Utils/NamespaceBuilder.cpp +++ b/src/ZoneCodeGeneratorLib/Utils/NamespaceBuilder.cpp @@ -13,6 +13,11 @@ std::string NamespaceBuilder::Combine(const std::string& _namespace, const std:: return str.str(); } +bool NamespaceBuilder::IsEmpty() const +{ + return m_elements.empty(); +} + void NamespaceBuilder::Push(std::string element) { m_elements.emplace_back(std::move(element)); diff --git a/src/ZoneCodeGeneratorLib/Utils/NamespaceBuilder.h b/src/ZoneCodeGeneratorLib/Utils/NamespaceBuilder.h index b624dcb1..51e83c94 100644 --- a/src/ZoneCodeGeneratorLib/Utils/NamespaceBuilder.h +++ b/src/ZoneCodeGeneratorLib/Utils/NamespaceBuilder.h @@ -10,6 +10,7 @@ class NamespaceBuilder public: static std::string Combine(const std::string& _namespace, const std::string& name); + _NODISCARD bool IsEmpty() const; void Push(std::string element); void Pop(); std::string ToString();