ZoneCodeGenerator: Replace OperandDynamics static array indices with Evaluations

This commit is contained in:
Jan 2019-12-23 23:46:04 +01:00
parent db8e4c987c
commit 62ac2e8aae
3 changed files with 32 additions and 15 deletions

View File

@ -9,7 +9,7 @@ namespace ZoneCodeGenerator.Domain.Evaluation
{ {
public StructureInformation Structure { get; } public StructureInformation Structure { get; }
public IList<MemberInformation> ReferencedMemberChain { get; } public IList<MemberInformation> ReferencedMemberChain { get; }
public IList<int> ArrayIndices { get; } public IList<IEvaluation> ArrayIndices { get; }
public bool IsStatic => false; public bool IsStatic => false;
@ -17,7 +17,7 @@ namespace ZoneCodeGenerator.Domain.Evaluation
{ {
Structure = structure; Structure = structure;
ReferencedMemberChain = new List<MemberInformation>(memberChain); ReferencedMemberChain = new List<MemberInformation>(memberChain);
ArrayIndices = new List<int>(); ArrayIndices = new List<IEvaluation>();
} }
public int EvaluateNumeric() public int EvaluateNumeric()

View File

@ -34,9 +34,9 @@ $endif$
PrintOperandDynamic(op) ::= <% PrintOperandDynamic(op) ::= <%
$TypeVarName(op.Structure.Type)$ $TypeVarName(op.Structure.Type)$
->$first(op.ReferencedMemberChain):{member | $member.Member.Name$}$ ->$trunc(op.ReferencedMemberChain):{member | $member.Member.Name$$if(member.Computations.ContainsNonEmbeddedReference)$->$else$.$endif$}$
$rest(op.ReferencedMemberChain):{member | .$member.Member.Name$}$ $last(op.ReferencedMemberChain):{member | $member.Member.Name$}$
$op.ArrayIndices:{ arrayIndex | [$arrayIndex$]}$ $op.ArrayIndices:{ arrayIndex | [$PrintEvaluation(arrayIndex)$]}$
%> %>
PrintOperation(operation) ::= <% PrintOperation(operation) ::= <%

View File

@ -25,19 +25,28 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Tests
// Operand Sub-Tags // Operand Sub-Tags
private const string TagOperandNumber = "operandNumber"; private const string TagOperandNumber = "operandNumber";
private const string TagOperandTypename = "operandTypename"; private const string TagOperandTypename = "operandTypename";
private const string TagOperandArray = "operandArray";
private const string TokenOperandNumber = "operandNumberToken"; private const string TokenOperandNumber = "operandNumberToken";
private const string TokenOperandTypename = "operandTypenameToken"; private const string TokenOperandTypename = "operandTypenameToken";
private const string TokenOperandArray = "operandArrayToken"; private const string TokenOperandArray = "operandArrayToken";
// OperandArray Sub-Tags
private const string TagOperandArray = "operandArray";
private const string TagOperandArrayEnd = "operandArrayEnd";
// Visible to children // Visible to children
protected const string TagEvaluation = "evaluation"; protected const string TagEvaluation = "evaluation";
private static readonly TokenMatcher operandArray = new MatcherGroupAnd(
new MatcherLiteral("["),
new MatcherWithTag(TagEvaluation),
new MatcherLiteral("]").WithTag(TagOperandArrayEnd)
).WithTag(TagOperandArray);
// operand ::= <typename> <array>* | <number> // operand ::= <typename> <array>* | <number>
private static readonly TokenMatcher operand = new MatcherGroupOr( private static readonly TokenMatcher operand = new MatcherGroupOr(
new MatcherGroupAnd( new MatcherGroupAnd(
new MatcherTypename().WithName(TokenOperandTypename), 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), ).WithTag(TagOperandTypename),
new MatcherNumber().WithName(TokenOperandNumber).WithTag(TagOperandNumber) new MatcherNumber().WithName(TokenOperandNumber).WithTag(TagOperandNumber)
).WithTag(TagOperand); ).WithTag(TagOperand);
@ -70,6 +79,7 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Tests
protected TestWithEvaluation(TokenMatcher[] matchers) : base(matchers) protected TestWithEvaluation(TokenMatcher[] matchers) : base(matchers)
{ {
AddTaggedMatcher(operandArray);
AddTaggedMatcher(operand); AddTaggedMatcher(operand);
AddTaggedMatcher(operationType); AddTaggedMatcher(operationType);
AddTaggedMatcher(evaluation); AddTaggedMatcher(evaluation);
@ -86,17 +96,24 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Tests
private IEvaluation ProcessOperandTypename(ICommandParserState state) private IEvaluation ProcessOperandTypename(ICommandParserState state)
{ {
var typenameString = NextMatch(TokenOperandTypename); var typenameString = NextMatch(TokenOperandTypename);
var arrayIndexStrings = new List<string>(); var arrayIndexEvaluations = new List<IEvaluation>();
while (PeekTag().Equals(TagOperandArray)) while (PeekTag().Equals(TagOperandArray))
{ {
NextTag(); 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); 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) var enumMember = state.Repository.GetAllEnums().SelectMany(_enum => _enum.Members)
.FirstOrDefault(member => member.Name.Equals(nameParts[0])); .FirstOrDefault(member => member.Name.Equals(nameParts[0]));
@ -127,10 +144,9 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Tests
} }
var operandDynamic = new OperandDynamic(referencedType, referencedMemberChain); var operandDynamic = new OperandDynamic(referencedType, referencedMemberChain);
foreach (var indexEvaluation in arrayIndexEvaluations)
foreach (var arrayIndexString in arrayIndexStrings)
{ {
operandDynamic.ArrayIndices.Add(int.Parse(arrayIndexString)); operandDynamic.ArrayIndices.Add(indexEvaluation);
} }
return operandDynamic; return operandDynamic;
@ -187,7 +203,8 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Tests
while (true) while (true)
{ {
IEvaluation firstStatementPart; IEvaluation firstStatementPart;
switch (NextTag()) var tag = NextTag();
switch (tag)
{ {
case TagEvaluationParenthesis: case TagEvaluationParenthesis:
firstStatementPart = ProcessEvaluationInParenthesis(state); firstStatementPart = ProcessEvaluationInParenthesis(state);
@ -198,7 +215,7 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Tests
break; break;
default: default:
throw new Exception("Invalid followup tag @ Evaluation"); throw new Exception($"Invalid followup tag '{tag}' @ Evaluation");
} }
operands.Add(firstStatementPart); operands.Add(firstStatementPart);