996
|
1 #include <stdlib.h>
|
|
2 #include <stdio.h>
|
|
3 #include <string.h>
|
|
4
|
|
5 #include "egobfi.h"
|
|
6 #include "optimize.h"
|
|
7
|
|
8 #define NEXT pptr++; CHKPSZ(pptr)
|
|
9
|
|
10 int optaddto(int cur);
|
|
11
|
|
12 void optimize()
|
|
13 {
|
|
14 /* optimize optimizes a chunk of code at ipptr */
|
|
15 int cnt, a;
|
|
16 struct bfi *cur;
|
|
17
|
|
18 while (iprog[ipptr]) {
|
|
19 switch(iprog[ipptr]) {
|
|
20 case '+':
|
|
21 case '-':
|
|
22 cnt = 0;
|
|
23 while (iprog[ipptr] == '+' ||
|
|
24 iprog[ipptr] == '-') {
|
|
25 if (iprog[ipptr] == '+') cnt++;
|
|
26 else cnt--;
|
|
27 ipptr++;
|
|
28 }
|
|
29
|
|
30 cur = prog + pptr;
|
|
31 cur->cmd = ADD;
|
|
32 cur->arg1 = cnt;
|
|
33 NEXT
|
|
34 break;
|
|
35
|
|
36 case '>':
|
|
37 case '<':
|
|
38 cnt = 0;
|
|
39 while (iprog[ipptr] == '>' ||
|
|
40 iprog[ipptr] == '<') {
|
|
41 if (iprog[ipptr] == '>') cnt++;
|
|
42 else cnt--;
|
|
43 ipptr++;
|
|
44 }
|
|
45
|
|
46 cur = prog + pptr;
|
|
47 cur->cmd = RHT;
|
|
48 cur->arg1 = cnt;
|
|
49 NEXT
|
|
50 break;
|
|
51
|
|
52 case '[':
|
|
53 /* special case 1: zero */
|
|
54 if (iprog[ipptr + 2] == ']' &&
|
|
55 (iprog[ipptr + 1] == '-' ||
|
|
56 (iprog[ipptr + 1] == '+' && wrapping))
|
|
57 ) {
|
|
58 prog[pptr].cmd = ZRO;
|
|
59 NEXT
|
|
60 ipptr += 3;
|
|
61 break;
|
|
62 }
|
|
63
|
|
64 /* start a suboptimize */
|
|
65 a = pptr;
|
|
66 NEXT
|
|
67 ipptr++;
|
|
68 optimize();
|
|
69
|
|
70 /* check for addto */
|
|
71 if (pptr == a + 5 && optaddto(a)) {
|
|
72 ipptr++;
|
|
73 break;
|
|
74 }
|
|
75
|
|
76 /* make the jump */
|
|
77 cur = prog + a;
|
|
78 cur->cmd = LPO;
|
|
79 cur->arg1 = pptr;
|
|
80
|
|
81 cur = prog + pptr;
|
|
82 cur->cmd = LPC;
|
|
83 cur->arg1 = a;
|
|
84
|
|
85 NEXT
|
|
86 ipptr++;
|
|
87 break;
|
|
88
|
|
89 case ']':
|
|
90 /* this optimization session is over */
|
|
91 return;
|
|
92
|
|
93 case '.':
|
|
94 /* not much we can optimize here ... */
|
|
95 prog[pptr].cmd = OUT;
|
|
96 NEXT
|
|
97 ipptr++;
|
|
98 break;
|
|
99
|
|
100 case ',':
|
|
101 /* here neither ... */
|
|
102 prog[pptr].cmd = INP;
|
|
103 NEXT
|
|
104 ipptr++;
|
|
105 break;
|
|
106
|
|
107 case '#':
|
|
108 /* still no optimizations! */
|
|
109 prog[pptr].cmd = DBG;
|
|
110 NEXT
|
|
111 ipptr++;
|
|
112 break;
|
|
113
|
|
114 default:
|
|
115 ipptr++;
|
|
116 break;
|
|
117 }
|
|
118 }
|
|
119
|
|
120 /* if we finished making the optimized program, this is the end */
|
|
121 prog[pptr].cmd = FIN;
|
|
122 pptr = 0;
|
|
123 }
|
|
124
|
|
125 int optaddto(int cur)
|
|
126 {
|
|
127 /* a = pptr of LPO,
|
|
128 pptr = pptr of LPC */
|
|
129 struct bfi *a = prog + cur;
|
|
130
|
|
131 /* two types of add-tos:
|
|
132 >x +x <x -x
|
|
133 -x >x +x <x
|
|
134 */
|
|
135 if (a[1].cmd == RHT &&
|
|
136 a[3].cmd == RHT &&
|
|
137 a[1].arg1 == a[3].arg1 * -1) {
|
|
138 if (a[2].cmd == ADD &&
|
|
139 a[4].cmd == ADD &&
|
|
140 a[4].arg1 == -1) {
|
|
141 /* YAY! */
|
|
142 a->cmd = ADDTO;
|
|
143 a->arg1 = a[1].arg1;
|
|
144 a->arg2 = a[2].arg1;
|
|
145
|
|
146 pptr = cur + 1;
|
|
147 return 1;
|
|
148 }
|
|
149 } else if (a[2].cmd == RHT &&
|
|
150 a[4].cmd == RHT &&
|
|
151 a[2].arg1 == a[4].arg1 * -1) {
|
|
152 if (a[1].cmd == ADD &&
|
|
153 a[3].cmd == ADD &&
|
|
154 a[1].arg1 == -1) {
|
|
155 /* YAY! */
|
|
156 a->cmd = ADDTO;
|
|
157 a->arg1 = a[2].arg1;
|
|
158 a->arg2 = a[3].arg1;
|
|
159
|
|
160 pptr = cur + 1;
|
|
161 return 1;
|
|
162 }
|
|
163 }
|
|
164
|
|
165 return 0;
|
|
166 }
|