mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-19 15:52:53 +00:00
ZoneCodeGenerator: Add Evaluation as basis for specifying conditions and counts
This commit is contained in:
parent
61eb92588e
commit
785e2c9bfb
15
src/ZoneCodeGenerator/Domain/Evaluation/IEvaluation.cs
Normal file
15
src/ZoneCodeGenerator/Domain/Evaluation/IEvaluation.cs
Normal 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();
|
||||
}
|
||||
}
|
17
src/ZoneCodeGenerator/Domain/Evaluation/OperandDynamic.cs
Normal file
17
src/ZoneCodeGenerator/Domain/Evaluation/OperandDynamic.cs
Normal 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.");
|
||||
}
|
||||
}
|
||||
}
|
24
src/ZoneCodeGenerator/Domain/Evaluation/OperandStatic.cs
Normal file
24
src/ZoneCodeGenerator/Domain/Evaluation/OperandStatic.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
29
src/ZoneCodeGenerator/Domain/Evaluation/Operation.cs
Normal file
29
src/ZoneCodeGenerator/Domain/Evaluation/Operation.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
138
src/ZoneCodeGenerator/Domain/Evaluation/OperationType.cs
Normal file
138
src/ZoneCodeGenerator/Domain/Evaluation/OperationType.cs
Normal 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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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>();
|
||||
|
@ -9,21 +9,21 @@ LoaderClassName(asset) ::= "Loader_$asset.Type.Name$"
|
||||
|
||||
HeaderConstructor(context) ::= "$LoaderClassName(context.Asset)$(IZoneScriptStringProvider* scriptStringProvider, Zone* zone, IZoneInputStream* stream);"
|
||||
|
||||
HeaderPtrLoadMethodDeclaration(structure) ::= "void LoadPtr_$structure.Type.Name$($structure.Type.FullName$** pPtr);"
|
||||
HeaderArrayLoadMethodDeclaration(structure) ::= "void LoadArray_$structure.Type.Name$($structure.Type.FullName$** pArray, size_t count, bool atStreamStart);"
|
||||
HeaderSinglePtrLoadMethodDeclaration(structure) ::= "void LoadPtr_$structure.Type.Name$($structure.Type.FullName$** pPtr);"
|
||||
HeaderArrayPtrLoadMethodDeclaration(structure) ::= "void LoadArray_$structure.Type.Name$($structure.Type.FullName$** pArray, size_t count, bool atStreamStart);"
|
||||
HeaderLoadMethodDeclaration(structure) ::= "void Load_$structure.Type.Name$($structure.Type.FullName$* p$structure.Type.Name$, bool atStreamStart);"
|
||||
|
||||
HeaderGetNameMethodDeclaration(asset) ::= "static std::string GetAssetName($asset.Type.FullName$* p$asset.Type.Name$);"
|
||||
HeaderAssetLoadMethodDeclaration(asset) ::= "void LoadAsset_$asset.Type.Name$($asset.Type.FullName$** pPtr);"
|
||||
|
||||
HeaderDeclaration(structure) ::= <%
|
||||
$if(structure.PointerReferenceExists)$
|
||||
$HeaderPtrLoadMethodDeclaration(structure)$
|
||||
$if(structure.SinglePointerReferenceExists)$
|
||||
$HeaderSinglePtrLoadMethodDeclaration(structure)$
|
||||
$\n$
|
||||
$endif$
|
||||
|
||||
$if(structure.ArrayReferenceExists)$
|
||||
$HeaderArrayLoadMethodDeclaration(structure)$
|
||||
$if(structure.ArrayPointerReferenceExists)$
|
||||
$HeaderArrayPtrLoadMethodDeclaration(structure)$
|
||||
$\n$
|
||||
$endif$
|
||||
|
||||
@ -60,7 +60,7 @@ namespace $context.Game$
|
||||
public:
|
||||
$HeaderConstructor(context)$
|
||||
|
||||
$HeaderPtrLoadMethodDeclaration(context.Asset)$
|
||||
$HeaderSinglePtrLoadMethodDeclaration(context.Asset)$
|
||||
$HeaderGetNameMethodDeclaration(context.Asset)$
|
||||
};
|
||||
}
|
||||
@ -91,7 +91,7 @@ void $LoaderClassName(context.Asset)$::Load_$structure.Type.Name$($structure.Typ
|
||||
}
|
||||
>>
|
||||
|
||||
LoadPtrMethod(structure, context) ::= <<
|
||||
LoadSinglePtrMethod(structure, context) ::= <<
|
||||
void $LoaderClassName(context.Asset)$::LoadPtr_$structure.Type.Name$($structure.Type.FullName$** pPtr)
|
||||
{
|
||||
assert(pPtr != nullptr);
|
||||
@ -141,7 +141,7 @@ void $LoaderClassName(context.Asset)$::LoadPtr_$structure.Type.Name$($structure.
|
||||
}
|
||||
>>
|
||||
|
||||
LoadArrayMethod(structure, context) ::= <<
|
||||
LoadArrayPtrMethod(structure, context) ::= <<
|
||||
void $LoaderClassName(context.Asset)$::LoadArray_$structure.Type.Name$($structure.Type.FullName$** pArray, const size_t count, const bool atStreamStart)
|
||||
{
|
||||
assert(pArray != nullptr);
|
||||
@ -161,12 +161,12 @@ $if(structure.NonEmbeddedReferenceExists)$
|
||||
$LoadMethod(structure, context)$
|
||||
|
||||
$endif$
|
||||
$if(structure.PointerReferenceExists)$
|
||||
$LoadPtrMethod(structure, context)$
|
||||
$if(structure.SinglePointerReferenceExists)$
|
||||
$LoadSinglePtrMethod(structure, context)$
|
||||
|
||||
$endif$
|
||||
$if(structure.ArrayReferenceExists)$
|
||||
$LoadArrayMethod(structure, context)$
|
||||
$if(structure.ArrayPointerReferenceExists)$
|
||||
$LoadArrayPtrMethod(structure, context)$
|
||||
|
||||
$endif$
|
||||
>>
|
||||
@ -220,7 +220,7 @@ $LoadMethod(context.Asset, context)$
|
||||
|
||||
$LoadAssetMethod(context.Asset, context)$
|
||||
|
||||
$LoadPtrMethod(context.Asset, context)$
|
||||
$LoadSinglePtrMethod(context.Asset, context)$
|
||||
|
||||
$GetNameMethod(context)$
|
||||
>>
|
@ -23,11 +23,14 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.PostProcessor
|
||||
if (IsNonEmbeddedReference(memberInformation.Member))
|
||||
memberInformation.StructureType.NonEmbeddedReferenceExists = true;
|
||||
|
||||
if (IsPointerReference(memberInformation.Member))
|
||||
memberInformation.StructureType.PointerReferenceExists = true;
|
||||
if (IsSinglePointerReference(memberInformation.Member))
|
||||
memberInformation.StructureType.SinglePointerReferenceExists = true;
|
||||
|
||||
if (IsArrayPointerReference(memberInformation.Member))
|
||||
memberInformation.StructureType.ArrayPointerReferenceExists = true;
|
||||
|
||||
if (IsArrayReference(memberInformation.Member))
|
||||
memberInformation.StructureType.PointerReferenceExists = true;
|
||||
memberInformation.StructureType.ArrayReferenceExists = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,10 +42,18 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.PostProcessor
|
||||
return var.VariableType.References.Any();
|
||||
}
|
||||
|
||||
private static bool IsPointerReference(Variable var)
|
||||
private static bool IsSinglePointerReference(Variable var)
|
||||
{
|
||||
return var.VariableType.References.Any()
|
||||
&& var.VariableType.References.Last() is ReferenceTypePointer;
|
||||
&& var.VariableType.References.Last() is ReferenceTypePointer pointerReference
|
||||
&& !pointerReference.IsArray;
|
||||
}
|
||||
|
||||
private static bool IsArrayPointerReference(Variable var)
|
||||
{
|
||||
return var.VariableType.References.Any()
|
||||
&& var.VariableType.References.Last() is ReferenceTypePointer pointerReference
|
||||
&& pointerReference.IsArray;
|
||||
}
|
||||
|
||||
private static bool IsArrayReference(Variable var)
|
||||
|
@ -63,6 +63,11 @@
|
||||
<Compile Include="Domain\DataTypeUnion.cs" />
|
||||
<Compile Include="Domain\DataTypeWithMembers.cs" />
|
||||
<Compile Include="Domain\EnumMember.cs" />
|
||||
<Compile Include="Domain\Evaluation\IEvaluation.cs" />
|
||||
<Compile Include="Domain\Evaluation\OperandDynamic.cs" />
|
||||
<Compile Include="Domain\Evaluation\OperandStatic.cs" />
|
||||
<Compile Include="Domain\Evaluation\Operation.cs" />
|
||||
<Compile Include="Domain\Evaluation\OperationType.cs" />
|
||||
<Compile Include="Domain\FastFileStructure\FastFileBlock.cs" />
|
||||
<Compile Include="Domain\ForwardDeclaration.cs" />
|
||||
<Compile Include="Domain\Namespace.cs" />
|
||||
@ -169,5 +174,6 @@
|
||||
<EmbeddedResource Include="Generating\Templates\AssetStructTests.stg" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
Loading…
x
Reference in New Issue
Block a user