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