// Copyright Epic Games, Inc. All Rights Reserved.
using System;
using System.Linq;
namespace EpicGames.BuildGraph.Expressions
{
///
/// Abstract base class for expressions returning a string value
///
[BgType(typeof(BgEnumType<>))]
public abstract class BgEnum : BgExpr where TEnum : struct
{
///
public Type EnumType => typeof(TEnum);
///
/// Names of this enum
///
public static BgList Names { get; } = BgList.Create(Enum.GetNames(typeof(TEnum)).Select(x => (BgString)x));
///
/// Values of this enum
///
public static BgList Values { get; } = BgList.Create(((TEnum[])Enum.GetValues(typeof(TEnum))).Select(x => (BgInt)(int)(object)x));
///
/// Constructor
///
protected BgEnum(BgExprFlags flags)
: base(flags)
{
}
///
/// Implicit conversion from a regular enum type
///
public static implicit operator BgEnum(TEnum value)
{
return new BgEnumConstantExpr(value);
}
///
/// Explicit conversion from a string value
///
public static BgEnum Parse(BgString value)
{
return new BgEnumParseExpr(value);
}
///
public override BgString ToBgString() => new BgEnumToStringExpr(this);
}
///
/// Type traits for a
///
class BgEnumType : BgType> where TEnum : struct
{
///
public override BgEnum Constant(object value)
{
return new BgEnumConstantExpr((TEnum)value);
}
///
public override BgEnum Wrap(BgExpr expr)
{
throw new NotImplementedException();
}
}
#region Expression classes
class BgEnumConstantExpr : BgEnum where TEnum : struct
{
public TEnum Value { get; }
public BgEnumConstantExpr(TEnum value)
: base(BgExprFlags.NotInterned | BgExprFlags.Eager)
{
Value = value;
}
public override void Write(BgBytecodeWriter writer)
{
writer.WriteOpcode(BgOpcode.EnumConstant);
writer.WriteSignedInteger((int)(object)Value);
}
}
class BgEnumParseExpr : BgEnum where TEnum : struct
{
public BgString Value { get; }
public BgEnumParseExpr(BgString value)
: base(value.Flags & BgExprFlags.Eager)
{
Value = value;
}
public override void Write(BgBytecodeWriter writer)
{
writer.WriteOpcode(BgOpcode.EnumParse);
writer.WriteExpr(Value);
writer.WriteExpr(Names);
writer.WriteExpr(Values);
}
}
class BgEnumToStringExpr : BgString where TEnum : struct
{
public BgEnum Expr { get; }
public BgEnumToStringExpr(BgEnum expr)
: base(expr.Flags & BgExprFlags.Eager)
{
Expr = expr;
}
public override void Write(BgBytecodeWriter writer)
{
writer.WriteOpcode(BgOpcode.EnumToString);
writer.WriteExpr(Expr);
writer.WriteExpr(BgEnum.Names);
writer.WriteExpr(BgEnum.Values);
}
}
class BgEnumWrappedExpr : BgEnum where TEnum : struct
{
public BgExpr Expr { get; }
public BgEnumWrappedExpr(BgExpr expr)
: base(expr.Flags)
{
Expr = expr;
}
public override void Write(BgBytecodeWriter writer)
{
Expr.Write(writer);
}
}
#endregion
}