80e9f0176e183926312fe88a0db3991625256044
1 using System;
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 */
9 struct SType {
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 }
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 }
32 /*
33 * Tell whether the stack effect is known.
34 */
35 internal bool IsKnown {
36 get {
37 return din >= 0;
38 }
39 }
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 }
50 int din, dout;
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 }
64 /*
65 * Special value for the unknown stack effect.
66 */
67 internal static SType UNKNOWN = new SType(-1, -1);
69 /*
70 * Constant for the "blank stack effect".
71 */
72 internal static SType BLANK = new SType(0, 0);
74 public static bool operator ==(SType s1, SType s2)
75 {
76 return s1.din == s2.din && s1.dout == s2.dout;
77 }
79 public static bool operator !=(SType s1, SType s2)
80 {
81 return s1.din != s2.din || s1.dout != s2.dout;
82 }
84 public override bool Equals(Object obj)
85 {
86 return (obj is SType) && ((SType)obj == this);
87 }
89 public override int GetHashCode()
90 {
91 return din * 31 + dout * 17;
92 }
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 }
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 }