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 STypeSType52 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 operator ==SType74 public static bool operator ==(SType s1, SType s2) 75 { 76 return s1.din == s2.din && s1.dout == s2.dout; 77 } 78 operator !=SType79 public static bool operator !=(SType s1, SType s2) 80 { 81 return s1.din != s2.din || s1.dout != s2.dout; 82 } 83 EqualsSType84 public override bool Equals(Object obj) 85 { 86 return (obj is SType) && ((SType)obj == this); 87 } 88 GetHashCodeSType89 public override int GetHashCode() 90 { 91 return din * 31 + dout * 17; 92 } 93 ToStringSType94 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 */ IsSubOfSType113 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 } 130