mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 00:02:55 +00:00
135 lines
3.9 KiB
C#
135 lines
3.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using ZoneCodeGenerator.Domain;
|
|
using ZoneCodeGenerator.Parsing.C_Header.Tests;
|
|
using ZoneCodeGenerator.Parsing.Testing;
|
|
using ZoneCodeGenerator.Utils;
|
|
|
|
namespace ZoneCodeGenerator.Parsing.C_Header.Blocks
|
|
{
|
|
class BlockUnion : Block, INameAssignable, IVariableHolder, IVariableBlock
|
|
{
|
|
private readonly ITokenTest<IHeaderParserState>[] tests =
|
|
{
|
|
new TestStruct(),
|
|
new TestEnum(),
|
|
new TestUnion(),
|
|
new TestVariable(),
|
|
new TestCloseBlock(true)
|
|
};
|
|
|
|
public string Name { get; }
|
|
public bool IsAnonymous { get; }
|
|
|
|
public string AssignedName { get; private set; }
|
|
public string Namespace { get; private set; }
|
|
public bool IsTypedef { get; }
|
|
public int? CustomAlignment { get; set; }
|
|
public int Pack { get; private set; }
|
|
public List<Variable> Variables { get; }
|
|
|
|
private DataTypeUnion union;
|
|
private DataTypeTypedef typedef;
|
|
|
|
public BlockUnion(IHeaderParserState headerParserState, string name, bool isTypedef) : base(headerParserState, BlockType.Union)
|
|
{
|
|
if (!string.IsNullOrEmpty(name))
|
|
{
|
|
Name = name;
|
|
IsAnonymous = false;
|
|
}
|
|
else
|
|
{
|
|
Name = RandomName.GenerateName();
|
|
IsAnonymous = true;
|
|
}
|
|
|
|
IsTypedef = isTypedef;
|
|
Variables = new List<Variable>();
|
|
CustomAlignment = null;
|
|
AssignedName = "";
|
|
union = null;
|
|
typedef = null;
|
|
}
|
|
|
|
public override IEnumerable<ITokenTest<IHeaderParserState>> GetAvailableTests()
|
|
{
|
|
return tests;
|
|
}
|
|
|
|
public override void OnOpen()
|
|
{
|
|
Namespace = State.CurrentNamespace.ToString();
|
|
Pack = State.CurrentPack;
|
|
|
|
State.CurrentNamespace.Push(Name);
|
|
|
|
State.AddForwardDeclaration(new ForwardDeclaration(Namespace, Name, DataTypeType.Union));
|
|
}
|
|
|
|
public override void OnClose()
|
|
{
|
|
var poppedNamespaceName = State.CurrentNamespace.Pop();
|
|
|
|
if (!Name.Equals(poppedNamespaceName))
|
|
throw new Exception($"Popped namespace '{poppedNamespaceName}' does not equal name of union block '{Name}'");
|
|
|
|
union = new DataTypeUnion(Namespace, Name, Pack)
|
|
{
|
|
AlignmentOverride = CustomAlignment,
|
|
IsAnonymous = IsAnonymous
|
|
};
|
|
|
|
union.Members.AddRange(Variables);
|
|
|
|
State.AddDataType(union);
|
|
|
|
if (IsTypedef)
|
|
{
|
|
var typeDeclaration = new TypeDeclaration(union, new List<ReferenceType>());
|
|
typedef = new DataTypeTypedef(Namespace, AssignedName, typeDeclaration);
|
|
|
|
State.AddDataType(typedef);
|
|
}
|
|
}
|
|
|
|
public override void OnChildBlockClose(Block childBlock)
|
|
{
|
|
if (childBlock is IVariableBlock variableBlock)
|
|
{
|
|
AddVariable(variableBlock.GetDefinedVariable());
|
|
}
|
|
}
|
|
|
|
public void AssignName(string nameAssignment)
|
|
{
|
|
AssignedName = nameAssignment;
|
|
}
|
|
|
|
public void AddVariable(Variable variable)
|
|
{
|
|
Variables.Add(variable);
|
|
}
|
|
|
|
public Variable GetDefinedVariable()
|
|
{
|
|
var name = "";
|
|
DataType dataType = union;
|
|
|
|
if (!IsTypedef)
|
|
name = AssignedName;
|
|
else
|
|
dataType = typedef;
|
|
|
|
var typeDeclaration = new TypeDeclaration(dataType, new List<ReferenceType>());
|
|
return new Variable(name, typeDeclaration);
|
|
}
|
|
|
|
public void Inherit(DataTypeUnion parent)
|
|
{
|
|
foreach(var variable in parent.Members)
|
|
AddVariable(variable);
|
|
}
|
|
}
|
|
}
|