diff --git a/src/ZoneCodeGenerator/Parsing/CommandFile/Impl/CommandParserState.cs b/src/ZoneCodeGenerator/Parsing/CommandFile/Impl/CommandParserState.cs index 8a735ef3..7d4e0d3f 100644 --- a/src/ZoneCodeGenerator/Parsing/CommandFile/Impl/CommandParserState.cs +++ b/src/ZoneCodeGenerator/Parsing/CommandFile/Impl/CommandParserState.cs @@ -24,6 +24,7 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Impl new TestReorder(), new TestReusable(), new TestScriptString(), + new TestSetBlock(), new TestString(), new TestUse() }; diff --git a/src/ZoneCodeGenerator/Parsing/CommandFile/Tests/TestSetBlock.cs b/src/ZoneCodeGenerator/Parsing/CommandFile/Tests/TestSetBlock.cs new file mode 100644 index 00000000..d15ca01a --- /dev/null +++ b/src/ZoneCodeGenerator/Parsing/CommandFile/Tests/TestSetBlock.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ZoneCodeGenerator.Domain; +using ZoneCodeGenerator.Domain.FastFileStructure; +using ZoneCodeGenerator.Domain.Information; +using ZoneCodeGenerator.Parsing.Matching; +using ZoneCodeGenerator.Parsing.Matching.Matchers; +using ZoneCodeGenerator.Parsing.Testing; + +namespace ZoneCodeGenerator.Parsing.CommandFile.Tests +{ + class TestSetBlock : AbstractTokenTest + { + private const string TokenTypeName = "name"; + private const string TokenBlockEnumEntry = "block"; + + private static readonly TokenMatcher[] matchers = + { + new MatcherLiteral("set"), + new MatcherLiteral("block"), + new MatcherTypename().WithName(TokenTypeName), + new MatcherName().WithName(TokenBlockEnumEntry), + new MatcherLiteral(";") + }; + + public TestSetBlock() : base(matchers) + { + } + + protected override void ProcessMatch(ICommandParserState state) + { + var typeName = NextMatch(TokenTypeName); + var typeNameParts = typeName.Split(new[] {"::"}, StringSplitOptions.None); + StructureInformation structure; + + if (state.DataTypeInUse != null && + state.GetMembersFromParts(typeNameParts, state.DataTypeInUse, out var memberList)) + { + structure = state.DataTypeInUse; + } + else if (state.GetTypenameAndMembersFromParts(typeNameParts, out structure, out memberList)) + { + // Do nothing + } + else + { + throw new TestFailedException($"Could not find type '{typeName}'."); + } + + if (memberList.Any()) + { + var lastMember = memberList.Last(); + + structure = lastMember.StructureType ?? throw new TestFailedException( + $"Specified member '{lastMember.Member.Name}' is not a structure or union and therefore cannot have its block set."); + } + + var blockName = NextMatch(TokenBlockEnumEntry); + var block = state.FastFileBlocks + .FirstOrDefault(fastFileBlock => fastFileBlock.Name.Equals(blockName)); + + structure.Block = + block ?? throw new TestFailedException($"Could not find fastfile block with name '{blockName}'"); + } + } +} \ No newline at end of file