1 /* 2 * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org> 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining 5 * a copy of this software and associated documentation files (the 6 * "Software"), to deal in the Software without restriction, including 7 * without limitation the rights to use, copy, modify, merge, publish, 8 * distribute, sublicense, and/or sell copies of the Software, and to 9 * permit persons to whom the Software is furnished to do so, subject to 10 * the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 */ 24 25 using System; 26 using System.Collections.Generic; 27 28 /* 29 * Each value is represented with a TValue structure. Integers use the 'x' 30 * field, and 'ptr' is null; for pointers, the 'ptr' field is used, and the 31 * 'x' is then an offset in the object represented by 'ptr'. 32 */ 33 34 struct TValue { 35 36 internal int x; 37 internal TPointerBase ptr; 38 39 internal TValue(int x) 40 { 41 this.x = x; 42 this.ptr = null; 43 } 44 45 internal TValue(uint x) 46 { 47 this.x = (int)x; 48 this.ptr = null; 49 } 50 51 internal TValue(bool b) 52 { 53 this.x = b ? -1 : 0; 54 this.ptr = null; 55 } 56 57 internal TValue(int x, TPointerBase ptr) 58 { 59 this.x = x; 60 this.ptr = ptr; 61 } 62 63 /* 64 * Convert this value to a boolean; integer 0 and null pointer are 65 * 'false', other values are 'true'. 66 */ 67 internal bool Bool { 68 get { 69 if (ptr == null) { 70 return x != 0; 71 } else { 72 return ptr.ToBool(this); 73 } 74 } 75 } 76 77 /* 78 * Get this value as an integer. Pointers cannot be converted to 79 * integers. 80 */ 81 internal int Int { 82 get { 83 if (ptr == null) { 84 return x; 85 } 86 throw new Exception("not an integer: " + ToString()); 87 } 88 } 89 90 /* 91 * Get this value as an unsigned integer. This is the integer 92 * value, reduced modulo 2^32 in the 0..2^32-1 range. 93 */ 94 internal uint UInt { 95 get { 96 return (uint)Int; 97 } 98 } 99 100 /* 101 * String format of integers uses decimal representation. For 102 * pointers, this depends on the pointed-to value. 103 */ 104 public override string ToString() 105 { 106 if (ptr == null) { 107 return String.Format("{0}", x); 108 } else { 109 return ptr.ToString(this); 110 } 111 } 112 113 /* 114 * If this value is an XT, then execute it. Otherwise, an exception 115 * is thrown. 116 */ 117 internal void Execute(T0Comp ctx, CPU cpu) 118 { 119 ToXT().Execute(ctx, cpu); 120 } 121 122 /* 123 * Convert this value to an XT. On failure, an exception is thrown. 124 */ 125 internal TPointerXT ToXT() 126 { 127 TPointerXT xt = ptr as TPointerXT; 128 if (xt == null) { 129 throw new Exception( 130 "value is not an xt: " + ToString()); 131 } 132 return xt; 133 } 134 135 /* 136 * Compare this value to another. 137 */ 138 internal bool Equals(TValue v) 139 { 140 if (x != v.x) { 141 return false; 142 } 143 if (ptr == v.ptr) { 144 return true; 145 } 146 if (ptr == null || v.ptr == null) { 147 return false; 148 } 149 return ptr.Equals(v.ptr); 150 } 151 152 public static implicit operator TValue(bool val) 153 { 154 return new TValue(val); 155 } 156 157 public static implicit operator TValue(sbyte val) 158 { 159 return new TValue((int)val); 160 } 161 162 public static implicit operator TValue(byte val) 163 { 164 return new TValue((int)val); 165 } 166 167 public static implicit operator TValue(short val) 168 { 169 return new TValue((int)val); 170 } 171 172 public static implicit operator TValue(ushort val) 173 { 174 return new TValue((int)val); 175 } 176 177 public static implicit operator TValue(char val) 178 { 179 return new TValue((int)val); 180 } 181 182 public static implicit operator TValue(int val) 183 { 184 return new TValue((int)val); 185 } 186 187 public static implicit operator TValue(uint val) 188 { 189 return new TValue((int)val); 190 } 191 192 public static implicit operator bool(TValue v) 193 { 194 return v.Bool; 195 } 196 197 public static implicit operator sbyte(TValue v) 198 { 199 return (sbyte)v.Int; 200 } 201 202 public static implicit operator byte(TValue v) 203 { 204 return (byte)v.Int; 205 } 206 207 public static implicit operator short(TValue v) 208 { 209 return (short)v.Int; 210 } 211 212 public static implicit operator ushort(TValue v) 213 { 214 return (ushort)v.Int; 215 } 216 217 public static implicit operator char(TValue v) 218 { 219 return (char)v.Int; 220 } 221 222 public static implicit operator int(TValue v) 223 { 224 return (int)v.Int; 225 } 226 227 public static implicit operator uint(TValue v) 228 { 229 return (uint)v.Int; 230 } 231 } 232