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