1
2 /*
3 # Sfront, a SAOL to C translator
4 # This file: Handles specialops
5 #
6 # Copyright (c) 1999-2006, Regents of the University of California
7 # All rights reserved.
8 #
9 # Redistribution and use in source and binary forms, with or without
10 # modification, are permitted provided that the following conditions are
11 # met:
12 #
13 # Redistributions of source code must retain the above copyright
14 # notice, this list of conditions and the following disclaimer.
15 #
16 # Redistributions in binary form must reproduce the above copyright
17 # notice, this list of conditions and the following disclaimer in the
18 # documentation and/or other materials provided with the distribution.
19 #
20 # Neither the name of the University of California, Berkeley nor the
21 # names of its contributors may be used to endorse or promote products
22 # derived from this software without specific prior written permission.
23 #
24 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #
36 # Maintainer: John Lazzaro, lazzaro@cs.berkeley.edu
37 */
38
39
40 #include "tree.h"
41 #include "parser.tab.h"
42
43
44 /************************************************************/
45 /* special check for two tnodes in an <expr> */
46 /************************************************************/
47
exprspecial(tnode * left,tnode * right)48 int exprspecial(tnode * left, tnode * right)
49
50 {
51 return (left->special || right->special);
52 }
53
54 /************************************************************/
55 /* special check for an exprlist */
56 /************************************************************/
57
exprlistspecial(tnode * elist)58 int exprlistspecial(tnode * elist)
59
60 {
61 int sp = 0;
62
63 elist = elist->down;
64 while (elist != NULL)
65 {
66 sp = sp || elist->special;
67 elist = elist->next;
68 }
69 return sp;
70
71 }
72
73 /************************************************************/
74 /* computes special flag for a list of statements */
75 /************************************************************/
76
blockspecial(tnode * block)77 int blockspecial(tnode * block)
78
79 {
80
81 int sp = 0;
82
83 while (block != NULL)
84 {
85 sp = sp || block->special;
86 block = block->next;
87 }
88 return sp;
89
90 }
91
92 /****************************************************************/
93 /* updates special flag in parse tree */
94 /****************************************************************/
95
specialupdate(tnode * tbranch)96 int specialupdate(tnode * tbranch)
97
98 {
99
100 tnode * tptr = tbranch;
101 tnode * cptr;
102 int sp = 0;
103
104 while (tptr != NULL)
105 {
106 specialupdate(tptr->down);
107 switch (tptr->ttype) {
108 case S_LVALUE:
109 if (tptr->down->next == NULL) /* unindexed */
110 {
111 }
112 else /* indexed */
113 {
114 tptr->special = tptr->down->next->next->special;
115 }
116 break;
117 case S_STATEMENT:
118 if (tptr->down->next->ttype == S_SEM)
119 {
120 if (tptr->down->ttype == S_EXPR) /* expr SEM */
121 {
122 tptr->special = tptr->down->special;
123 }
124 else /* turnoff SEM */
125 {
126
127 }
128 break;
129 }
130 if (tptr->down->ttype == S_LVALUE) /* lvalue EQ expr SEM */
131 {
132 tptr->special = exprspecial(tptr->down,tptr->down->next->next);
133 break;
134 }
135 if (tptr->down->ttype == S_OUTPUT)
136 {
137 tptr->special = exprlistspecial(tptr->down->next->next);
138 break;
139 }
140 if (tptr->down->ttype == S_OUTBUS)
141 {
142 tptr->special = exprlistspecial(tptr->down->next->next->next->next);
143 break;
144 }
145 if (tptr->down->ttype == S_INSTR)
146 {
147 tptr->special = exprlistspecial(tptr->down->next->next->next);
148 break;
149 }
150 if (tptr->down->ttype == S_RETURN)
151 {
152 tptr->special = exprlistspecial(tptr->down->next->next);
153 break;
154 }
155 if (tptr->down->ttype == S_PRINTF)
156 {
157 tptr->special = exprlistspecial(tptr->down->next->next);
158 break;
159 }
160 if (tptr->down->ttype == S_IF)
161 {
162 cptr = tptr->down->next->next->next->next->next;
163 tptr->special = tptr->down->next->next->special;
164 if (!(tptr->special) && blockspecial(cptr->down))
165 {
166 printf("Error: If block has specialops, guard doesn't.\n");
167 showerrorplace(tptr->down->linenum, tptr->down->filename);
168 }
169 if (cptr->next->next != NULL)
170 {
171 cptr = cptr->next->next->next->next;
172 if (!(tptr->special) && blockspecial(cptr->down))
173 {
174 printf("Error: Else block has specialops, ");
175 printf("guard doesn't.\n");
176 showerrorplace(tptr->down->linenum, tptr->down->filename);
177
178 }
179 }
180 break;
181 }
182 if (tptr->down->ttype == S_WHILE)
183 {
184 cptr = tptr->down->next->next->next->next->next;
185 tptr->special = tptr->down->next->next->special;
186 if ((tptr->special) || (blockspecial(cptr->down)))
187 {
188 printf("Error: While guard or block may not be specialop.\n");
189 showerrorplace(tptr->down->linenum, tptr->down->filename);
190 }
191 break;
192 }
193 break;
194 case S_EXPR:
195 if (tptr->down->next == NULL)
196 {
197 if (tptr->down->ttype == S_IDENT) /* ident */
198 {
199 }
200 else
201 { /* constant */
202 }
203 break;
204 }
205 if ((tptr->down->ttype == S_MINUS) ||
206 (tptr->down->ttype == S_NOT)) /* unary */
207 {
208 tptr->special = tptr->down->next->special;
209 break;
210 }
211 if (tptr->down->ttype == S_LP) /* works for float->into to */
212 {
213 tptr->special = tptr->down->next->special;
214 break;
215 }
216 if (tptr->down->ttype == S_FLOATCAST)
217 {
218 tptr->special = tptr->down->next->next->special;
219 break;
220 }
221 if ((tptr->down->next->ttype == S_LEQ) ||
222 (tptr->down->next->ttype == S_GEQ) ||
223 (tptr->down->next->ttype == S_NEQ) ||
224 (tptr->down->next->ttype == S_EQEQ) ||
225 (tptr->down->next->ttype == S_GT) ||
226 (tptr->down->next->ttype == S_LT) ||
227 (tptr->down->next->ttype == S_AND) ||
228 (tptr->down->next->ttype == S_OR) ||
229 (tptr->down->next->ttype == S_SLASH) )
230 {
231 tptr->special = exprspecial(tptr->down, tptr->down->next->next);
232 break;
233 }
234 if ((tptr->down->next->ttype == S_PLUS) ||
235 (tptr->down->next->ttype == S_MINUS) ||
236 (tptr->down->next->ttype == S_STAR) )
237 {
238 cptr = tptr->down;
239 tptr->special = 0;
240 while (cptr != NULL)
241 {
242 if (cptr->ttype == S_EXPR)
243 tptr->special = tptr->special || cptr->special;
244 cptr = cptr->next;
245 }
246 break;
247 }
248 if (tptr->down->next->ttype == S_Q)
249 {
250 tptr->special = exprspecial(tptr->down,
251 tptr->down->next->next);
252 tptr->special = exprspecial(tptr,
253 tptr->down->next->next->next->next);
254 break;
255 }
256 if ((tptr->down->next->ttype == S_LB) && /*array index*/
257 (tptr->down->next->next->next->next == NULL))
258 {
259 tptr->special = tptr->down->next->next->special;
260 break;
261 }
262 if ((tptr->optr != NULL)) /* opcode and oparray */
263 {
264 if (coreopcodename(tptr->down))
265 tptr->special = tptr->down->special = tptr->optr->special =
266 tptr->optr->sptr->special = coreopcodespecial(tptr->down);
267 else
268 {
269 /* user-defined opcodes -- process the opcode lines, */
270 /* don't set the user-defined opcode special flag, so */
271 /* the semantics of specialops are hidden below. */
272
273 specialupdate(tptr->optr->sptr->defnode->down->
274 next->next->next->next->next->next->next->down);
275
276 }
277 if (tptr->optr->ttype == S_OPCALL)
278 cptr = tptr->down->next->next->down;
279 else
280 cptr = tptr->down->next->next->next->next->next->down;
281 while (cptr != NULL)
282 {
283 if (cptr->ttype == S_EXPR)
284 {
285 tptr->special = tptr->special || cptr->special;
286 }
287 cptr = cptr->next;
288 }
289 break;
290 }
291 break;
292 }
293 sp = sp || tptr->special;
294 tptr = tptr->next;
295 }
296 return sp;
297 }
298
299
300
301