LiteralInteger.cs
1 using System; 2 using System.IO; 3 4 namespace Spv.Generator 5 { 6 public class LiteralInteger : IOperand, IEquatable<LiteralInteger> 7 { 8 [ThreadStatic] 9 private static GeneratorPool<LiteralInteger> _pool; 10 11 internal static void RegisterPool(GeneratorPool<LiteralInteger> pool) 12 { 13 _pool = pool; 14 } 15 16 internal static void UnregisterPool() 17 { 18 _pool = null; 19 } 20 21 public OperandType Type => OperandType.Number; 22 23 private enum IntegerType 24 { 25 UInt32, 26 Int32, 27 UInt64, 28 Int64, 29 Float32, 30 Float64, 31 } 32 33 private IntegerType _integerType; 34 private ulong _data; 35 36 public ushort WordCount { get; private set; } 37 38 public LiteralInteger() { } 39 40 private static LiteralInteger New() 41 { 42 return _pool.Allocate(); 43 } 44 45 private LiteralInteger Set(ulong data, IntegerType integerType, ushort wordCount) 46 { 47 _data = data; 48 _integerType = integerType; 49 50 WordCount = wordCount; 51 52 return this; 53 } 54 55 public static implicit operator LiteralInteger(int value) => New().Set((ulong)value, IntegerType.Int32, 1); 56 public static implicit operator LiteralInteger(uint value) => New().Set(value, IntegerType.UInt32, 1); 57 public static implicit operator LiteralInteger(long value) => New().Set((ulong)value, IntegerType.Int64, 2); 58 public static implicit operator LiteralInteger(ulong value) => New().Set(value, IntegerType.UInt64, 2); 59 public static implicit operator LiteralInteger(float value) => New().Set(BitConverter.SingleToUInt32Bits(value), IntegerType.Float32, 1); 60 public static implicit operator LiteralInteger(double value) => New().Set(BitConverter.DoubleToUInt64Bits(value), IntegerType.Float64, 2); 61 public static implicit operator LiteralInteger(Enum value) => New().Set((ulong)(int)(object)value, IntegerType.Int32, 1); 62 63 // NOTE: this is not in the standard, but this is some syntax sugar useful in some instructions (TypeInt ect) 64 public static implicit operator LiteralInteger(bool value) => New().Set(Convert.ToUInt64(value), IntegerType.Int32, 1); 65 66 public static LiteralInteger CreateForEnum<T>(T value) where T : Enum 67 { 68 return value; 69 } 70 71 public void WriteOperand(BinaryWriter writer) 72 { 73 if (WordCount == 1) 74 { 75 writer.Write((uint)_data); 76 } 77 else 78 { 79 writer.Write(_data); 80 } 81 } 82 83 public override bool Equals(object obj) 84 { 85 return obj is LiteralInteger literalInteger && Equals(literalInteger); 86 } 87 88 public bool Equals(LiteralInteger cmpObj) 89 { 90 return Type == cmpObj.Type && _integerType == cmpObj._integerType && _data == cmpObj._data; 91 } 92 93 public override int GetHashCode() 94 { 95 return DeterministicHashCode.Combine(Type, _data); 96 } 97 98 public bool Equals(IOperand obj) 99 { 100 return obj is LiteralInteger literalInteger && Equals(literalInteger); 101 } 102 103 public override string ToString() => $"{_integerType} {_data}"; 104 } 105 }