Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
NumericConvertInstruction.cs
Go to the documentation of this file.
2
4
5internal abstract class NumericConvertInstruction : Instruction
6{
7 internal sealed class Unchecked : NumericConvertInstruction
8 {
9 public override string InstructionName => "UncheckedConvert";
10
11 public Unchecked(TypeCode from, TypeCode to, bool isLiftedToNull)
12 : base(from, to, isLiftedToNull)
13 {
14 }
15
16 protected override object Convert(object obj)
17 {
18 return _from switch
19 {
20 TypeCode.Boolean => ConvertInt32(((bool)obj) ? 1 : 0),
21 TypeCode.Byte => ConvertInt32((byte)obj),
22 TypeCode.SByte => ConvertInt32((sbyte)obj),
23 TypeCode.Int16 => ConvertInt32((short)obj),
24 TypeCode.Char => ConvertInt32((char)obj),
25 TypeCode.Int32 => ConvertInt32((int)obj),
26 TypeCode.Int64 => ConvertInt64((long)obj),
27 TypeCode.UInt16 => ConvertInt32((ushort)obj),
28 TypeCode.UInt32 => ConvertInt64((uint)obj),
29 TypeCode.UInt64 => ConvertUInt64((ulong)obj),
30 TypeCode.Single => ConvertDouble((float)obj),
31 TypeCode.Double => ConvertDouble((double)obj),
32 _ => throw ContractUtils.Unreachable,
33 };
34 }
35
36 private object ConvertInt32(int obj)
37 {
38 return _to switch
39 {
40 TypeCode.Byte => (byte)obj,
41 TypeCode.SByte => (sbyte)obj,
42 TypeCode.Int16 => (short)obj,
43 TypeCode.Char => (char)obj,
44 TypeCode.Int32 => obj,
45 TypeCode.Int64 => (long)obj,
46 TypeCode.UInt16 => (ushort)obj,
47 TypeCode.UInt32 => (uint)obj,
48 TypeCode.UInt64 => (ulong)obj,
49 TypeCode.Single => (float)obj,
50 TypeCode.Double => (double)obj,
51 TypeCode.Decimal => (decimal)obj,
52 TypeCode.Boolean => obj != 0,
53 _ => throw ContractUtils.Unreachable,
54 };
55 }
56
57 private object ConvertInt64(long obj)
58 {
59 return _to switch
60 {
61 TypeCode.Byte => (byte)obj,
62 TypeCode.SByte => (sbyte)obj,
63 TypeCode.Int16 => (short)obj,
64 TypeCode.Char => (char)obj,
65 TypeCode.Int32 => (int)obj,
66 TypeCode.Int64 => obj,
67 TypeCode.UInt16 => (ushort)obj,
68 TypeCode.UInt32 => (uint)obj,
69 TypeCode.UInt64 => (ulong)obj,
70 TypeCode.Single => (float)obj,
71 TypeCode.Double => (double)obj,
72 TypeCode.Decimal => (decimal)obj,
73 _ => throw ContractUtils.Unreachable,
74 };
75 }
76
77 private object ConvertUInt64(ulong obj)
78 {
79 return _to switch
80 {
81 TypeCode.Byte => (byte)obj,
82 TypeCode.SByte => (sbyte)obj,
83 TypeCode.Int16 => (short)obj,
84 TypeCode.Char => (char)obj,
85 TypeCode.Int32 => (int)obj,
86 TypeCode.Int64 => (long)obj,
87 TypeCode.UInt16 => (ushort)obj,
88 TypeCode.UInt32 => (uint)obj,
89 TypeCode.UInt64 => obj,
90 TypeCode.Single => (float)obj,
91 TypeCode.Double => (double)obj,
92 TypeCode.Decimal => (decimal)obj,
93 _ => throw ContractUtils.Unreachable,
94 };
95 }
96
97 private object ConvertDouble(double obj)
98 {
99 return _to switch
100 {
101 TypeCode.Byte => (byte)obj,
102 TypeCode.SByte => (sbyte)obj,
103 TypeCode.Int16 => (short)obj,
104 TypeCode.Char => (char)obj,
105 TypeCode.Int32 => (int)obj,
106 TypeCode.Int64 => (long)obj,
107 TypeCode.UInt16 => (ushort)obj,
108 TypeCode.UInt32 => (uint)obj,
109 TypeCode.UInt64 => (ulong)obj,
110 TypeCode.Single => (float)obj,
111 TypeCode.Double => obj,
112 TypeCode.Decimal => (decimal)obj,
113 _ => throw ContractUtils.Unreachable,
114 };
115 }
116 }
117
118 internal sealed class Checked : NumericConvertInstruction
119 {
120 public override string InstructionName => "CheckedConvert";
121
122 public Checked(TypeCode from, TypeCode to, bool isLiftedToNull)
123 : base(from, to, isLiftedToNull)
124 {
125 }
126
127 protected override object Convert(object obj)
128 {
129 return _from switch
130 {
131 TypeCode.Boolean => ConvertInt32(((bool)obj) ? 1 : 0),
132 TypeCode.Byte => ConvertInt32((byte)obj),
133 TypeCode.SByte => ConvertInt32((sbyte)obj),
134 TypeCode.Int16 => ConvertInt32((short)obj),
135 TypeCode.Char => ConvertInt32((char)obj),
136 TypeCode.Int32 => ConvertInt32((int)obj),
137 TypeCode.Int64 => ConvertInt64((long)obj),
138 TypeCode.UInt16 => ConvertInt32((ushort)obj),
139 TypeCode.UInt32 => ConvertInt64((uint)obj),
140 TypeCode.UInt64 => ConvertUInt64((ulong)obj),
141 TypeCode.Single => ConvertDouble((float)obj),
142 TypeCode.Double => ConvertDouble((double)obj),
143 _ => throw ContractUtils.Unreachable,
144 };
145 }
146
147 private object ConvertInt32(int obj)
148 {
149 checked
150 {
151 return _to switch
152 {
153 TypeCode.Byte => (byte)obj,
154 TypeCode.SByte => (sbyte)obj,
155 TypeCode.Int16 => (short)obj,
156 TypeCode.Char => unchecked((char)checked((ushort)obj)),
157 TypeCode.Int32 => obj,
158 TypeCode.Int64 => unchecked((long)obj),
159 TypeCode.UInt16 => (ushort)obj,
160 TypeCode.UInt32 => (uint)obj,
161 TypeCode.UInt64 => (ulong)obj,
162 TypeCode.Single => (float)obj,
163 TypeCode.Double => (double)obj,
164 TypeCode.Decimal => (decimal)obj,
165 TypeCode.Boolean => obj != 0,
166 _ => throw ContractUtils.Unreachable,
167 };
168 }
169 }
170
171 private object ConvertInt64(long obj)
172 {
173 checked
174 {
175 return _to switch
176 {
177 TypeCode.Byte => (byte)obj,
178 TypeCode.SByte => (sbyte)obj,
179 TypeCode.Int16 => (short)obj,
180 TypeCode.Char => unchecked((char)checked((ushort)obj)),
181 TypeCode.Int32 => (int)obj,
182 TypeCode.Int64 => obj,
183 TypeCode.UInt16 => (ushort)obj,
184 TypeCode.UInt32 => (uint)obj,
185 TypeCode.UInt64 => (ulong)obj,
186 TypeCode.Single => (float)obj,
187 TypeCode.Double => (double)obj,
188 TypeCode.Decimal => (decimal)obj,
189 _ => throw ContractUtils.Unreachable,
190 };
191 }
192 }
193
194 private object ConvertUInt64(ulong obj)
195 {
196 checked
197 {
198 return _to switch
199 {
200 TypeCode.Byte => (byte)obj,
201 TypeCode.SByte => (sbyte)obj,
202 TypeCode.Int16 => (short)obj,
203 TypeCode.Char => unchecked((char)checked((ushort)obj)),
204 TypeCode.Int32 => (int)obj,
205 TypeCode.Int64 => (long)obj,
206 TypeCode.UInt16 => (ushort)obj,
207 TypeCode.UInt32 => (uint)obj,
208 TypeCode.UInt64 => obj,
209 TypeCode.Single => (float)obj,
210 TypeCode.Double => (double)obj,
211 TypeCode.Decimal => (decimal)obj,
212 _ => throw ContractUtils.Unreachable,
213 };
214 }
215 }
216
217 private object ConvertDouble(double obj)
218 {
219 checked
220 {
221 return _to switch
222 {
223 TypeCode.Byte => (byte)obj,
224 TypeCode.SByte => (sbyte)obj,
225 TypeCode.Int16 => (short)obj,
226 TypeCode.Char => unchecked((char)checked((ushort)obj)),
227 TypeCode.Int32 => (int)obj,
228 TypeCode.Int64 => (long)obj,
229 TypeCode.UInt16 => (ushort)obj,
230 TypeCode.UInt32 => (uint)obj,
231 TypeCode.UInt64 => (ulong)obj,
232 TypeCode.Single => (float)obj,
233 TypeCode.Double => obj,
234 TypeCode.Decimal => (decimal)obj,
235 _ => throw ContractUtils.Unreachable,
236 };
237 }
238 }
239 }
240
242 {
243 public override string InstructionName => "ConvertToUnderlying";
244
245 public ToUnderlying(TypeCode to, bool isLiftedToNull)
246 : base(to, to, isLiftedToNull)
247 {
248 }
249
250 protected override object Convert(object obj)
251 {
252 return _to switch
253 {
254 TypeCode.Boolean => (bool)obj,
255 TypeCode.Byte => (byte)obj,
256 TypeCode.SByte => (sbyte)obj,
257 TypeCode.Int16 => (short)obj,
258 TypeCode.Char => (char)obj,
259 TypeCode.Int32 => (int)obj,
260 TypeCode.Int64 => (long)obj,
261 TypeCode.UInt16 => (ushort)obj,
262 TypeCode.UInt32 => (uint)obj,
263 TypeCode.UInt64 => (ulong)obj,
264 _ => throw ContractUtils.Unreachable,
265 };
266 }
267 }
268
269 internal readonly TypeCode _from;
270
271 internal readonly TypeCode _to;
272
273 private readonly bool _isLiftedToNull;
274
275 public override string InstructionName => "NumericConvert";
276
277 public override int ConsumedStack => 1;
278
279 public override int ProducedStack => 1;
280
281 protected NumericConvertInstruction(TypeCode from, TypeCode to, bool isLiftedToNull)
282 {
283 _from = from;
284 _to = to;
285 _isLiftedToNull = isLiftedToNull;
286 }
287
288 public sealed override int Run(InterpretedFrame frame)
289 {
290 object obj = frame.Pop();
291 object value;
292 if (obj == null)
293 {
294 if (!_isLiftedToNull)
295 {
296 return ((int?)obj).Value;
297 }
298 value = null;
299 }
300 else
301 {
302 value = Convert(obj);
303 }
304 frame.Push(value);
305 return 1;
306 }
307
308 protected abstract object Convert(object obj);
309
310 public override string ToString()
311 {
312 return InstructionName + "(" + _from.ToString() + "->" + _to.ToString() + ")";
313 }
314}
NumericConvertInstruction(TypeCode from, TypeCode to, bool isLiftedToNull)
TypeCode
Definition TypeCode.cs:4