From 48e3738c05c34e2e93503635c294b77925865787 Mon Sep 17 00:00:00 2001 From: Jan Date: Fri, 19 Feb 2021 20:23:11 +0100 Subject: [PATCH] implement parsing for reusable and scriptstring and string --- .../Commands/Sequence/SequenceReusable.cpp | 11 +++++ .../Sequence/SequenceScriptString.cpp | 19 ++++++++ .../Commands/Sequence/SequenceString.cpp | 44 +++++++++++++++++++ 3 files changed, 74 insertions(+) diff --git a/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceReusable.cpp b/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceReusable.cpp index 7531bf5f..89ab259c 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceReusable.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceReusable.cpp @@ -18,4 +18,15 @@ SequenceReusable::SequenceReusable() void SequenceReusable::ProcessMatch(CommandsParserState* state, SequenceResult& result) const { + const auto& typeNameToken = result.NextCapture(CAPTURE_TYPE); + + StructureInformation* type; + std::vector members; + if (!state->GetTypenameAndMembersFromTypename(typeNameToken.TypeNameValue(), type, members)) + throw ParsingException(typeNameToken.GetPos(), "Unknown type"); + + if (members.empty()) + throw ParsingException(typeNameToken.GetPos(), "Need to specify a member when trying to mark as reusable."); + + members.back()->m_is_reusable = true; } diff --git a/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceScriptString.cpp b/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceScriptString.cpp index a1a57c60..fc813baa 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceScriptString.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceScriptString.cpp @@ -18,4 +18,23 @@ SequenceScriptString::SequenceScriptString() void SequenceScriptString::ProcessMatch(CommandsParserState* state, SequenceResult& result) const { + const auto& typeNameToken = result.NextCapture(CAPTURE_TYPE); + + StructureInformation* type; + std::vector members; + if (!state->GetTypenameAndMembersFromTypename(typeNameToken.TypeNameValue(), type, members)) + throw ParsingException(typeNameToken.GetPos(), "Unknown type"); + + if (members.empty()) + throw ParsingException(typeNameToken.GetPos(), "Need to specify a member when trying to mark as script string."); + + auto* lastMember = members.back(); + const auto* dataDef = lastMember->m_member->m_type_declaration->m_type; + while (dataDef->GetType() == DataDefinitionType::TYPEDEF) + dataDef = dynamic_cast(dataDef)->m_type_declaration->m_type; + + if (dataDef->GetType() != DataDefinitionType::BASE_TYPE) + throw ParsingException(typeNameToken.GetPos(), "Invalid type for script string, must be a base type"); + + members.back()->m_is_script_string = true; } diff --git a/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceString.cpp b/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceString.cpp index e1e3bd70..dd8a3e58 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceString.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceString.cpp @@ -1,5 +1,8 @@ #include "SequenceString.h" +#include + + #include "Parsing/Commands/Matcher/CommandsMatcherFactory.h" #include "Parsing/Commands/Matcher/CommandsCommonMatchers.h" @@ -18,4 +21,45 @@ SequenceString::SequenceString() void SequenceString::ProcessMatch(CommandsParserState* state, SequenceResult& result) const { + const auto& typeNameToken = result.NextCapture(CAPTURE_TYPE); + + StructureInformation* type; + std::vector members; + if (!state->GetTypenameAndMembersFromTypename(typeNameToken.TypeNameValue(), type, members)) + throw ParsingException(typeNameToken.GetPos(), "Unknown type"); + + if (members.empty()) + throw ParsingException(typeNameToken.GetPos(), "Need to specify a member when trying to mark as string."); + + auto* lastMember = members.back(); + auto* typeDecl = lastMember->m_member->m_type_declaration.get(); + auto hasPointerRef = false; + + while (true) + { + if (!hasPointerRef) + { + const auto& modifiers = typeDecl->m_declaration_modifiers; + hasPointerRef = std::any_of(modifiers.begin(), modifiers.end(), [](const std::unique_ptr& modifier) + { + return modifier->GetType() == DeclarationModifierType::POINTER; + }); + } + + if (typeDecl->m_type->GetType() == DataDefinitionType::TYPEDEF) + { + const auto* typedefDef = dynamic_cast(typeDecl->m_type); + typeDecl = typedefDef->m_type_declaration.get(); + } + else + break; + } + + if (!hasPointerRef) + throw ParsingException(typeNameToken.GetPos(), "Invalid type for string, must be a pointer"); + + if (typeDecl->m_type->GetType() != DataDefinitionType::BASE_TYPE) + throw ParsingException(typeNameToken.GetPos(), "Invalid type for string, must be a base type"); + + lastMember->m_is_string = true; }