diff --git a/src/ZoneCodeGenerator/Domain/Evaluation/OperandDynamic.cs b/src/ZoneCodeGenerator/Domain/Evaluation/OperandDynamic.cs index 2b2e559a..3b1a20aa 100644 --- a/src/ZoneCodeGenerator/Domain/Evaluation/OperandDynamic.cs +++ b/src/ZoneCodeGenerator/Domain/Evaluation/OperandDynamic.cs @@ -9,7 +9,7 @@ namespace ZoneCodeGenerator.Domain.Evaluation { public StructureInformation Structure { get; } public IList ReferencedMemberChain { get; } - public IList ArrayIndices { get; } + public IList ArrayIndices { get; } public bool IsStatic => false; @@ -17,7 +17,7 @@ namespace ZoneCodeGenerator.Domain.Evaluation { Structure = structure; ReferencedMemberChain = new List(memberChain); - ArrayIndices = new List(); + ArrayIndices = new List(); } public int EvaluateNumeric() diff --git a/src/ZoneCodeGenerator/Generating/Templates/Common.stg b/src/ZoneCodeGenerator/Generating/Templates/Common.stg index 60510df5..b1dc6b9f 100644 --- a/src/ZoneCodeGenerator/Generating/Templates/Common.stg +++ b/src/ZoneCodeGenerator/Generating/Templates/Common.stg @@ -34,9 +34,9 @@ $endif$ PrintOperandDynamic(op) ::= <% $TypeVarName(op.Structure.Type)$ -->$first(op.ReferencedMemberChain):{member | $member.Member.Name$}$ -$rest(op.ReferencedMemberChain):{member | .$member.Member.Name$}$ -$op.ArrayIndices:{ arrayIndex | [$arrayIndex$]}$ +->$trunc(op.ReferencedMemberChain):{member | $member.Member.Name$$if(member.Computations.ContainsNonEmbeddedReference)$->$else$.$endif$}$ +$last(op.ReferencedMemberChain):{member | $member.Member.Name$}$ +$op.ArrayIndices:{ arrayIndex | [$PrintEvaluation(arrayIndex)$]}$ %> PrintOperation(operation) ::= <% diff --git a/src/ZoneCodeGenerator/Parsing/CommandFile/Tests/TestWithEvaluation.cs b/src/ZoneCodeGenerator/Parsing/CommandFile/Tests/TestWithEvaluation.cs index fbdfe81c..bed7e9f0 100644 --- a/src/ZoneCodeGenerator/Parsing/CommandFile/Tests/TestWithEvaluation.cs +++ b/src/ZoneCodeGenerator/Parsing/CommandFile/Tests/TestWithEvaluation.cs @@ -25,19 +25,28 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Tests // Operand Sub-Tags private const string TagOperandNumber = "operandNumber"; private const string TagOperandTypename = "operandTypename"; - private const string TagOperandArray = "operandArray"; private const string TokenOperandNumber = "operandNumberToken"; private const string TokenOperandTypename = "operandTypenameToken"; private const string TokenOperandArray = "operandArrayToken"; + // OperandArray Sub-Tags + private const string TagOperandArray = "operandArray"; + private const string TagOperandArrayEnd = "operandArrayEnd"; + // Visible to children protected const string TagEvaluation = "evaluation"; + private static readonly TokenMatcher operandArray = new MatcherGroupAnd( + new MatcherLiteral("["), + new MatcherWithTag(TagEvaluation), + new MatcherLiteral("]").WithTag(TagOperandArrayEnd) + ).WithTag(TagOperandArray); + // operand ::= * | private static readonly TokenMatcher operand = new MatcherGroupOr( new MatcherGroupAnd( new MatcherTypename().WithName(TokenOperandTypename), - new MatcherGroupLoop(MatcherGroupLoop.LoopMode.ZeroOneMultiple, new MatcherArray().WithName(TokenOperandArray).WithTag(TagOperandArray)) + new MatcherGroupLoop(MatcherGroupLoop.LoopMode.ZeroOneMultiple, new MatcherWithTag(TagOperandArray)) ).WithTag(TagOperandTypename), new MatcherNumber().WithName(TokenOperandNumber).WithTag(TagOperandNumber) ).WithTag(TagOperand); @@ -70,6 +79,7 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Tests protected TestWithEvaluation(TokenMatcher[] matchers) : base(matchers) { + AddTaggedMatcher(operandArray); AddTaggedMatcher(operand); AddTaggedMatcher(operationType); AddTaggedMatcher(evaluation); @@ -86,17 +96,24 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Tests private IEvaluation ProcessOperandTypename(ICommandParserState state) { var typenameString = NextMatch(TokenOperandTypename); - var arrayIndexStrings = new List(); + var arrayIndexEvaluations = new List(); while (PeekTag().Equals(TagOperandArray)) { NextTag(); - arrayIndexStrings.Add(NextMatch(TokenOperandArray)); + + if (NextTag() != TagEvaluation) + throw new Exception("Expected evaluation tag @ Operand"); + + arrayIndexEvaluations.Add(ProcessEvaluation(state)); + + if (NextTag() != TagOperandArrayEnd) + throw new Exception("Expected operand array end tag @ Operand"); } var nameParts = typenameString.Split(new[] { "::" }, StringSplitOptions.None); - if (nameParts.Length == 1 && arrayIndexStrings.Count == 0) + if (nameParts.Length == 1 && arrayIndexEvaluations.Count == 0) { var enumMember = state.Repository.GetAllEnums().SelectMany(_enum => _enum.Members) .FirstOrDefault(member => member.Name.Equals(nameParts[0])); @@ -127,10 +144,9 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Tests } var operandDynamic = new OperandDynamic(referencedType, referencedMemberChain); - - foreach (var arrayIndexString in arrayIndexStrings) + foreach (var indexEvaluation in arrayIndexEvaluations) { - operandDynamic.ArrayIndices.Add(int.Parse(arrayIndexString)); + operandDynamic.ArrayIndices.Add(indexEvaluation); } return operandDynamic; @@ -187,7 +203,8 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Tests while (true) { IEvaluation firstStatementPart; - switch (NextTag()) + var tag = NextTag(); + switch (tag) { case TagEvaluationParenthesis: firstStatementPart = ProcessEvaluationInParenthesis(state); @@ -198,7 +215,7 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Tests break; default: - throw new Exception("Invalid followup tag @ Evaluation"); + throw new Exception($"Invalid followup tag '{tag}' @ Evaluation"); } operands.Add(firstStatementPart);