1: #include <stdio.h> 2: #include "def.h" 3: #include "3.def.h" 4: 5: #define ARCCOUNT(v) REACH(v) 6: 7: 8: fixhd(v,hd,head) 9: VERT v,hd,*head; 10: { 11: VERT w,newhd; 12: int i; 13: head[v] = hd; 14: newhd = (NTYPE(v) == ITERVX) ? v : hd; 15: for (i = 0; i < CHILDNUM(v); ++i) 16: for (w = LCHILD(v,i); DEFINED(w); w = RSIB(w)) 17: fixhd(w,newhd,head); 18: } 19: 20: getloop() 21: { 22: cntarcs(); 23: fixloop(START); 24: } 25: 26: 27: cntarcs() /* count arcs entering each node */ 28: { 29: VERT w,v; 30: int i; 31: for (v = 0; v < nodenum; ++v) 32: ARCCOUNT(v) = 0; 33: for (v = 0; v < nodenum; ++v) 34: for (i = 0; i < ARCNUM(v); ++i) 35: { 36: w = ARC(v,i); 37: if (!DEFINED(w)) continue; 38: ++ARCCOUNT(w); 39: } 40: } 41: 42: 43: fixloop(v) /* find WHILE loops */ 44: VERT v; 45: { 46: int recvar; 47: if (NTYPE(v) == LOOPVX) 48: { 49: ASSERT(DEFINED(ARC(v,0)),fixloop); 50: NXT(ARC(v,0)) = ARC(v,0); 51: if (!getwh(v)) 52: getun(v); 53: } 54: else if (NTYPE(v) == IFVX && arbcase) 55: getswitch(v); 56: else if (NTYPE(v)==DOVX) 57: { 58: ASSERT(DEFINED(ARC(v,0)),fixloop); 59: NXT(ARC(v,0))=ARC(v,0); 60: } 61: RECURSE(fixloop,v,recvar); 62: } 63: 64: 65: getwh(v) 66: VERT v; 67: { 68: VERT vchild, vgrand,vgreat; 69: ASSERT(NTYPE(v) == LOOPVX,getwh); 70: vchild = LCHILD(v,0); 71: ASSERT(DEFINED(vchild),getwh); 72: ASSERT(NTYPE(vchild) == ITERVX,getwh); 73: vgrand = LCHILD(vchild,0); 74: if (!DEFINED(vgrand) || !IFTHEN(vgrand) ) 75: return(FALSE); 76: vgreat = LCHILD(vgrand,THEN); 77: if (DEFINED(vgreat) && NTYPE(vgreat) == GOVX && ARC(vgreat,0) == BRK(vchild)) 78: { 79: /* turn into WHILE */ 80: NTYPE(v) = WHIVX; 81: NEG(vgrand) = !NEG(vgrand); 82: LPRED(vchild) = vgrand; 83: LCHILD(vchild,0) = RSIB(vgrand); 84: RSIB(vgrand) = UNDEFINED; 85: return(TRUE); 86: } 87: return(FALSE); 88: } 89: 90: 91: 92: getun(v) /* change loop to REPEAT UNTIL if possible */ 93: VERT v; 94: { 95: VERT vchild, vgrand, vgreat, before, ch; 96: ASSERT(NTYPE(v) == LOOPVX,getun); 97: vchild = LCHILD(v,0); 98: ASSERT(DEFINED(vchild), getun); 99: if (ARCCOUNT(vchild) > 2) 100: return(FALSE); /* loop can be iterated without passing through predicate of UNTIL */ 101: vgrand = ARC(vchild,0); 102: if (!DEFINED(vgrand)) 103: return(FALSE); 104: for (ch = vgrand,before = UNDEFINED; DEFINED(RSIB(ch)); ch = RSIB(ch)) 105: before = ch; 106: if (!IFTHEN(ch)) 107: return(FALSE); 108: vgreat = LCHILD(ch,THEN); 109: if (DEFINED(vgreat) && NTYPE(vgreat) == GOVX && ARC(vgreat,0) == BRK(vchild)) 110: { 111: /* create UNTIL node */ 112: NTYPE(v) = UNTVX; 113: NXT(vchild) = ch; 114: LPRED(vchild)=ch; 115: RSIB(before) = UNDEFINED; 116: return(TRUE); 117: } 118: return(FALSE); 119: } 120: 121: 122: #define FORMCASE(w) (DEFINED(w) && !DEFINED(RSIB(w)) && NTYPE(w) == IFVX && ARCCOUNT(w) == 1) 123: 124: getswitch(v) 125: VERT v; 126: { 127: VERT ch, grand, temp; 128: /* must be of form if ... else if ... else if ... */ 129: if (NTYPE(v) != IFVX) return(FALSE); 130: ch = LCHILD(v,ELSE); 131: if (!FORMCASE(ch)) return(FALSE); 132: grand = LCHILD(ch,ELSE); 133: if (!FORMCASE(grand)) return(FALSE); 134: 135: temp = create(SWCHVX,0); 136: exchange(&graph[temp],&graph[v]); /* want arcs to enter switch, not first case*/ 137: BEGCOM(v) = UNDEFINED; 138: RSIB(v) = RSIB(temp); /* statements which followed IFVX should follow switch */ 139: EXP(v) = UNDEFINED; 140: LCHILD(v,0) = temp; 141: NTYPE(temp) = ACASVX; 142: for (ch = LCHILD(temp,ELSE); FORMCASE(ch); ) 143: { 144: LCHILD(temp,ELSE) = UNDEFINED; 145: RSIB(temp) = ch; 146: NTYPE(ch) = ACASVX; 147: temp = ch; 148: ch = LCHILD(temp,ELSE); 149: } 150: ASSERT(!DEFINED(RSIB(temp)),getswitch); 151: return(TRUE); 152: }