-
Notifications
You must be signed in to change notification settings - Fork 0
/
Val.cs
471 lines (398 loc) · 18.1 KB
/
Val.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
// MIT License
//
// Copyright (c) 2021 Pixel Precision, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
namespace PxPre.Datum
{
public abstract class Val
{
/// <summary>
/// Intrinsic datatypes
/// </summary>
public enum Type
{
/// <summary>
/// The datatype for a null variable.
/// </summary>
None,
/// <summary>
/// The datatype is a bool. GetBool() and SetBool() should be used
/// to access its values.
/// </summary>
Bool,
/// <summary>
/// The datatype is an enum. GetInt() or GetString() should be used to
/// get the value. SetInt() or SetSTring() should be used to set the value.
/// </summary>
Enum,
/// <summary>
/// The datatype is an int. GetInt() and SetInt() should be used
/// to access its values.
/// </summary>
Int,
/// <summary>
/// The datatype is an unsigned int. GetUInt() and SetUInt() should be used
/// to access its values.
/// </summary>
UInt,
/// <summary>
/// The datatype is a float. GetFloat() and SetFloat() should be used
/// to access its values.
/// </summary>
Float,
/// <summary>
/// The datatype is a 64 bit int. GetInt64() and SetInt64() should be used
/// to access its values.
/// </summary>
Int64,
/// <summary>
/// The datatype is a 64 bit usngiend int. GetUInt64() and SetUInt64() should be used
/// to access its values.
/// </summary>
UInt64,
/// <summary>
/// The datatype is a double precision float. GetFloat64 and SetFloat64() should be used
/// to access it values.
/// </summary>
Float64,
/// <summary>
/// The datatype is a string. GetString() and SetString() should be used
/// to access its values.
/// </summary>
String,
Array,
StringMap,
ObjectMap,
Executable,
Context,
Custom,
Scope,
Relay
}
/// <summary>
/// When a Val is evaluated, where did the result come from?
/// </summary>
public enum EvalTy
{
/// <summary>
/// The Val sent itself back
/// </summary>
Relay,
/// <summary>
/// The Val came from a return statement
/// </summary>
Return,
/// <summary>
/// The Val came from a yield statement
/// </summary>
Yield,
/// <summary>
/// The Val performed a misc transformation (all others that don't fit
/// into any other EvalTy value).
/// </summary>
Transform,
/// <summary>
/// The Val came from a continue statement
/// </summary>
Continue,
/// <summary>
/// The Val came from a break statement
/// </summary>
Break
}
public IPrototype prototype = null;
public abstract Type ty {get; }
/// <summary>
/// The type the value should be treated as.
///
/// The variable can also be seen as shorthand for:
/// "this datatype is a wrapper for the datatype of -"
/// </summary>
public virtual Type wrapType { get => this.ty; }
/// <summary>
/// Get the bool value. It's either a bool value from
/// a bool Val, or the object's value converted to a bool.
/// </summary>
/// <returns>The bool value of the object.</returns>
public abstract bool GetBool();
/// <summary>
/// Get the int value. It's either an int value from
/// an int Val, or the object's value converted to an int.
/// </summary>
/// <returns>The int value of the object.</returns>
public abstract int GetInt();
/// <summary>
/// Get the unsigned int value. It's either an unsigned int value from
/// an int Val, or the object's value converted to an unsigned int.
/// </summary>
/// <returns>The int value of the object.</returns>
public abstract uint GetUInt();
/// <summary>
/// Get long int value. It's either a long value from
/// a Int64 Val, or the object's value converted to an long.
/// </summary>
/// <returns>The long value of the object.</returns>
public abstract long GetInt64();
/// <summary>
/// Get unsigned long value. It's either an unsigned long value from
/// a UInt64 Val, or the object's value converted to an unsigned long.
/// </summary>
/// <returns>The long value of the object.</returns>
public abstract ulong GetUInt64();
/// <summary>
/// Get the float value. It's either a float value from
/// a float Val, or the object's value converted to a float.
/// </summary>
/// <returns>The float value of the object.</returns>
public abstract float GetFloat();
/// <summary>
/// Get the double value. It's either a double value from
/// a Float64 Val, or the object's value converted to a double.
/// </summary>
/// <returns>The float value of the object.</returns>
public abstract double GetFloat64();
/// <summary>
/// Get the string value. It's either a string value from
/// a string Val, or the object's value converted to a string.
/// </summary>
/// <returns>The string value of the object.</returns>
public abstract string GetString();
/// <summary>
/// Set the bool value of the object - or the equivalent of the
/// specified bool value converted to its native datatype.
/// </summary>
/// <param name="v">The bool value to set the object to.</param>
/// <returns>True if the value, or an equivalent value was successfully set. Else, false</returns>
public abstract bool SetBool(bool v);
/// <summary>
/// Set the int value of the object - or the equivalent of the
/// specified int value converted to its native datatype.
/// </summary>
/// <param name="v">The int value to set the object to.</param>
/// <returns>True if the value, or an equivalent value was successfully set. Else, false</returns>
public abstract bool SetInt(int v);
/// <summary>
/// Set the unsigned int value of the object - or the equivalent of the
/// specified int value converted to its native datatype.
/// </summary>
/// <param name="v">The unsigned int value to set the object to.</param>
/// <returns>True if the value, or an equivalent value was successfully set. Else, false</returns>
public abstract bool SetUInt(uint v);
/// <summary>
/// Set the long value of the object - or the equivalent of the
/// specified long value converted to its native datatype.
/// </summary>
/// <param name="v">The long value to set the object to.</param>
/// <returns>True if the value, or an equivalent value was successfully set. Else, false</returns>
public abstract bool SetInt64(long v);
/// <summary>
/// Set the unsigned long value of the object - or the equivalent of the
/// specified unsigned long value converted to its native datatype.
/// </summary>
/// <param name="v">The unsigned long value to set the object to.</param>
/// <returns>True if the value, or an equivalent value was successfully set. Else, false</returns>
public abstract bool SetUInt64(ulong v);
/// <summary>
/// Set the float value of the object - or the equivalent of the
/// specified float value converted to its native datatype.
/// </summary>
/// <param name="v">The float value to set the object to.</param>
/// <returns>True if the value, or an equivalent value was successfully set. Else, false</returns>
public abstract bool SetFloat(float v);
/// <summary>
/// Set the double value of the object - or the equivalent of the
/// specified double value converted to its native datatype.
/// </summary>
/// <param name="v">The double value to set the object to.</param>
/// <returns>True if the value, or an equivalent value was successfully set. Else, false</returns>
public abstract bool SetFloat64(double v);
/// <summary>
/// Set the string value of the object - or the equivalent of the
/// specified string value converted to its native datatype.
/// </summary>
/// <param name="v">The string value to set the object to.</param>
/// <returns>True if the value, or an equivalent value was successfully set. Else, false</returns>
public abstract bool SetString(string v);
/// <summary>
/// Create a copy of the object.
/// </summary>
/// <returns>A deep copy of the object.</returns>
public abstract Val Clone();
/// <summary>
/// Set the value of an object from a Val.
/// </summary>
/// <param name="v"></param>
/// <returns></returns>
public abstract bool SetValue(Val v);
public abstract bool SetIndex(int idx, Val v);
public abstract bool SetIndex(string idx, Val v);
public abstract bool SetIndex(Val idx, Val v);
public virtual ValArray GetIndices(){ return new ValArray(); }
/// <summary>
/// Get the value of two Vals added.
/// </summary>
/// <param name="v">The other value to add to the invoking object.</param>
/// <returns>The value that is the sum of the invoking object and parameter.
/// The resulting datatype depends on the Add() implementation of the invoking object.</returns>
public abstract Val Add(Val v);
/// <summary>
/// Multiply the value of two Vals.
/// </summary>
/// <param name="v">The other value to multiply by the invoking object.</param>
/// <returns>The value that is the product of the invoking object and parameter.
/// The resulting datatype depends on the Mul() implementation of the invoking object.</returns>
public abstract Val Mul(Val v);
/// <summary>
///
/// </summary>
/// <param name="v"></param>
/// <returns> The value that is the minimum between the invoking object and parameter.
/// The resulting datatype depends on the Min() implementation of the invoking object.</returns>
public abstract Val Min(Val v);
/// <summary>
///
/// </summary>
/// <param name="v"></param>
/// <returns>The value that is the maximum between the invoking object and parameter.
/// The resulting datatype depends on the Max() implementation and the invoking object.</returns>
public abstract Val Max(Val v);
/// <summary>
/// The number of children in the object. Some datatypes cannot have children, and will
/// return 0 by default.
/// </summary>
/// <returns>The number of children the object has.</returns>
public virtual int ChildrenCount(){return 0; }
/// <summary>
/// If true, the value is a container type that explicitly contains children Val objects.
/// </summary>
/// <returns>If true, the datatype is a container that can contain child Val object. Else, the
/// datatype does not container children values.
///
/// Note that this is not the same as not having accessible children. Some datatypes can imply
/// children, even though they explicitly have none, such as strings containing invdividual character.
/// </returns>
public virtual bool IsContainer(){return false; }
/// <summary>
/// Get the child Val at a specified integer index.
/// </summary>
/// <param name="i">The index to retrieve.</param>
/// <returns>The Val found at the specified index, or a null or None object if the child
/// could not be found. It is unspecified if the return will be a None object or null,
/// and depends on the implementation of the invoking object.</returns>
public virtual Val GetIndex(int i){ return null; }
/// <summary>
/// Get the child Val mapped to a specific Val key.
/// </summary>
/// <param name="i">The key to retrieve the mapped value for.</param>
/// <returns>The Val found at the specified key, or a null or None object if the child
/// could not be found. It is unspecified if the return will be a None object or null,
/// and depends on the implementation of the invoking object.</returns>
public virtual Val GetIndex(Val i){ return null; }
public virtual Val GetIndex(string idx)
{
if(prototype != null)
return prototype.GetPrototypeMember(this, idx);
return null;
}
public virtual Val Execute(Ctx ctx, out EvalTy evalTy) { evalTy = EvalTy.Relay; return this; }
public virtual bool Equals(Val v)
{
if(this == v)
return true;
if(this.ty != v.ty)
return false;
return this.Equivalent(v);
}
public abstract bool Equivalent(Val v);
public virtual bool AppendInstruction(Val v) => false;
/// <summary>
/// Utility function to make a ValInt using an overloaded function name Make().
/// </summary>
/// <param name="i">The ValInt value.</param>
/// <returns>A ValInt with the parameter value.</returns>
public static Val Make(int i)
{
return new ValInt(i);
}
/// <summary>
/// Utility function to make a ValUInt using an overloaded function name Make().
/// </summary>
/// <param name="i">The ValUInt value.</param>
/// <returns>A ValUInt with the parameter value.</returns>
public static Val Make(uint i)
{
return new ValUInt(i);
}
/// <summary>
/// Utility function to make a ValFloat using an overloaded function name Make().
/// </summary>
/// <param name="f">The ValFloat value.</param>
/// <returns>A ValFloat with the parameter value.</returns>
public static Val Make(float f)
{
return new ValFloat(f);
}
/// <summary>
/// Utility function to make a ValInt64 using an overloaded function name Make().
/// </summary>
/// <param name="l">The ValInt64 value.</param>
/// <returns>A ValInt64 with the parameter value.</returns>
public static Val Make(long l)
{
return new ValInt64(l);
}
/// <summary>
/// Utility function to make a ValUInt64 using an overloaded function name Make().
/// </summary>
/// <param name="l">The ValUInt64 value.</param>
/// <returns>A ValUInt64 with the parameter value.</returns>
public static Val Make(ulong l)
{
return new ValUInt64(l);
}
/// <summary>
/// Utility function to make a ValFloat64 using an overloaded function name Make().
/// </summary>
/// <param name="d">The ValFloat64 value.</param>
/// <returns>A ValFloat64 with the parameter value.</returns>
public static Val Make(double d)
{
return new ValFloat64(d);
}
/// <summary>
/// Utility function to make a ValBool using an overloaded function name Make().
/// </summary>
/// <param name="b">The ValBool value.</param>
/// <returns>A ValBool with the parameter value.</returns>
public static Val Make(bool b)
{
return new ValBool(b);
}
/// <summary>
/// Utility function to make a ValString using an overloaded function name Make().
/// </summary>
/// <param name="s">The ValString value.</param>
/// <returns>A ValString with the parameter value.</returns>
public static Val Make(string s)
{
return new ValString(s);
}
}
}