/ T0 / TValue.cs
TValue.cs
  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  }