2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2025-09-06 16:57:25 +00:00

ZoneCodeGenerator: Add Evaluation as basis for specifying conditions and counts

This commit is contained in:
Jan
2019-10-02 15:47:24 +02:00
parent 61eb92588e
commit 785e2c9bfb
10 changed files with 271 additions and 22 deletions

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ZoneCodeGenerator.Domain.Evaluation
{
interface IEvaluation
{
bool IsStatic { get; }
int EvaluateNumeric();
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ZoneCodeGenerator.Domain.Evaluation
{
class OperandDynamic : IEvaluation
{
public bool IsStatic => false;
public int EvaluateNumeric()
{
throw new Exception("A dynamic operand cannot be evaluated.");
}
}
}

View File

@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ZoneCodeGenerator.Domain.Evaluation
{
class OperandStatic : IEvaluation
{
public int Value { get; }
public bool IsStatic => true;
public int EvaluateNumeric()
{
return Value;
}
public OperandStatic(int value)
{
Value = value;
}
}
}

View File

@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ZoneCodeGenerator.Domain.Evaluation
{
class Operation : IEvaluation
{
public IEvaluation Operand1 { get; }
public IEvaluation Operand2 { get; }
public OperationType OperationType { get; }
public bool IsStatic => Operand1.IsStatic && Operand2.IsStatic;
public int EvaluateNumeric()
{
return OperationType.Function(Operand1.EvaluateNumeric(), Operand2.EvaluateNumeric());
}
public Operation(IEvaluation operand1, IEvaluation operand2, OperationType type)
{
Operand1 = operand1;
Operand2 = operand2;
OperationType = type;
}
}
}

View File

@@ -0,0 +1,138 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace ZoneCodeGenerator.Domain.Evaluation
{
sealed class OperationType
{
// https://en.cppreference.com/w/cpp/language/operator_precedence
public enum OperationPrecedence
{
MultiplicationDivisionRemainder = 1,
AdditionSubtraction = 2,
BitwiseShift = 3,
RelationalGreaterLessThan = 4,
RelationalEquals = 5,
LogicalAnd = 6,
LogicalOr = 7
}
public delegate int EvaluationFunction(int operand1, int operand2);
public string Syntax { get; }
public OperationPrecedence Precedence { get; }
public EvaluationFunction Function { get; }
public override string ToString()
{
return Syntax;
}
private OperationType(string syntax, OperationPrecedence precedence, EvaluationFunction function)
{
Syntax = syntax;
Precedence = precedence;
Function = function;
}
public static OperationType OperationAdd = new OperationType(
"+",
OperationPrecedence.AdditionSubtraction,
(operand1, operand2) => operand1 + operand2
);
public static OperationType OperationSubtract = new OperationType(
"-",
OperationPrecedence.AdditionSubtraction,
(operand1, operand2) => operand1 - operand2
);
public static OperationType OperationMultiply = new OperationType(
"*",
OperationPrecedence.MultiplicationDivisionRemainder,
(operand1, operand2) => operand1 * operand2
);
public static OperationType OperationDivide = new OperationType(
"/",
OperationPrecedence.MultiplicationDivisionRemainder,
(operand1, operand2) => operand1 / operand2
);
public static OperationType OperationRemainder = new OperationType(
"%",
OperationPrecedence.MultiplicationDivisionRemainder,
(operand1, operand2) => operand1 % operand2
);
public static OperationType OperationShiftLeft = new OperationType(
"<<",
OperationPrecedence.BitwiseShift,
(operand1, operand2) => operand1 << operand2
);
public static OperationType OperationShiftRight = new OperationType(
">>",
OperationPrecedence.BitwiseShift,
(operand1, operand2) => operand1 >> operand2
);
public static OperationType OperationGreaterThan = new OperationType(
">",
OperationPrecedence.RelationalGreaterLessThan,
(operand1, operand2) => operand1 > operand2 ? 1 : 0
);
public static OperationType OperationGreaterEqualsThan = new OperationType(
">=",
OperationPrecedence.RelationalGreaterLessThan,
(operand1, operand2) => operand1 >= operand2 ? 1 : 0
);
public static OperationType OperationLessThan = new OperationType(
"<",
OperationPrecedence.RelationalGreaterLessThan,
(operand1, operand2) => operand1 < operand2 ? 1 : 0
);
public static OperationType OperationLessEqualsThan = new OperationType(
"<=",
OperationPrecedence.RelationalGreaterLessThan,
(operand1, operand2) => operand1 <= operand2 ? 1 : 0
);
public static OperationType OperationEquals = new OperationType(
"==",
OperationPrecedence.RelationalEquals,
(operand1, operand2) => operand1 == operand2 ? 1 : 0
);
public static OperationType OperationNotEquals = new OperationType(
"!=",
OperationPrecedence.RelationalEquals,
(operand1, operand2) => operand1 != operand2 ? 1 : 0
);
public static OperationType OperationAnd = new OperationType(
"&&",
OperationPrecedence.LogicalAnd,
(operand1, operand2) => operand1 > 0 && operand2 > 0 ? 1 : 0
);
public static OperationType OperationOr = new OperationType(
"||",
OperationPrecedence.LogicalOr,
(operand1, operand2) => operand1 > 0 || operand2 > 0 ? 1 : 0
);
public static List<OperationType> Types => typeof(OperationType)
.GetFields(BindingFlags.Static | BindingFlags.Public)
.Select(info => info.GetValue(null))
.OfType<OperationType>()
.ToList();
}
}

View File

@@ -1,6 +1,14 @@
namespace ZoneCodeGenerator.Domain
using System;
using ZoneCodeGenerator.Domain.Evaluation;
namespace ZoneCodeGenerator.Domain
{
class ReferenceTypePointer : ReferenceType
{
public static IEvaluation DefaultCount = new OperandStatic(1);
public IEvaluation Count { get; set; } = DefaultCount;
public bool IsArray => !Count.IsStatic || Count.EvaluateNumeric() > 1;
}
}

View File

@@ -26,7 +26,8 @@ namespace ZoneCodeGenerator.Domain.StructureInformation
public List<StructureInformation> Usages { get; }
public List<MemberInformation> OrderedMembers { get; }
public bool NonEmbeddedReferenceExists { get; set; }
public bool PointerReferenceExists { get; set; }
public bool SinglePointerReferenceExists { get; set; }
public bool ArrayPointerReferenceExists { get; set; }
public bool ArrayReferenceExists { get; set; }
public bool HasNameMember => Type.Members.Any(variable => variable.Name.Equals("name", StringComparison.CurrentCultureIgnoreCase));
@@ -37,7 +38,7 @@ namespace ZoneCodeGenerator.Domain.StructureInformation
fastFileAlign = null;
Type = type;
NonEmbeddedReferenceExists = false;
PointerReferenceExists = false;
SinglePointerReferenceExists = false;
ArrayReferenceExists = false;
Usages = new List<StructureInformation>();
OrderedMembers = new List<MemberInformation>();