Commit | Line | Data |
---|---|---|
758d36cd | 1 | /* common.c 4.5 88/05/11 */ |
ae51d042 RC |
2 | |
3 | #ifdef PASS1COMMON | |
4 | #include "pass1.h" | |
5 | #else | |
6 | #ifdef PASS2COMMON | |
7 | #include "pass2.h" | |
8 | #endif | |
9 | #endif | |
10 | ||
11 | #ifdef FORT | |
12 | #undef BUFSTDERR | |
13 | #endif | |
14 | #ifndef ONEPASS | |
15 | #undef BUFSTDERR | |
16 | #endif | |
17 | # ifndef EXIT | |
18 | # define EXIT exit | |
19 | # endif | |
20 | ||
21 | int nerrors = 0; /* number of errors */ | |
22 | ||
23 | extern unsigned int offsz; | |
24 | ||
25 | unsigned caloff(){ | |
26 | register i; | |
27 | unsigned int temp; | |
28 | unsigned int off; | |
29 | temp = 1; | |
30 | i = 0; | |
31 | do { | |
32 | temp <<= 1; | |
33 | ++i; | |
34 | } while( temp != 0 ); | |
35 | off = 1 << (i-1); | |
36 | return (off); | |
37 | } | |
38 | ||
39 | NODE *lastfree; /* pointer to last free node; (for allocator) */ | |
40 | ||
41 | /* VARARGS1 */ | |
42 | uerror( s, a ) char *s; { /* nonfatal error message */ | |
43 | /* the routine where is different for pass 1 and pass 2; | |
44 | /* it tells where the error took place */ | |
45 | ||
46 | ++nerrors; | |
47 | where('u'); | |
48 | fprintf( stderr, s, a ); | |
49 | fprintf( stderr, "\n" ); | |
50 | #ifdef BUFSTDERR | |
51 | fflush(stderr); | |
52 | #endif | |
53 | if( nerrors > 30 ) cerror( "too many errors"); | |
54 | } | |
55 | ||
56 | /* VARARGS1 */ | |
57 | cerror( s, a, b, c ) char *s; { /* compiler error: die */ | |
58 | where('c'); | |
59 | if( nerrors && nerrors <= 30 ){ /* give the compiler the benefit of the doubt */ | |
60 | fprintf( stderr, "cannot recover from earlier errors: goodbye!\n" ); | |
61 | } | |
62 | else { | |
63 | fprintf( stderr, "compiler error: " ); | |
64 | fprintf( stderr, s, a, b, c ); | |
65 | fprintf( stderr, "\n" ); | |
66 | } | |
67 | #ifdef BUFSTDERR | |
68 | fflush(stderr); | |
69 | #endif | |
70 | EXIT(1); | |
71 | } | |
72 | ||
73 | int Wflag = 0; /* Non-zero means do not print warnings */ | |
74 | ||
75 | /* VARARGS1 */ | |
76 | werror( s, a, b ) char *s; { /* warning */ | |
77 | if(Wflag) return; | |
78 | where('w'); | |
79 | fprintf( stderr, "warning: " ); | |
80 | fprintf( stderr, s, a, b ); | |
81 | fprintf( stderr, "\n" ); | |
82 | #ifdef BUFSTDERR | |
83 | fflush(stderr); | |
84 | #endif | |
85 | } | |
86 | ||
87 | tinit(){ /* initialize expression tree search */ | |
88 | ||
3464f46e | 89 | register NODE *p; |
ae51d042 RC |
90 | |
91 | for( p=node; p<= &node[TREESZ-1]; ++p ) p->in.op = FREE; | |
92 | lastfree = node; | |
93 | ||
94 | } | |
95 | ||
96 | # define TNEXT(p) (p== &node[TREESZ-1]?node:p+1) | |
97 | ||
98 | NODE * | |
99 | talloc(){ | |
3464f46e | 100 | register NODE *p, *q; |
ae51d042 RC |
101 | |
102 | q = lastfree; | |
103 | for( p = TNEXT(q); p!=q; p= TNEXT(p)) | |
79e776a3 DS |
104 | if( p->in.op ==FREE ) |
105 | return(lastfree=p); | |
ae51d042 RC |
106 | |
107 | cerror( "out of tree space; simplify expression"); | |
108 | /* NOTREACHED */ | |
109 | } | |
110 | ||
111 | tcheck(){ /* ensure that all nodes have been freed */ | |
112 | ||
3464f46e | 113 | register NODE *p; |
ae51d042 RC |
114 | |
115 | if( !nerrors ) | |
116 | for( p=node; p<= &node[TREESZ-1]; ++p ) | |
79e776a3 DS |
117 | if( p->in.op != FREE ) |
118 | cerror( "wasted space: %o", p ); | |
ae51d042 RC |
119 | tinit(); |
120 | #ifdef FLEXNAMES | |
121 | freetstr(); | |
122 | #endif | |
123 | } | |
124 | tfree( p ) NODE *p; { | |
125 | /* free the tree p */ | |
126 | extern tfree1(); | |
127 | ||
128 | if( p->in.op != FREE ) walkf( p, tfree1 ); | |
129 | ||
130 | } | |
131 | ||
132 | tfree1(p) NODE *p; { | |
133 | if( p == 0 ) cerror( "freeing blank tree!"); | |
134 | else p->in.op = FREE; | |
135 | } | |
136 | ||
137 | fwalk( t, f, down ) register NODE *t; int (*f)(); { | |
138 | ||
139 | int down1, down2; | |
140 | ||
141 | more: | |
142 | down1 = down2 = 0; | |
143 | ||
144 | (*f)( t, down, &down1, &down2 ); | |
145 | ||
146 | switch( optype( t->in.op ) ){ | |
147 | ||
148 | case BITYPE: | |
149 | fwalk( t->in.left, f, down1 ); | |
150 | t = t->in.right; | |
151 | down = down2; | |
152 | goto more; | |
153 | ||
154 | case UTYPE: | |
155 | t = t->in.left; | |
156 | down = down1; | |
157 | goto more; | |
158 | ||
159 | } | |
160 | } | |
161 | ||
3464f46e | 162 | #ifndef vax |
ae51d042 RC |
163 | walkf( t, f ) register NODE *t; int (*f)(); { |
164 | register opty; | |
165 | ||
166 | opty = optype(t->in.op); | |
167 | ||
168 | if( opty != LTYPE ) walkf( t->in.left, f ); | |
169 | if( opty == BITYPE ) walkf( t->in.right, f ); | |
170 | (*f)( t ); | |
171 | } | |
3464f46e | 172 | #else |
758d36cd | 173 | #define NR 32 |
3464f46e KM |
174 | |
175 | /* | |
176 | * Deliberately avoids recursion -- use this version on machines with | |
177 | * expensive procedure calls. | |
178 | */ | |
179 | walkf(t, f) | |
180 | register NODE *t; | |
181 | register int (*f)(); | |
182 | { | |
758d36cd DS |
183 | NODE *Aat[NR]; |
184 | int Aao[NR]; | |
3464f46e KM |
185 | register int i = 1; |
186 | register int opty = optype(t->in.op); | |
758d36cd DS |
187 | register NODE **at = Aat; |
188 | register int *ao = Aao; | |
3464f46e KM |
189 | |
190 | #define PUSH(dir, state) \ | |
191 | (ao[i] = state, at[i++] = t, t = t->in.dir, opty = optype(t->in.op)) | |
192 | #define POP() \ | |
193 | (opty = ao[--i], t = at[i]) | |
194 | ||
195 | do { | |
196 | switch (opty) { | |
197 | case LTYPE: (*f)(t); POP(); break; | |
198 | case UTYPE: PUSH(left, LTYPE); break; | |
199 | case BITYPE: PUSH(left, BITYPE+1); break; | |
200 | case BITYPE+1: PUSH(right, LTYPE); break; | |
201 | default: | |
202 | cerror("bad op type in walkf"); | |
203 | } | |
204 | if (i >= NR) { | |
205 | walkf(t, f); | |
206 | POP(); | |
207 | } | |
208 | } while (i > 0); | |
209 | } | |
210 | #undef NR | |
211 | #undef PUSH | |
212 | #undef POP | |
213 | #endif | |
ae51d042 RC |
214 | |
215 | ||
216 | ||
217 | int dope[ DSIZE ]; | |
218 | char *opst[DSIZE]; | |
219 | ||
220 | struct dopest { int dopeop; char opst[8]; int dopeval; } indope[] = { | |
221 | ||
222 | NAME, "NAME", LTYPE, | |
223 | STRING, "STRING", LTYPE, | |
224 | REG, "REG", LTYPE, | |
225 | OREG, "OREG", LTYPE, | |
226 | ICON, "ICON", LTYPE, | |
227 | FCON, "FCON", LTYPE, | |
228 | DCON, "DCON", LTYPE, | |
229 | CCODES, "CCODES", LTYPE, | |
230 | UNARY MINUS, "U-", UTYPE, | |
231 | UNARY MUL, "U*", UTYPE, | |
232 | UNARY AND, "U&", UTYPE, | |
233 | UNARY CALL, "UCALL", UTYPE|CALLFLG, | |
234 | UNARY FORTCALL, "UFCALL", UTYPE|CALLFLG, | |
235 | NOT, "!", UTYPE|LOGFLG, | |
236 | COMPL, "~", UTYPE, | |
237 | FORCE, "FORCE", UTYPE, | |
238 | INIT, "INIT", UTYPE, | |
239 | SCONV, "SCONV", UTYPE, | |
240 | PCONV, "PCONV", UTYPE, | |
241 | PLUS, "+", BITYPE|FLOFLG|SIMPFLG|COMMFLG, | |
242 | ASG PLUS, "+=", BITYPE|ASGFLG|ASGOPFLG|FLOFLG|SIMPFLG|COMMFLG, | |
243 | MINUS, "-", BITYPE|FLOFLG|SIMPFLG, | |
244 | ASG MINUS, "-=", BITYPE|FLOFLG|SIMPFLG|ASGFLG|ASGOPFLG, | |
245 | MUL, "*", BITYPE|FLOFLG|MULFLG, | |
246 | ASG MUL, "*=", BITYPE|FLOFLG|MULFLG|ASGFLG|ASGOPFLG, | |
247 | AND, "&", BITYPE|SIMPFLG|COMMFLG, | |
248 | ASG AND, "&=", BITYPE|SIMPFLG|COMMFLG|ASGFLG|ASGOPFLG, | |
249 | QUEST, "?", BITYPE, | |
250 | COLON, ":", BITYPE, | |
251 | ANDAND, "&&", BITYPE|LOGFLG, | |
252 | OROR, "||", BITYPE|LOGFLG, | |
253 | CM, ",", BITYPE, | |
254 | COMOP, ",OP", BITYPE, | |
255 | ASSIGN, "=", BITYPE|ASGFLG, | |
256 | DIV, "/", BITYPE|FLOFLG|MULFLG|DIVFLG, | |
257 | ASG DIV, "/=", BITYPE|FLOFLG|MULFLG|DIVFLG|ASGFLG|ASGOPFLG, | |
258 | MOD, "%", BITYPE|DIVFLG, | |
259 | ASG MOD, "%=", BITYPE|DIVFLG|ASGFLG|ASGOPFLG, | |
260 | LS, "<<", BITYPE|SHFFLG, | |
261 | ASG LS, "<<=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG, | |
262 | RS, ">>", BITYPE|SHFFLG, | |
263 | ASG RS, ">>=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG, | |
264 | OR, "|", BITYPE|COMMFLG|SIMPFLG, | |
265 | ASG OR, "|=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG, | |
266 | ER, "^", BITYPE|COMMFLG|SIMPFLG, | |
267 | ASG ER, "^=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG, | |
268 | INCR, "++", BITYPE|ASGFLG, | |
269 | DECR, "--", BITYPE|ASGFLG, | |
270 | STREF, "->", BITYPE, | |
271 | CALL, "CALL", BITYPE|CALLFLG, | |
272 | FORTCALL, "FCALL", BITYPE|CALLFLG, | |
273 | EQ, "==", BITYPE|LOGFLG, | |
274 | NE, "!=", BITYPE|LOGFLG, | |
275 | LE, "<=", BITYPE|LOGFLG, | |
276 | LT, "<", BITYPE|LOGFLG, | |
277 | GE, ">", BITYPE|LOGFLG, | |
278 | GT, ">", BITYPE|LOGFLG, | |
279 | UGT, "UGT", BITYPE|LOGFLG, | |
280 | UGE, "UGE", BITYPE|LOGFLG, | |
281 | ULT, "ULT", BITYPE|LOGFLG, | |
282 | ULE, "ULE", BITYPE|LOGFLG, | |
283 | #ifdef ARS | |
284 | ARS, "A>>", BITYPE, | |
285 | #endif | |
286 | TYPE, "TYPE", LTYPE, | |
287 | LB, "[", BITYPE, | |
288 | CBRANCH, "CBRANCH", BITYPE, | |
289 | FLD, "FLD", UTYPE, | |
290 | PMCONV, "PMCONV", BITYPE, | |
291 | PVCONV, "PVCONV", BITYPE, | |
292 | RETURN, "RETURN", BITYPE|ASGFLG|ASGOPFLG, | |
293 | CAST, "CAST", BITYPE|ASGFLG|ASGOPFLG, | |
294 | GOTO, "GOTO", UTYPE, | |
295 | STASG, "STASG", BITYPE|ASGFLG, | |
296 | STARG, "STARG", UTYPE, | |
297 | STCALL, "STCALL", BITYPE|CALLFLG, | |
298 | UNARY STCALL, "USTCALL", UTYPE|CALLFLG, | |
299 | ||
300 | -1, "", 0 | |
301 | }; | |
302 | ||
303 | mkdope(){ | |
304 | register struct dopest *q; | |
305 | ||
306 | for( q = indope; q->dopeop >= 0; ++q ){ | |
307 | dope[q->dopeop] = q->dopeval; | |
308 | opst[q->dopeop] = q->opst; | |
309 | } | |
310 | } | |
311 | # ifndef BUG4 | |
312 | tprint( t ) TWORD t; { /* output a nice description of the type of t */ | |
313 | ||
314 | static char * tnames[] = { | |
315 | "undef", | |
316 | "farg", | |
317 | "char", | |
318 | "short", | |
319 | "int", | |
320 | "long", | |
321 | "float", | |
322 | "double", | |
323 | "strty", | |
324 | "unionty", | |
325 | "enumty", | |
326 | "moety", | |
327 | "uchar", | |
328 | "ushort", | |
329 | "unsigned", | |
330 | "ulong", | |
331 | "?", "?" | |
332 | }; | |
333 | ||
334 | for(;; t = DECREF(t) ){ | |
335 | ||
336 | if( ISPTR(t) ) printf( "PTR " ); | |
337 | else if( ISFTN(t) ) printf( "FTN " ); | |
338 | else if( ISARY(t) ) printf( "ARY " ); | |
339 | else { | |
340 | printf( "%s", tnames[t] ); | |
341 | return; | |
342 | } | |
343 | } | |
344 | } | |
345 | # endif | |
346 | ||
347 | #ifdef FLEXNAMES | |
348 | #define NTSTRBUF 40 | |
349 | #define TSTRSZ 2048 | |
350 | char itstrbuf[TSTRSZ]; | |
351 | char *tstrbuf[NTSTRBUF] = { itstrbuf }; | |
352 | char **curtstr = tstrbuf; | |
353 | int tstrused; | |
3a4907d0 DS |
354 | char *malloc(); |
355 | char *strcpy(); | |
ae51d042 RC |
356 | |
357 | char * | |
358 | tstr(cp) | |
359 | register char *cp; | |
360 | { | |
361 | register int i = strlen(cp); | |
362 | register char *dp; | |
363 | ||
364 | if (tstrused + i >= TSTRSZ) { | |
365 | if (++curtstr >= &tstrbuf[NTSTRBUF]) | |
366 | cerror("out of temporary string space"); | |
367 | tstrused = 0; | |
368 | if (*curtstr == 0) { | |
3a4907d0 | 369 | dp = malloc(TSTRSZ); |
ae51d042 RC |
370 | if (dp == 0) |
371 | cerror("out of memory (tstr)"); | |
372 | *curtstr = dp; | |
373 | } | |
374 | } | |
3a4907d0 | 375 | (void) strcpy(dp = *curtstr+tstrused, cp); |
ae51d042 RC |
376 | tstrused += i + 1; |
377 | return (dp); | |
378 | } | |
379 | #endif |