CLanguage by praeclarum

<PackageReference Include="CLanguage" Version="0.18.48" />

.NET API 203,776 bytes

 ConstantExpression

using CLanguage.Compiler; using CLanguage.Interpreter; using CLanguage.Types; using System; using System.Runtime.CompilerServices; namespace CLanguage.Syntax { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] public class ConstantExpression : Expression { public static readonly ConstantExpression Zero = new ConstantExpression(0); public static readonly ConstantExpression One = new ConstantExpression(1); public static readonly ConstantExpression NegativeOne = new ConstantExpression(-1); public static readonly ConstantExpression True = new ConstantExpression(true); public static readonly ConstantExpression False = new ConstantExpression(false); public object Value { get; set; } public CType ConstantType { get; set; } public ConstantExpression(object val, CType type) : this(val) { ConstantType = type; } public ConstantExpression(object val) { Value = val; if (Value is string) ConstantType = CPointerType.PointerToConstChar; else if (Value is bool) { ConstantType = CBasicType.Bool; } else if (Value is byte) { ConstantType = CBasicType.UnsignedChar; } else if (Value is char) { ConstantType = CBasicType.SignedChar; } else if (Value is ushort) { ConstantType = CBasicType.UnsignedShortInt; } else if (Value is short) { ConstantType = CBasicType.SignedShortInt; } else if (Value is uint) { ConstantType = CBasicType.UnsignedInt; } else if (Value is int) { ConstantType = CBasicType.SignedInt; } else if (Value is ulong) { ConstantType = CBasicType.UnsignedLongInt; } else if (Value is long) { ConstantType = CBasicType.SignedLongInt; } else if (Value is float) { ConstantType = CBasicType.Float; } else if (Value is double) { ConstantType = CBasicType.Double; } else { ConstantType = CBasicType.SignedInt; } } public override CType GetEvaluatedCType(EmitContext ec) { return ConstantType; } protected override void DoEmit(EmitContext ec) { Value x = EvalConstant(ec); ec.Emit(OpCode.LoadConstant, x); } public override string ToString() { return Value.ToString(); } public override Value EvalConstant(EmitContext ec) { CIntType cIntType = ConstantType as CIntType; if (cIntType != null) { int byteSize = cIntType.GetByteSize(ec); if (cIntType.Signedness != Signedness.Signed) { switch (byteSize) { case 1: return (byte)Convert.ToInt64(Value); case 2: return (ushort)Convert.ToInt64(Value); case 4: return (uint)Convert.ToInt64(Value); case 8: return Convert.ToUInt64(Value); default: throw new NotSupportedException("Unsigned integral constants with type '" + ConstantType?.ToString() + "'"); } } switch (byteSize) { case 1: return (sbyte)Convert.ToInt64(Value); case 2: return (short)Convert.ToInt64(Value); case 4: return (int)Convert.ToInt64(Value); case 8: return Convert.ToInt64(Value); default: throw new NotSupportedException("Signed integral constants with type '" + ConstantType?.ToString() + "'"); } } if (ConstantType is CBoolType) return (byte)(((bool)Value) ? 1 : 0); CFloatType cFloatType = ConstantType as CFloatType; if (cFloatType != null) { if (cFloatType.Bits != 64) return Convert.ToSingle(Value); return Convert.ToDouble(Value); } string text = Value as string; if (text != null) return ec.GetConstantMemory(text); throw new NotSupportedException("Non-basic constants with type '" + ConstantType?.ToString() + "'"); } } }