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