mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-19 15:52:53 +00:00
ZoneCodeGenerator: Make use of the parsed tokens in TestCount and TestCondition
This commit is contained in:
parent
2bcb776bbf
commit
f2cc95ee32
@ -1,14 +1,25 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using ZoneCodeGenerator.Domain.Information;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace ZoneCodeGenerator.Domain.Evaluation
|
namespace ZoneCodeGenerator.Domain.Evaluation
|
||||||
{
|
{
|
||||||
class OperandDynamic : IEvaluation
|
class OperandDynamic : IEvaluation
|
||||||
{
|
{
|
||||||
|
public StructureInformation Structure { get; }
|
||||||
|
public IList<MemberInformation> ReferencedMemberChain { get; }
|
||||||
|
public IList<int> ArrayIndices { get; }
|
||||||
|
|
||||||
public bool IsStatic => false;
|
public bool IsStatic => false;
|
||||||
|
|
||||||
|
public OperandDynamic(StructureInformation structure, IEnumerable<MemberInformation> memberChain)
|
||||||
|
{
|
||||||
|
Structure = structure;
|
||||||
|
ReferencedMemberChain = new List<MemberInformation>(memberChain);
|
||||||
|
ArrayIndices = new List<int>();
|
||||||
|
}
|
||||||
|
|
||||||
public int EvaluateNumeric()
|
public int EvaluateNumeric()
|
||||||
{
|
{
|
||||||
throw new Exception("A dynamic operand cannot be evaluated.");
|
throw new Exception("A dynamic operand cannot be evaluated.");
|
||||||
@ -16,7 +27,7 @@ namespace ZoneCodeGenerator.Domain.Evaluation
|
|||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return "dynamic";
|
return $"{Structure.Type.FullName}::{string.Join("::", ReferencedMemberChain.Select(information => information.Member.Name))}{string.Concat(ArrayIndices.Select(i => $"[{i}]"))}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,20 @@
|
|||||||
namespace ZoneCodeGenerator.Domain.StructureInformation
|
using ZoneCodeGenerator.Domain.Evaluation;
|
||||||
|
|
||||||
|
namespace ZoneCodeGenerator.Domain.Information
|
||||||
{
|
{
|
||||||
class MemberInformation
|
class MemberInformation
|
||||||
{
|
{
|
||||||
public StructureInformation StructureType { get; }
|
public StructureInformation StructureType { get; }
|
||||||
public Variable Member { get; set; }
|
public Variable Member { get; set; }
|
||||||
public bool IsScriptString { get; set; }
|
public bool IsScriptString { get; set; }
|
||||||
|
public IEvaluation Condition { get; set; }
|
||||||
|
|
||||||
public MemberInformation(Variable member, StructureInformation structureType)
|
public MemberInformation(Variable member, StructureInformation structureType)
|
||||||
{
|
{
|
||||||
Member = member;
|
Member = member;
|
||||||
StructureType = structureType;
|
StructureType = structureType;
|
||||||
IsScriptString = false;
|
IsScriptString = false;
|
||||||
|
Condition = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,7 +4,7 @@ using System.Linq;
|
|||||||
using ZoneCodeGenerator.Domain.FastFileStructure;
|
using ZoneCodeGenerator.Domain.FastFileStructure;
|
||||||
using ZoneCodeGenerator.Persistence;
|
using ZoneCodeGenerator.Persistence;
|
||||||
|
|
||||||
namespace ZoneCodeGenerator.Domain.StructureInformation
|
namespace ZoneCodeGenerator.Domain.Information
|
||||||
{
|
{
|
||||||
class StructureInformation
|
class StructureInformation
|
||||||
{
|
{
|
@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using ZoneCodeGenerator.Domain.StructureInformation;
|
using ZoneCodeGenerator.Domain.Information;
|
||||||
using ZoneCodeGenerator.Interface;
|
using ZoneCodeGenerator.Interface;
|
||||||
using ZoneCodeGenerator.Persistence;
|
using ZoneCodeGenerator.Persistence;
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using ZoneCodeGenerator.Domain;
|
using ZoneCodeGenerator.Domain;
|
||||||
using ZoneCodeGenerator.Domain.FastFileStructure;
|
using ZoneCodeGenerator.Domain.FastFileStructure;
|
||||||
using ZoneCodeGenerator.Domain.StructureInformation;
|
using ZoneCodeGenerator.Domain.Information;
|
||||||
using ZoneCodeGenerator.Interface;
|
using ZoneCodeGenerator.Interface;
|
||||||
using ZoneCodeGenerator.Persistence;
|
using ZoneCodeGenerator.Persistence;
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using ZoneCodeGenerator.Domain;
|
using ZoneCodeGenerator.Domain;
|
||||||
using ZoneCodeGenerator.Domain.FastFileStructure;
|
using ZoneCodeGenerator.Domain.FastFileStructure;
|
||||||
|
using ZoneCodeGenerator.Domain.Information;
|
||||||
using ZoneCodeGenerator.Persistence;
|
using ZoneCodeGenerator.Persistence;
|
||||||
|
|
||||||
namespace ZoneCodeGenerator.Parsing.CommandFile
|
namespace ZoneCodeGenerator.Parsing.CommandFile
|
||||||
@ -10,6 +11,10 @@ namespace ZoneCodeGenerator.Parsing.CommandFile
|
|||||||
string Game { get; set; }
|
string Game { get; set; }
|
||||||
IReadOnlyDataRepository Repository { get; }
|
IReadOnlyDataRepository Repository { get; }
|
||||||
List<FastFileBlock> FastFileBlocks { get; }
|
List<FastFileBlock> FastFileBlocks { get; }
|
||||||
DataTypeWithMembers DataTypeInUse { get; set; }
|
StructureInformation DataTypeInUse { get; set; }
|
||||||
|
|
||||||
|
bool GetMembersFromParts(string[] parts, StructureInformation baseType, out List<MemberInformation> members);
|
||||||
|
bool GetTypenameAndMembersFromParts(string[] parts, out StructureInformation typeInformation,
|
||||||
|
out List<MemberInformation> members);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using ZoneCodeGenerator.Domain;
|
using ZoneCodeGenerator.Domain;
|
||||||
using ZoneCodeGenerator.Domain.FastFileStructure;
|
using ZoneCodeGenerator.Domain.FastFileStructure;
|
||||||
|
using ZoneCodeGenerator.Domain.Information;
|
||||||
using ZoneCodeGenerator.Interface;
|
using ZoneCodeGenerator.Interface;
|
||||||
using ZoneCodeGenerator.Parsing.CommandFile.Tests;
|
using ZoneCodeGenerator.Parsing.CommandFile.Tests;
|
||||||
using ZoneCodeGenerator.Parsing.Testing;
|
using ZoneCodeGenerator.Parsing.Testing;
|
||||||
@ -25,7 +28,7 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Impl
|
|||||||
public string Game { get; set; }
|
public string Game { get; set; }
|
||||||
public IReadOnlyDataRepository Repository { get; }
|
public IReadOnlyDataRepository Repository { get; }
|
||||||
public List<FastFileBlock> FastFileBlocks { get; }
|
public List<FastFileBlock> FastFileBlocks { get; }
|
||||||
public DataTypeWithMembers DataTypeInUse { get; set; }
|
public StructureInformation DataTypeInUse { get; set; }
|
||||||
|
|
||||||
public CommandParserState(IReadOnlyDataRepository repository)
|
public CommandParserState(IReadOnlyDataRepository repository)
|
||||||
{
|
{
|
||||||
@ -50,5 +53,76 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Impl
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool FindTypenameParts(string[] parts, out DataTypeWithMembers dataTypeWithMembers, out int typeNamePartCount)
|
||||||
|
{
|
||||||
|
typeNamePartCount = 1;
|
||||||
|
while (typeNamePartCount <= parts.Length)
|
||||||
|
{
|
||||||
|
var currentTypeName = string.Join("::", parts, 0, typeNamePartCount);
|
||||||
|
var foundDataType = Repository.GetDataTypeByName(currentTypeName);
|
||||||
|
|
||||||
|
if (foundDataType != null)
|
||||||
|
{
|
||||||
|
if (!(foundDataType is DataTypeWithMembers foundDataTypeWithMembers))
|
||||||
|
{
|
||||||
|
throw new TestFailedException($"Referenced type '{currentTypeName}' needs to be a data type with members to be used in an evaluation.");
|
||||||
|
}
|
||||||
|
|
||||||
|
dataTypeWithMembers = foundDataTypeWithMembers;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
typeNamePartCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
dataTypeWithMembers = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetMembersFromParts(string[] parts, StructureInformation baseType, out List<MemberInformation> members)
|
||||||
|
{
|
||||||
|
members = new List<MemberInformation>();
|
||||||
|
var currentStructure = baseType;
|
||||||
|
foreach (var part in parts)
|
||||||
|
{
|
||||||
|
var member = currentStructure.OrderedMembers.FirstOrDefault(information =>
|
||||||
|
information.Member.Name.Equals(part));
|
||||||
|
|
||||||
|
if (member == null)
|
||||||
|
{
|
||||||
|
members = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
members.Add(member);
|
||||||
|
currentStructure = member.StructureType;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetTypenameAndMembersFromParts(string[] parts, out StructureInformation typeInformation,
|
||||||
|
out List<MemberInformation> members)
|
||||||
|
{
|
||||||
|
if (!FindTypenameParts(parts, out var type, out var typeNamePartCount))
|
||||||
|
{
|
||||||
|
typeInformation = null;
|
||||||
|
members = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
typeInformation = Repository.GetInformationFor(type);
|
||||||
|
if (typeInformation == null)
|
||||||
|
{
|
||||||
|
members = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var memberParts = new string[parts.Length - typeNamePartCount];
|
||||||
|
Array.Copy(parts, typeNamePartCount, memberParts, 0, memberParts.Length);
|
||||||
|
|
||||||
|
return GetMembersFromParts(memberParts, typeInformation, out members);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using ZoneCodeGenerator.Domain;
|
||||||
using ZoneCodeGenerator.Domain.Evaluation;
|
using ZoneCodeGenerator.Domain.Evaluation;
|
||||||
|
using ZoneCodeGenerator.Domain.Information;
|
||||||
using ZoneCodeGenerator.Parsing.Matching;
|
using ZoneCodeGenerator.Parsing.Matching;
|
||||||
using ZoneCodeGenerator.Parsing.Matching.Matchers;
|
using ZoneCodeGenerator.Parsing.Matching.Matchers;
|
||||||
|
using ZoneCodeGenerator.Parsing.Testing;
|
||||||
|
|
||||||
namespace ZoneCodeGenerator.Parsing.CommandFile.Tests
|
namespace ZoneCodeGenerator.Parsing.CommandFile.Tests
|
||||||
{
|
{
|
||||||
class TestCondition : TestWithEvaluation
|
class TestCondition : TestWithEvaluation
|
||||||
{
|
{
|
||||||
|
private StructureInformation referencedType;
|
||||||
|
|
||||||
private const string TagAlways = "always";
|
private const string TagAlways = "always";
|
||||||
private const string TagNever = "never";
|
private const string TagNever = "never";
|
||||||
private const string TypeNameToken = "typeName";
|
private const string TypeNameToken = "typeName";
|
||||||
@ -27,11 +34,33 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Tests
|
|||||||
|
|
||||||
public TestCondition() : base(matchers)
|
public TestCondition() : base(matchers)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ProcessMatch(ICommandParserState state)
|
protected override void ProcessMatch(ICommandParserState state)
|
||||||
{
|
{
|
||||||
|
var typeName = NextMatch(TypeNameToken);
|
||||||
|
var typeNameParts = typeName.Split(new[] {"::"}, StringSplitOptions.None);
|
||||||
|
|
||||||
|
if (state.DataTypeInUse != null
|
||||||
|
&& state.GetMembersFromParts(typeNameParts, state.DataTypeInUse, out var typeMembers))
|
||||||
|
{
|
||||||
|
referencedType = state.DataTypeInUse;
|
||||||
|
}
|
||||||
|
else if (state.GetTypenameAndMembersFromParts(typeNameParts, out referencedType, out typeMembers))
|
||||||
|
{
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new TestFailedException($"Could not find type/members '{typeName}'");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeMembers == null
|
||||||
|
|| !typeMembers.Any())
|
||||||
|
{
|
||||||
|
throw new TestFailedException("Can only set conditions for members and not for types.");
|
||||||
|
}
|
||||||
|
|
||||||
IEvaluation evaluation;
|
IEvaluation evaluation;
|
||||||
switch (NextTag())
|
switch (NextTag())
|
||||||
{
|
{
|
||||||
@ -51,7 +80,19 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Tests
|
|||||||
throw new Exception("Unexpected Tag in TestCondition");
|
throw new Exception("Unexpected Tag in TestCondition");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var referencedMember = typeMembers.Last();
|
||||||
|
referencedMember.Condition = evaluation;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IEnumerable<StructureInformation> GetUsedTypes(ICommandParserState state)
|
||||||
|
{
|
||||||
|
if (state.DataTypeInUse != null
|
||||||
|
&& state.DataTypeInUse != referencedType)
|
||||||
|
{
|
||||||
|
return new[] {state.DataTypeInUse, referencedType};
|
||||||
|
}
|
||||||
|
|
||||||
|
return new[] {referencedType};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,11 +1,17 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using ZoneCodeGenerator.Domain;
|
||||||
|
using ZoneCodeGenerator.Domain.Information;
|
||||||
using ZoneCodeGenerator.Parsing.Matching;
|
using ZoneCodeGenerator.Parsing.Matching;
|
||||||
using ZoneCodeGenerator.Parsing.Matching.Matchers;
|
using ZoneCodeGenerator.Parsing.Matching.Matchers;
|
||||||
|
using ZoneCodeGenerator.Parsing.Testing;
|
||||||
|
|
||||||
namespace ZoneCodeGenerator.Parsing.CommandFile.Tests
|
namespace ZoneCodeGenerator.Parsing.CommandFile.Tests
|
||||||
{
|
{
|
||||||
class TestCount : TestWithEvaluation
|
class TestCount : TestWithEvaluation
|
||||||
{
|
{
|
||||||
|
private StructureInformation referencedType;
|
||||||
private const string TypeNameToken = "typeName";
|
private const string TypeNameToken = "typeName";
|
||||||
|
|
||||||
// set count <typename> <calculationStatement>;
|
// set count <typename> <calculationStatement>;
|
||||||
@ -25,12 +31,53 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Tests
|
|||||||
|
|
||||||
protected override void ProcessMatch(ICommandParserState state)
|
protected override void ProcessMatch(ICommandParserState state)
|
||||||
{
|
{
|
||||||
if (!NextTag().Equals(TagEvaluation))
|
var typeName = NextMatch(TypeNameToken);
|
||||||
|
var typeNameParts = typeName.Split(new[] { "::" }, StringSplitOptions.None);
|
||||||
|
if (state.DataTypeInUse != null
|
||||||
|
&& state.GetMembersFromParts(typeNameParts, state.DataTypeInUse, out var typeMembers))
|
||||||
{
|
{
|
||||||
throw new Exception("Expected first count tag to be a calculation statement");
|
referencedType = state.DataTypeInUse;
|
||||||
|
}
|
||||||
|
else if (state.GetTypenameAndMembersFromParts(typeNameParts, out referencedType, out typeMembers))
|
||||||
|
{
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new TestFailedException($"Could not find type/members '{typeName}'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeMembers == null
|
||||||
|
|| !typeMembers.Any())
|
||||||
|
{
|
||||||
|
throw new TestFailedException("Can only set count for members and not for types.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NextTag().Equals(TagEvaluation))
|
||||||
|
throw new Exception("Expected first count tag to be a calculation statement");
|
||||||
|
|
||||||
var evaluation = ProcessEvaluation(state);
|
var evaluation = ProcessEvaluation(state);
|
||||||
|
|
||||||
|
var referencedMember = typeMembers.Last();
|
||||||
|
var reference = referencedMember.Member.VariableType.References.OfType<ReferenceTypePointer>()
|
||||||
|
.LastOrDefault();
|
||||||
|
|
||||||
|
if (reference != null)
|
||||||
|
reference.Count = evaluation;
|
||||||
|
else
|
||||||
|
throw new TestFailedException(
|
||||||
|
$"Member '{referencedMember.Member.Name}' of type '{referencedMember.Member.VariableType.Type.FullName}' cannot have its count set due to it not having a pointer reference");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IEnumerable<StructureInformation> GetUsedTypes(ICommandParserState state)
|
||||||
|
{
|
||||||
|
if (state.DataTypeInUse != null
|
||||||
|
&& state.DataTypeInUse != referencedType)
|
||||||
|
{
|
||||||
|
return new[] { state.DataTypeInUse, referencedType };
|
||||||
|
}
|
||||||
|
|
||||||
|
return new[] { referencedType };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,5 @@
|
|||||||
using ZoneCodeGenerator.Domain;
|
using System;
|
||||||
|
using ZoneCodeGenerator.Domain;
|
||||||
using ZoneCodeGenerator.Parsing.Matching;
|
using ZoneCodeGenerator.Parsing.Matching;
|
||||||
using ZoneCodeGenerator.Parsing.Matching.Matchers;
|
using ZoneCodeGenerator.Parsing.Matching.Matchers;
|
||||||
using ZoneCodeGenerator.Parsing.Testing;
|
using ZoneCodeGenerator.Parsing.Testing;
|
||||||
@ -35,7 +36,14 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Tests
|
|||||||
throw new TestFailedException($"To use data type '{typeName}' it must either be a struct or a union.");
|
throw new TestFailedException($"To use data type '{typeName}' it must either be a struct or a union.");
|
||||||
}
|
}
|
||||||
|
|
||||||
state.DataTypeInUse = dataTypeWithMembersToUse;
|
var dataTypeToUseInformation = state.Repository.GetInformationFor(dataTypeWithMembersToUse);
|
||||||
|
|
||||||
|
if (dataTypeToUseInformation == null)
|
||||||
|
{
|
||||||
|
throw new Exception($"Could not find information for type '{dataTypeWithMembersToUse.FullName}'");
|
||||||
|
}
|
||||||
|
|
||||||
|
state.DataTypeInUse = dataTypeToUseInformation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using ZoneCodeGenerator.Domain.Evaluation;
|
using ZoneCodeGenerator.Domain.Evaluation;
|
||||||
|
using ZoneCodeGenerator.Domain.Information;
|
||||||
using ZoneCodeGenerator.Parsing.Matching;
|
using ZoneCodeGenerator.Parsing.Matching;
|
||||||
using ZoneCodeGenerator.Parsing.Matching.Matchers;
|
using ZoneCodeGenerator.Parsing.Matching.Matchers;
|
||||||
using ZoneCodeGenerator.Parsing.Testing;
|
using ZoneCodeGenerator.Parsing.Testing;
|
||||||
@ -72,32 +73,70 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Tests
|
|||||||
AddTaggedMatcher(evaluation);
|
AddTaggedMatcher(evaluation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IEvaluation ProcessOperandNumber(ICommandParserState state)
|
||||||
|
{
|
||||||
|
var numberString = NextMatch(TokenOperandNumber);
|
||||||
|
return new OperandStatic(int.Parse(numberString));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract IEnumerable<StructureInformation> GetUsedTypes(ICommandParserState state);
|
||||||
|
|
||||||
|
private IEvaluation ProcessOperandTypename(ICommandParserState state)
|
||||||
|
{
|
||||||
|
var typenameString = NextMatch(TokenOperandTypename);
|
||||||
|
var arrayIndexStrings = new List<string>();
|
||||||
|
|
||||||
|
while (PeekTag().Equals(TagOperandArray))
|
||||||
|
{
|
||||||
|
NextTag();
|
||||||
|
arrayIndexStrings.Add(NextMatch(TokenOperandArray));
|
||||||
|
}
|
||||||
|
|
||||||
|
var nameParts = typenameString.Split(new[] { "::" }, StringSplitOptions.None);
|
||||||
|
List<MemberInformation> referencedMemberChain = null;
|
||||||
|
|
||||||
|
var referencedType = GetUsedTypes(state)
|
||||||
|
.FirstOrDefault(usedType => state.GetMembersFromParts(nameParts, usedType, out referencedMemberChain));
|
||||||
|
|
||||||
|
if (referencedType == null)
|
||||||
|
{
|
||||||
|
if (!state.GetTypenameAndMembersFromParts(nameParts, out referencedType,
|
||||||
|
out referencedMemberChain))
|
||||||
|
{
|
||||||
|
throw new TestFailedException($"Could not evaluate '{typenameString}'.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!referencedMemberChain.Any())
|
||||||
|
{
|
||||||
|
throw new TestFailedException($"Typename '{typenameString}' needs to reference a member at this place.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var operandDynamic = new OperandDynamic(referencedType, referencedMemberChain);
|
||||||
|
|
||||||
|
foreach (var arrayIndexString in arrayIndexStrings)
|
||||||
|
{
|
||||||
|
operandDynamic.ArrayIndices.Add(int.Parse(arrayIndexString));
|
||||||
|
}
|
||||||
|
|
||||||
|
return operandDynamic;
|
||||||
|
}
|
||||||
|
|
||||||
private IEvaluation ProcessOperand(ICommandParserState state)
|
private IEvaluation ProcessOperand(ICommandParserState state)
|
||||||
{
|
{
|
||||||
var operandTypeTag = NextTag();
|
var operandTypeTag = NextTag();
|
||||||
|
|
||||||
if (operandTypeTag.Equals(TagOperandNumber))
|
if (operandTypeTag.Equals(TagOperandNumber))
|
||||||
{
|
{
|
||||||
var numberString = NextMatch(TokenOperandNumber);
|
return ProcessOperandNumber(state);
|
||||||
return new OperandStatic(int.Parse(numberString));
|
|
||||||
}
|
}
|
||||||
else if(operandTypeTag.Equals(TagOperandTypename))
|
|
||||||
|
if(operandTypeTag.Equals(TagOperandTypename))
|
||||||
{
|
{
|
||||||
var typenameString = NextMatch(TokenOperandTypename);
|
return ProcessOperandTypename(state);
|
||||||
var arrayIndexStrings = new List<string>();
|
|
||||||
|
|
||||||
while (PeekTag().Equals(TagOperandArray))
|
|
||||||
{
|
|
||||||
NextTag();
|
|
||||||
arrayIndexStrings.Add(NextMatch(TokenOperandArray));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new OperandDynamic();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new Exception("Unknown Operand Type");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw new Exception("Unknown Operand Type");
|
||||||
}
|
}
|
||||||
|
|
||||||
private OperationType ProcessOperationType(ICommandParserState state)
|
private OperationType ProcessOperationType(ICommandParserState state)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using ZoneCodeGenerator.Domain;
|
using ZoneCodeGenerator.Domain;
|
||||||
using ZoneCodeGenerator.Domain.FastFileStructure;
|
using ZoneCodeGenerator.Domain.FastFileStructure;
|
||||||
using ZoneCodeGenerator.Domain.StructureInformation;
|
using ZoneCodeGenerator.Domain.Information;
|
||||||
|
|
||||||
namespace ZoneCodeGenerator.Persistence
|
namespace ZoneCodeGenerator.Persistence
|
||||||
{
|
{
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using ZoneCodeGenerator.Domain;
|
using ZoneCodeGenerator.Domain;
|
||||||
using ZoneCodeGenerator.Domain.FastFileStructure;
|
using ZoneCodeGenerator.Domain.FastFileStructure;
|
||||||
using ZoneCodeGenerator.Domain.StructureInformation;
|
using ZoneCodeGenerator.Domain.Information;
|
||||||
|
|
||||||
namespace ZoneCodeGenerator.Persistence
|
namespace ZoneCodeGenerator.Persistence
|
||||||
{
|
{
|
||||||
|
@ -4,7 +4,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|||||||
using Moq;
|
using Moq;
|
||||||
using ZoneCodeGenerator;
|
using ZoneCodeGenerator;
|
||||||
using ZoneCodeGenerator.Domain;
|
using ZoneCodeGenerator.Domain;
|
||||||
using ZoneCodeGenerator.Domain.StructureInformation;
|
using ZoneCodeGenerator.Domain.Information;
|
||||||
using ZoneCodeGenerator.Parsing;
|
using ZoneCodeGenerator.Parsing;
|
||||||
using ZoneCodeGenerator.Parsing.CommandFile;
|
using ZoneCodeGenerator.Parsing.CommandFile;
|
||||||
using ZoneCodeGenerator.Parsing.CommandFile.Tests;
|
using ZoneCodeGenerator.Parsing.CommandFile.Tests;
|
||||||
|
@ -4,6 +4,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|||||||
using Moq;
|
using Moq;
|
||||||
using ZoneCodeGenerator.Domain;
|
using ZoneCodeGenerator.Domain;
|
||||||
using ZoneCodeGenerator.Domain.FastFileStructure;
|
using ZoneCodeGenerator.Domain.FastFileStructure;
|
||||||
|
using ZoneCodeGenerator.Domain.Information;
|
||||||
using ZoneCodeGenerator.Parsing;
|
using ZoneCodeGenerator.Parsing;
|
||||||
using ZoneCodeGenerator.Parsing.CommandFile;
|
using ZoneCodeGenerator.Parsing.CommandFile;
|
||||||
using ZoneCodeGenerator.Parsing.CommandFile.Tests;
|
using ZoneCodeGenerator.Parsing.CommandFile.Tests;
|
||||||
@ -18,7 +19,7 @@ namespace ZoneCodeGeneratorTests.Parsing.CommandFile.Tests
|
|||||||
private Mock<IReadOnlyDataRepository> repositoryMock;
|
private Mock<IReadOnlyDataRepository> repositoryMock;
|
||||||
private Mock<ICommandParserState> parserStateMock;
|
private Mock<ICommandParserState> parserStateMock;
|
||||||
|
|
||||||
private DataTypeWithMembers dataTypeWithMembers;
|
private StructureInformation usedType;
|
||||||
|
|
||||||
private Mock<ILexer> lexerMock;
|
private Mock<ILexer> lexerMock;
|
||||||
private int tokenOffset;
|
private int tokenOffset;
|
||||||
@ -29,7 +30,7 @@ namespace ZoneCodeGeneratorTests.Parsing.CommandFile.Tests
|
|||||||
{
|
{
|
||||||
parserStateMock = new Mock<ICommandParserState>();
|
parserStateMock = new Mock<ICommandParserState>();
|
||||||
|
|
||||||
dataTypeWithMembers = null;
|
usedType = null;
|
||||||
|
|
||||||
tokenOffset = 0;
|
tokenOffset = 0;
|
||||||
tokens = new List<string>();
|
tokens = new List<string>();
|
||||||
@ -39,6 +40,9 @@ namespace ZoneCodeGeneratorTests.Parsing.CommandFile.Tests
|
|||||||
parserStateMock.SetupGet(state => state.Repository)
|
parserStateMock.SetupGet(state => state.Repository)
|
||||||
.Returns(() => repositoryMock.Object);
|
.Returns(() => repositoryMock.Object);
|
||||||
|
|
||||||
|
repositoryMock.Setup(repository => repository.GetInformationFor(It.IsAny<DataTypeWithMembers>()))
|
||||||
|
.Returns((DataTypeWithMembers type) => new StructureInformation(type));
|
||||||
|
|
||||||
lexerMock.Setup(lexer => lexer.PeekToken(It.IsAny<int>()))
|
lexerMock.Setup(lexer => lexer.PeekToken(It.IsAny<int>()))
|
||||||
.Returns((int index) => tokens.ElementAtOrDefault(index + tokenOffset));
|
.Returns((int index) => tokens.ElementAtOrDefault(index + tokenOffset));
|
||||||
lexerMock.Setup(lexer => lexer.NextToken())
|
lexerMock.Setup(lexer => lexer.NextToken())
|
||||||
@ -47,9 +51,9 @@ namespace ZoneCodeGeneratorTests.Parsing.CommandFile.Tests
|
|||||||
.Callback((int count) => tokenOffset += count);
|
.Callback((int count) => tokenOffset += count);
|
||||||
|
|
||||||
parserStateMock.SetupGet(state => state.DataTypeInUse)
|
parserStateMock.SetupGet(state => state.DataTypeInUse)
|
||||||
.Returns(() => dataTypeWithMembers);
|
.Returns(() => usedType);
|
||||||
parserStateMock.SetupSet(state => state.DataTypeInUse = It.IsAny<DataTypeWithMembers>())
|
parserStateMock.SetupSet(state => state.DataTypeInUse = It.IsAny<StructureInformation>())
|
||||||
.Callback((DataTypeWithMembers type) => dataTypeWithMembers = type);
|
.Callback((StructureInformation type) => usedType = type);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@ -70,7 +74,8 @@ namespace ZoneCodeGeneratorTests.Parsing.CommandFile.Tests
|
|||||||
Assert.AreEqual(TokenTestResult.Match, test.PerformTest(parserStateMock.Object, lexerMock.Object));
|
Assert.AreEqual(TokenTestResult.Match, test.PerformTest(parserStateMock.Object, lexerMock.Object));
|
||||||
Assert.AreEqual(6, test.ConsumedTokenCount);
|
Assert.AreEqual(6, test.ConsumedTokenCount);
|
||||||
|
|
||||||
Assert.AreEqual(assetTypeToUse, dataTypeWithMembers);
|
Assert.IsNotNull(assetTypeToUse);
|
||||||
|
Assert.AreEqual(usedType.Type, assetTypeToUse);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user