diff --git a/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefEnum.cpp b/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefEnum.cpp index af2e3ea9..4296f3fc 100644 --- a/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefEnum.cpp +++ b/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefEnum.cpp @@ -12,9 +12,18 @@ CommonStructuredDataDefEnumEntry::CommonStructuredDataDefEnumEntry(std::string n } CommonStructuredDataDefEnum::CommonStructuredDataDefEnum() -= default; - -CommonStructuredDataDefEnum::CommonStructuredDataDefEnum(std::string name) - : m_name(std::move(name)) + : m_reserved_entry_count(-1) +{ +} + +CommonStructuredDataDefEnum::CommonStructuredDataDefEnum(std::string name) + : m_name(std::move(name)), + m_reserved_entry_count(-1) +{ +} + +CommonStructuredDataDefEnum::CommonStructuredDataDefEnum(std::string name, const int reservedEntryCount) + : m_name(std::move(name)), + m_reserved_entry_count(reservedEntryCount) { } diff --git a/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefEnum.h b/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefEnum.h index 03788831..52e10731 100644 --- a/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefEnum.h +++ b/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefEnum.h @@ -14,8 +14,10 @@ struct CommonStructuredDataDefEnumEntry struct CommonStructuredDataDefEnum { std::string m_name; + int m_reserved_entry_count; std::vector m_entries; CommonStructuredDataDefEnum(); explicit CommonStructuredDataDefEnum(std::string name); + CommonStructuredDataDefEnum(std::string name, int reservedEntryCount); }; \ No newline at end of file diff --git a/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefDefScopeSequences.cpp b/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefDefScopeSequences.cpp index 10013315..a0a415a5 100644 --- a/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefDefScopeSequences.cpp +++ b/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefDefScopeSequences.cpp @@ -7,6 +7,7 @@ namespace sdd::def_scope_sequences class SequenceEnum final : public StructuredDataDefParser::sequence_t { static constexpr auto CAPTURE_NAME = 1; + static constexpr auto CAPTURE_RESERVED_COUNT = 2; public: SequenceEnum() @@ -15,6 +16,11 @@ namespace sdd::def_scope_sequences AddMatchers({ create.Keyword("enum"), + create.Optional(create.And({ + create.Char('('), + create.Integer().Capture(CAPTURE_RESERVED_COUNT), + create.Char(')') + })), create.Identifier().Capture(CAPTURE_NAME), create.Char('{') }); @@ -26,6 +32,15 @@ namespace sdd::def_scope_sequences assert(state->m_current_def); auto newEnum = std::make_unique(result.NextCapture(CAPTURE_NAME).IdentifierValue()); + if (result.HasNextCapture(CAPTURE_RESERVED_COUNT)) + { + const auto& reservedCountToken = result.NextCapture(CAPTURE_RESERVED_COUNT); + newEnum->m_reserved_entry_count = reservedCountToken.IntegerValue(); + + if (newEnum->m_reserved_entry_count <= 0) + throw ParsingException(reservedCountToken.GetPos(), "Reserved enum entry count must be greater than zero"); + } + state->m_current_enum = newEnum.get(); state->m_def_types_by_name.emplace(newEnum->m_name, CommonStructuredDataDefType(CommonStructuredDataDefTypeCategory::ENUM, state->m_current_def->m_enums.size())); state->m_current_def->m_enums.emplace_back(std::move(newEnum)); diff --git a/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefEnumScopeSequences.cpp b/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefEnumScopeSequences.cpp index bf0e242c..c14bcb12 100644 --- a/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefEnumScopeSequences.cpp +++ b/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefEnumScopeSequences.cpp @@ -29,7 +29,11 @@ namespace sdd::enum_scope_sequences { assert(state->m_current_enum); - state->m_current_enum->m_entries.emplace_back(result.NextCapture(CAPTURE_ENTRY_VALUE).StringValue(), state->m_current_enum->m_entries.size()); + const auto& entryValueToken = result.NextCapture(CAPTURE_ENTRY_VALUE); + if (state->m_current_enum->m_reserved_entry_count > 0 && static_cast(state->m_current_enum->m_reserved_entry_count) <= state->m_current_enum->m_entries.size()) + throw ParsingException(entryValueToken.GetPos(), "Enum entry count exceeds reserved count"); + + state->m_current_enum->m_entries.emplace_back(entryValueToken.StringValue(), state->m_current_enum->m_entries.size()); } };