mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-21 00:25:44 +00:00
implement reordering seequence
This commit is contained in:
parent
0cafabc44e
commit
0fcb3d388a
@ -9,7 +9,7 @@ SequenceReorder::SequenceReorder()
|
|||||||
|
|
||||||
AddLabeledMatchers(CommandsCommonMatchers::Typename(this), CommandsCommonMatchers::LABEL_TYPENAME);
|
AddLabeledMatchers(CommandsCommonMatchers::Typename(this), CommandsCommonMatchers::LABEL_TYPENAME);
|
||||||
AddMatchers({
|
AddMatchers({
|
||||||
create.Keyword("reorder"),
|
create.Keyword("reorder").Capture(CAPTURE_START),
|
||||||
create.Optional(create.Label(CommandsCommonMatchers::LABEL_TYPENAME).Capture(CAPTURE_TYPE)),
|
create.Optional(create.Label(CommandsCommonMatchers::LABEL_TYPENAME).Capture(CAPTURE_TYPE)),
|
||||||
create.Char(':'),
|
create.Char(':'),
|
||||||
create.Optional(create.And({
|
create.Optional(create.And({
|
||||||
@ -22,6 +22,84 @@ SequenceReorder::SequenceReorder()
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StructureInformation* SequenceReorder::GetType(CommandsParserState* state, SequenceResult<CommandsParserValue>& result)
|
||||||
|
{
|
||||||
|
if (result.HasNextCapture(CAPTURE_TYPE))
|
||||||
|
{
|
||||||
|
const auto& typeNameToken = result.NextCapture(CAPTURE_TYPE);
|
||||||
|
StructureInformation* information;
|
||||||
|
std::vector<MemberInformation*> memberChain;
|
||||||
|
|
||||||
|
if (!state->GetTypenameAndMembersFromTypename(typeNameToken.TypeNameValue(), information, memberChain))
|
||||||
|
throw ParsingException(typeNameToken.GetPos(), "Unknown type");
|
||||||
|
|
||||||
|
if (memberChain.empty())
|
||||||
|
return information;
|
||||||
|
|
||||||
|
auto* lastMember = memberChain.back();
|
||||||
|
|
||||||
|
if (lastMember->m_type == nullptr)
|
||||||
|
throw ParsingException(typeNameToken.GetPos(), "Member type must either be struct or union");
|
||||||
|
|
||||||
|
return lastMember->m_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->GetInUse() != nullptr)
|
||||||
|
return state->GetInUse();
|
||||||
|
|
||||||
|
throw ParsingException(result.NextCapture(CAPTURE_START).GetPos(), "No type is used. Therefore one needs to be specified directly.");
|
||||||
|
}
|
||||||
|
|
||||||
void SequenceReorder::ProcessMatch(CommandsParserState* state, SequenceResult<CommandsParserValue>& result) const
|
void SequenceReorder::ProcessMatch(CommandsParserState* state, SequenceResult<CommandsParserValue>& result) const
|
||||||
{
|
{
|
||||||
|
auto* information = GetType(state, result);
|
||||||
|
auto findFirst = result.PeekAndRemoveIfTag(TAG_FIND_FIRST) == TAG_FIND_FIRST;
|
||||||
|
|
||||||
|
std::string firstVariableName;
|
||||||
|
if(findFirst)
|
||||||
|
firstVariableName = result.NextCapture(CAPTURE_ENTRY).IdentifierValue();
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<MemberInformation>> newMembers;
|
||||||
|
std::list<std::unique_ptr<MemberInformation>> oldMembers;
|
||||||
|
|
||||||
|
for (auto& oldMember : information->m_ordered_members)
|
||||||
|
oldMembers.emplace_back(std::move(oldMember));
|
||||||
|
|
||||||
|
while(result.HasNextCapture(CAPTURE_ENTRY))
|
||||||
|
{
|
||||||
|
const auto& entryToken = result.NextCapture(CAPTURE_ENTRY);
|
||||||
|
const auto& nextVariableName = entryToken.IdentifierValue();
|
||||||
|
auto foundEntry = false;
|
||||||
|
|
||||||
|
for(auto i = oldMembers.begin(); i != oldMembers.end(); ++i)
|
||||||
|
{
|
||||||
|
if(i->get()->m_member->m_name == nextVariableName)
|
||||||
|
{
|
||||||
|
newMembers.emplace_back(std::move(*i));
|
||||||
|
oldMembers.erase(i);
|
||||||
|
foundEntry = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!foundEntry)
|
||||||
|
throw ParsingException(entryToken.GetPos(), "Could not find member with specified name");
|
||||||
|
}
|
||||||
|
|
||||||
|
information->m_ordered_members.clear();
|
||||||
|
|
||||||
|
while(findFirst && !oldMembers.empty())
|
||||||
|
{
|
||||||
|
if (oldMembers.front()->m_member->m_name == firstVariableName)
|
||||||
|
findFirst = false;
|
||||||
|
|
||||||
|
information->m_ordered_members.push_back(std::move(oldMembers.front()));
|
||||||
|
oldMembers.pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& newMember : newMembers)
|
||||||
|
information->m_ordered_members.push_back(std::move(newMember));
|
||||||
|
|
||||||
|
for (auto& oldMember : oldMembers)
|
||||||
|
information->m_ordered_members.emplace_back(std::move(oldMember));
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,11 @@ class SequenceReorder final : public CommandsParser::sequence_t
|
|||||||
{
|
{
|
||||||
static constexpr auto TAG_FIND_FIRST = 1;
|
static constexpr auto TAG_FIND_FIRST = 1;
|
||||||
|
|
||||||
static constexpr auto CAPTURE_TYPE = 1;
|
static constexpr auto CAPTURE_START = 1;
|
||||||
static constexpr auto CAPTURE_ENTRY = 2;
|
static constexpr auto CAPTURE_TYPE = 2;
|
||||||
|
static constexpr auto CAPTURE_ENTRY = 3;
|
||||||
|
|
||||||
|
static StructureInformation* GetType(CommandsParserState* state, SequenceResult<CommandsParserValue>& result);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void ProcessMatch(CommandsParserState* state, SequenceResult<CommandsParserValue>& result) const override;
|
void ProcessMatch(CommandsParserState* state, SequenceResult<CommandsParserValue>& result) const override;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user