diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockEnum.cpp b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockEnum.cpp index 2a1ec68c..1f083faf 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockEnum.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockEnum.cpp @@ -7,6 +7,7 @@ HeaderBlockEnum::HeaderBlockEnum(std::string typeName, const BaseTypeDefinition* : m_type_name(std::move(typeName)), m_parent_type(parentType), m_is_typedef(isTypeDef), + m_next_value(0), m_enum_definition(nullptr) { } @@ -56,9 +57,26 @@ void HeaderBlockEnum::OnChildBlockClose(HeaderParserState* state, IHeaderBlock* void HeaderBlockEnum::AddEnumMember(std::unique_ptr enumMember) { + m_next_value = enumMember->m_value + 1; m_members.emplace_back(std::move(enumMember)); } +EnumMember* HeaderBlockEnum::GetEnumMember(const std::string& name) const +{ + for (const auto& member : m_members) + { + if (member->m_name == name) + return member.get(); + } + + return nullptr; +} + +long long HeaderBlockEnum::GetNextEnumMemberValue() const +{ + return m_next_value; +} + void HeaderBlockEnum::SetBlockName(const TokenPos& nameTokenPos, std::string name) { m_variable_name = std::move(name); diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockEnum.h b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockEnum.h index a706d60c..32e45c7d 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockEnum.h +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockEnum.h @@ -1,5 +1,6 @@ #pragma once +#include "Utils/ClassUtils.h" #include "IHeaderBlock.h" #include "IHeaderBlockNameHolder.h" #include "IHeaderBlockVariableDefining.h" @@ -13,6 +14,7 @@ class HeaderBlockEnum final : public IHeaderBlock, public IHeaderBlockNameHolder const BaseTypeDefinition* m_parent_type; bool m_is_typedef; std::vector> m_members; + long long m_next_value; EnumDefinition* m_enum_definition; std::string m_variable_name; @@ -27,6 +29,8 @@ public: void OnChildBlockClose(HeaderParserState* state, IHeaderBlock* block) override; void AddEnumMember(std::unique_ptr enumMember); + _NODISCARD EnumMember* GetEnumMember(const std::string& name) const; + _NODISCARD long long GetNextEnumMemberValue() const; void SetBlockName(const TokenPos& nameTokenPos, std::string name) override; bool IsDefiningVariable() override; diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Sequence/SequenceEnumMember.cpp b/src/ZoneCodeGeneratorLib/Parsing/Header/Sequence/SequenceEnumMember.cpp index ede39549..73b822a2 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Sequence/SequenceEnumMember.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Sequence/SequenceEnumMember.cpp @@ -1,5 +1,6 @@ #include "SequenceEnumMember.h" +#include "Parsing/Header/Block/HeaderBlockEnum.h" #include "Parsing/Header/Matcher/HeaderMatcherFactory.h" #include "Parsing/Header/Matcher/HeaderCommonMatchers.h" @@ -25,4 +26,33 @@ SequenceEnumMember::SequenceEnumMember() void SequenceEnumMember::ProcessMatch(HeaderParserState* state, SequenceResult& result) const { + long long value; + auto* enumBlock = dynamic_cast(state->GetBlock()); + + if (result.HasNextCapture(CAPTURE_VALUE)) + { + const auto& valueToken = result.NextCapture(CAPTURE_VALUE); + if (valueToken.m_type == HeaderParserValueType::IDENTIFIER) + { + auto* enumMember = enumBlock->GetEnumMember(valueToken.IdentifierValue()); + + if (enumMember == nullptr) + enumMember = state->FindEnumMember(valueToken.IdentifierValue()); + + if (enumMember == nullptr) + throw ParsingException(valueToken.GetPos(), "Could not find enum member with specified name"); + + value = enumMember->m_value; + } + else + { + value = valueToken.IntegerValue(); + } + } + else + { + value = enumBlock->GetNextEnumMemberValue(); + } + + enumBlock->AddEnumMember(std::make_unique(result.NextCapture(CAPTURE_NAME).IdentifierValue(), value)); }