/ T0 / SType.cs
SType.cs
  1  using System;
  2  
  3  /*
  4   * This structure contains the stack effect of a word: number of stack
  5   * element consumed on input, and number of stack element produced on
  6   * output.
  7   */
  8  
  9  struct SType {
 10  
 11  	/*
 12  	 * Get number of stack elements consumed on input; this is -1 if
 13  	 * the stack effect is not known.
 14  	 */
 15  	internal int DataIn {
 16  		get {
 17  			return din;
 18  		}
 19  	}
 20  
 21  	/*
 22  	 * Get number of stack elements produced on output; this is -1 if
 23  	 * either the stack effect is not known, or if the word never
 24  	 * exits.
 25  	 */
 26  	internal int DataOut {
 27  		get {
 28  			return dout;
 29  		}
 30  	}
 31  
 32  	/*
 33  	 * Tell whether the stack effect is known.
 34  	 */
 35  	internal bool IsKnown {
 36  		get {
 37  			return din >= 0;
 38  		}
 39  	}
 40  
 41  	/*
 42  	 * Tell whether the stack effect is known and the word never exits.
 43  	 */
 44  	internal bool NoExit {
 45  		get {
 46  			return din >= 0 && dout < 0;
 47  		}
 48  	}
 49  
 50  	int din, dout;
 51  
 52  	internal SType(int din, int dout)
 53  	{
 54  		if (din < 0) {
 55  			din = -1;
 56  		}
 57  		if (dout < 0) {
 58  			dout = -1;
 59  		}
 60  		this.din = din;
 61  		this.dout = dout;
 62  	}
 63  
 64  	/*
 65  	 * Special value for the unknown stack effect.
 66  	 */
 67  	internal static SType UNKNOWN = new SType(-1, -1);
 68  
 69  	/*
 70  	 * Constant for the "blank stack effect".
 71  	 */
 72  	internal static SType BLANK = new SType(0, 0);
 73  
 74  	public static bool operator ==(SType s1, SType s2)
 75  	{
 76  		return s1.din == s2.din && s1.dout == s2.dout;
 77  	}
 78  
 79  	public static bool operator !=(SType s1, SType s2)
 80  	{
 81  		return s1.din != s2.din || s1.dout != s2.dout;
 82  	}
 83  
 84  	public override bool Equals(Object obj)
 85  	{
 86  		return (obj is SType) && ((SType)obj == this);
 87  	}
 88  
 89  	public override int GetHashCode()
 90  	{
 91  		return din * 31 + dout * 17;
 92  	}
 93  
 94  	public override string ToString()
 95  	{
 96  		if (!IsKnown) {
 97  			return "UNKNOWN";
 98  		} else if (NoExit) {
 99  			return string.Format("in:{0},noexit", din);
100  		} else {
101  			return string.Format("in:{0},out:{1}", din, dout);
102  		}
103  	}
104  
105  	/*
106  	 * Test whether this stack effect is a sub-effect of the provided
107  	 * stack effect s. Stack effect s1 is a sub-effect of stack-effect
108  	 * s2 if any of the following holds:
109  	 * -- s1 and s2 are known, s1.din <= s2.din and s1 does not exit.
110  	 * -- s1 and s2 are known, s1.din <= s2.din, s1 and s2 exit,
111  	 *    and s1.din - s1.dout == s2.din - s2.dout.
112  	 */
113  	internal bool IsSubOf(SType s)
114  	{
115  		if (!IsKnown || !s.IsKnown) {
116  			return false;
117  		}
118  		if (din > s.din) {
119  			return false;
120  		}
121  		if (NoExit) {
122  			return true;
123  		}
124  		if (s.NoExit) {
125  			return false;
126  		}
127  		return (din - dout) == (s.din - s.dout);
128  	}
129  }