// 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 }