1 module navm.defs; 2 3 import utils.misc; 4 5 /// to store data from script at runtime 6 public union NaData{ 7 union{ 8 bool boolVal; /// boolean value 9 dchar dcharVal; /// dchar value 10 integer intVal; /// integer value 11 double doubleVal; /// double/float value 12 NaData* ptrVal; /// to store references 13 } 14 /// constructor 15 /// data can be any of the type which it can store 16 this (T)(T data){ 17 static if (is (T == int) || is (T == long) || is (T == uint) || is (T == ulong)){ 18 intVal = data; 19 }else static if (is (T == double) || is (T == float)){ 20 doubleVal = data; 21 }else static if (is (T == NaData[])){ 22 arrayVal = data; 23 }else static if (is (T == NaData*)){ 24 ptrVal = data; 25 }else static if (is (T == dchar)){ 26 dcharVal = data; 27 }else static if (is (T == dchar[]) || is (T == dstring)){ 28 strVal = cast(dchar[])data; 29 }else static if (is (T == bool)){ 30 boolVal = data; 31 }else{ 32 throw new Exception("cannot store "~T.stringof~" in NaData"); 33 } 34 } 35 /// makes this NaData into an array 36 void makeArray(uinteger length){ 37 NaData[] array; 38 array.length = length+1; 39 array[0].intVal = length; 40 ptrVal = array.ptr+1; 41 } 42 /// Returns: array value, read from ptrVal 43 @property NaData[] arrayVal(){ 44 return ptrVal[0 .. (*(ptrVal-1)).intVal]; 45 } 46 /// ditto 47 @property NaData[] arrayVal(NaData[] newVal){ 48 NaData[] array = NaData(newVal.length) ~ newVal; 49 ptrVal = array.ptr + 1; 50 return array[1 .. $]; 51 } 52 /// Returns: array length. 53 /// 54 /// Do NOT use this to initialize array, use `makeArray` 55 @property uinteger arrayValLength(){ 56 return (*(ptrVal - 1)).intVal; 57 } 58 /// ditto 59 @property uinteger arrayValLength(uinteger length){ 60 NaData[] array; 61 array.length = length + 1; 62 array[0].intVal = length; 63 immutable uinteger sliceLength = length > arrayValLength ? arrayValLength : length; 64 array[1 .. sliceLength+1] = arrayVal[0 .. sliceLength]; 65 ptrVal = array.ptr+1; 66 return length; 67 } 68 /// Returns: string value stored as NaData[] (in arrayVal) 69 @property dchar[] strVal(){ 70 dchar[] r; 71 r.length = arrayValLength; 72 foreach (i, ch; arrayVal){ 73 r[i] = ch.dcharVal; 74 } 75 return r; 76 } 77 /// Setter for strVal 78 @property dchar[] strVal(dchar[] newVal){ 79 makeArray(newVal.length); 80 foreach (i, ch; newVal){ 81 arrayVal[i].dcharVal = ch; 82 } 83 return newVal; 84 } 85 } 86 87 /// for storing a stack frame in stack 88 struct StackFrame{ 89 void delegate()* instruction; /// instruction 90 NaData* argument; /// argument for that instruction 91 uinteger stackIndex; /// stack index relative to which some instructions will pushFrom/writeTo 92 } 93 94 /// a simple array based stack 95 /// 96 /// no bound checking is done, so be careful 97 public class ArrayStack(T){ 98 private: 99 T[] _array; 100 T* _peekPtr; 101 public: 102 /// constructor (set the stack length here) 103 this(uinteger length=65_536){ 104 _array.length = length; 105 _peekPtr = _array.ptr; 106 } 107 /// Pops an element from stack 108 /// 109 /// Returns: popped element 110 T pop(){ 111 _peekPtr --; 112 return *_peekPtr; 113 } 114 /// pushes an element to stack 115 void push(T element){ 116 *_peekPtr = element; 117 _peekPtr++; 118 } 119 /// number of elements in stack 120 @property uinteger count(){ 121 return cast(uinteger)(_peekPtr - _array.ptr); 122 } 123 /// Reads n number of elements from stack, in reverse order (i.e: [nth-last pushed, (n-1)th-last pushed, ..., last pushed]) 124 /// 125 /// Returns: the elements read 126 T[] pop(uinteger n){ 127 _peekPtr -= n; 128 return _peekPtr[0 .. n]; 129 } 130 /// pushes elements to stack. First in array is pushed first 131 void push(T[] elements){ 132 _peekPtr[0 .. elements.length] = elements; 133 _peekPtr += elements.length; 134 } 135 /// Returns: element at index 136 T read(uinteger index){ 137 return _array[index]; 138 } 139 /// Returns: pointer to element at index 140 T* readPtr(uinteger index){ 141 return &(_array[index]); 142 } 143 /// Writes a value to index 144 void write(uinteger index, T value){ 145 _array[index] = value; 146 } 147 /// Moves peek pointer to index 148 void peek(uinteger index){ 149 _peekPtr = _array.ptr + index; 150 } 151 }