|
|
1.1 root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.