1 /* common.c 4.5 88/05/11 */
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
caloff()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 */
uerror(s,a)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 */
cerror(s,a,b,c)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 */
werror(s,a,b)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
tinit()87 tinit(){ /* initialize expression tree search */
88
89 register NODE *p;
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 *
talloc()99 talloc(){
100 register NODE *p, *q;
101
102 q = lastfree;
103 for( p = TNEXT(q); p!=q; p= TNEXT(p))
104 if( p->in.op ==FREE )
105 return(lastfree=p);
106
107 cerror( "out of tree space; simplify expression");
108 /* NOTREACHED */
109 }
110
tcheck()111 tcheck(){ /* ensure that all nodes have been freed */
112
113 register NODE *p;
114
115 if( !nerrors )
116 for( p=node; p<= &node[TREESZ-1]; ++p )
117 if( p->in.op != FREE )
118 cerror( "wasted space: %o", p );
119 tinit();
120 #ifdef FLEXNAMES
121 freetstr();
122 #endif
123 }
tfree(p)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
tfree1(p)132 tfree1(p) NODE *p; {
133 if( p == 0 ) cerror( "freeing blank tree!");
134 else p->in.op = FREE;
135 }
136
fwalk(t,f,down)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
162 #ifndef vax
walkf(t,f)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 }
172 #else
173 #define NR 32
174
175 /*
176 * Deliberately avoids recursion -- use this version on machines with
177 * expensive procedure calls.
178 */
walkf(t,f)179 walkf(t, f)
180 register NODE *t;
181 register int (*f)();
182 {
183 NODE *Aat[NR];
184 int Aao[NR];
185 register int i = 1;
186 register int opty = optype(t->in.op);
187 register NODE **at = Aat;
188 register int *ao = Aao;
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
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
mkdope()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
tprint(t)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;
354 char *malloc();
355 char *strcpy();
356
357 char *
tstr(cp)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) {
369 dp = malloc(TSTRSZ);
370 if (dp == 0)
371 cerror("out of memory (tstr)");
372 *curtstr = dp;
373 }
374 }
375 (void) strcpy(dp = *curtstr+tstrused, cp);
376 tstrused += i + 1;
377 return (dp);
378 }
379 #endif
380