|
|
1.1 root 1: /* @(#)common 1.1 86/02/03 SMI */
2:
3: #ifdef FORT
4: #undef BUFSTDERR
5: #endif
6: #ifndef ONEPASS
7: #undef BUFSTDERR
8: #endif
9: # ifndef EXIT
10: # define EXIT exit
11: # endif
12:
13: int nerrors = 0; /* number of errors */
14: int errline = -1; /* where last error took place */
15:
16: extern unsigned int offsz;
17:
18: unsigned caloff(){
19: register i;
20: unsigned int temp;
21: unsigned int off;
22: temp = 1;
23: i = 0;
24: do {
25: temp <<= 1;
26: ++i;
27: } while( temp > 0 );
28: off = 1 << (i-1);
29: return (off);
30: }
31:
32: /* VARARGS1 */
33: uerror( s, a ) char *s; { /* nonfatal error message */
34: /* the routine where is different for pass 1 and pass 2;
35: /* it tells where the error took place */
36:
37: fflush( stdout );
38: ++nerrors;
39: errline = lineno;
40: where('u');
41: fprintf( stderr, s, a );
42: fprintf( stderr, "\n" );
43: #ifdef BUFSTDERR
44: fflush(stderr);
45: #endif
46: if( nerrors > 30 ) fatal( "too many errors");
47: }
48:
49: /* VARARGS1 */
50: cerror( s, a, b, c ) char *s; { /* compiler error: die */
51: fflush( stdout );
52: where('c');
53: if( nerrors && nerrors <= 30 ){ /* give the compiler the benefit of the doubt */
54: fprintf( stderr, "cannot recover from earlier errors: goodbye!\n" );
55: }
56: else {
57: fprintf( stderr, "compiler error: " );
58: fprintf( stderr, s, a, b, c );
59: fprintf( stderr, "\n" );
60: }
61: #ifdef BUFSTDERR
62: fflush(stderr);
63: #endif
64: EXIT(1);
65: }
66:
67: fatal( s, a, b, c ) char *s; { /* non-compiler but fatal error: die */
68: fflush( stdout );
69: where('f');
70: fprintf( stderr, "fatal error: " );
71: fprintf( stderr, s, a, b, c );
72: fprintf( stderr, "\n" );
73: #ifdef BUFSTDERR
74: fflush(stderr);
75: #endif
76: EXIT(1);
77: }
78: int Wflag = 0; /* Non-zero means do not print warnings */
79:
80: /* VARARGS1 */
81: werror( s, a, b ) char *s; { /* warning */
82: if(Wflag) return;
83: fflush( stdout );
84: where('w');
85: fprintf( stderr, "warning: " );
86: fprintf( stderr, s, a, b );
87: fprintf( stderr, "\n" );
88: #ifdef BUFSTDERR
89: fflush(stderr);
90: #endif
91: }
92:
93: /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
94:
95: #ifdef TESTALLOC
96: /*
97: * this enables us to test
98: * tree allocation without having
99: * to construct bizarre test programs
100: */
101: #undef TREESZ
102: #define TREESZ 16
103: #endif TESTALLOC
104:
105: #define MAXTSEG 64 /* max # of tree segments */
106: static NODE treespace[TREESZ]; /* initial tree space */
107: static NODE *treeseg[MAXTSEG] = {treespace};/* table of seg pointers */
108: static NODE **activeseg = &treeseg[0]; /* ptr to active seg slot */
109: static NODE *node = treespace; /* ptr to active segment */
110: static NODE *nextfree = treespace; /* ptr to next free node */
111: static int nsegs = 1; /* # of allocated segments */
112: static int recycling = 0; /* =1 if using old nodes */
113:
114: /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
115:
116: static NODE *
117: tsegalloc()
118: {
119: NODE *newseg;
120: if ( activeseg == &treeseg[nsegs-1] ) {
121: /*
122: * no unused segments; allocate a new one
123: */
124: if (nsegs == MAXTSEG) {
125: cerror("out of tree space; try simplifying");
126: /*NOTREACHED*/
127: }
128: newseg = (NODE *)malloc(TREESZ*sizeof(NODE));
129: *++activeseg = newseg;
130: nsegs++;
131: } else {
132: /*
133: * segment already allocated; use it
134: */
135: newseg = *++activeseg;
136: if (newseg == NIL) {
137: cerror("tree space allocation");
138: /*NOTREACHED*/
139: }
140: }
141: return newseg;
142: }
143:
144: /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
145:
146: tinit()
147: {
148: /* initialize tree space allocation */
149: activeseg = &treeseg[0]; /* ptr to active seg slot */
150: node = *activeseg; /* ptr to active segment */
151: nextfree = node; /* ptr to next free node */
152: recycling = 0;
153: }
154:
155: /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
156:
157: #define TNEXT(p) (p == &node[TREESZ]? node : p+1)
158:
159: /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
160:
161: NODE *
162: talloc()
163: {
164: register NODE *p, *q;
165: static NODE *lastfrag;
166:
167: if ( nextfree < &node[TREESZ] )
168: return nextfree++;
169: if ( !recycling ) {
170: recycling = 1;
171: lastfrag = node;
172: }
173: q = lastfrag;
174: for( p = TNEXT(q); p != q; p = TNEXT(p) ) {
175: if (p->tn.op == FREE) {
176: return lastfrag = p;
177: }
178: }
179: /*
180: * current tree space segment is full;
181: * get a new one.
182: */
183: nextfree = node = tsegalloc();
184: recycling = 0;
185: return nextfree++;
186: }
187:
188: /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
189:
190: tcheck()
191: {
192: /*
193: * ensure that all nodes have been freed. Note that in the
194: * C compiler, some nodes remain active until the end of the
195: * current function, so this should not be called until then.
196: * In the backend-only configuration (fort) this is called
197: * on a statement-by-statement basis.
198: */
199:
200: register NODE *p;
201: register NODE *limit;
202: NODE **seg;
203:
204: if( !nerrors ) {
205: /*
206: * all segments below the top one must be scanned
207: * from beginning to end. The top one need only
208: * be scanned up to the high-water mark (nextfree)
209: */
210: for( seg = &treeseg[0]; seg < activeseg; seg++ ) {
211: limit = *seg + TREESZ;
212: for (p = *seg; p < limit; p++ ) {
213: if( p->in.op != FREE ) {
214: cerror( "wasted space: %#x", p );
215: }
216: }
217: }
218: limit = nextfree;
219: for( p=node; p < limit; ++p ) {
220: if( p->in.op != FREE ) {
221: cerror( "wasted space: %#x", p );
222: }
223: }
224: }
225: tinit();
226: #ifdef FLEXNAMES
227: freetstr();
228: #endif
229: }
230:
231: /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
232:
233: tfree(p)
234: register NODE *p;
235: {
236: if (p == NIL)
237: return;
238: again:
239: switch(optype(p->in.op)) {
240: case UTYPE:
241: tfree(p->in.left);
242: /*fall through*/
243: case LTYPE:
244: p->in.op = FREE;
245: return;
246: case BITYPE:
247: tfree(p->in.left);
248: p->in.op = FREE;
249: p = p->in.right;
250: goto again;
251: }
252: }
253:
254: fwalk( t, f, down ) register NODE *t; int (*f)(); {
255:
256: int down1, down2;
257:
258: more:
259: down1 = down2 = 0;
260:
261: (*f)( t, down, &down1, &down2 );
262:
263: switch( optype( t->in.op ) ){
264:
265: case BITYPE:
266: fwalk( t->in.left, f, down1 );
267: t = t->in.right;
268: down = down2;
269: goto more;
270:
271: case UTYPE:
272: t = t->in.left;
273: down = down1;
274: goto more;
275:
276: }
277: }
278:
279: walkf( t, f )
280: register NODE *t;
281: int (*f)();
282: {
283: switch(optype(t->in.op)) {
284: case LTYPE:
285: break;
286: case UTYPE:
287: walkf(t->in.left, f);
288: break;
289: default:
290: walkf(t->in.left, f);
291: walkf(t->in.right, f);
292: break;
293: }
294: (*f)( t );
295: }
296:
297: int dope[ DSIZE ];
298: char *opst[DSIZE];
299:
300: struct dopest { int dopeop; char opst[8]; int dopeval; } indope[] = {
301:
302: NAME, "NAME", LTYPE,
303: STRING, "STRING", LTYPE,
304: REG, "REG", LTYPE,
305: OREG, "OREG", LTYPE,
306: ICON, "ICON", LTYPE,
307: FCON, "FCON", LTYPE,
308: FCCODES, "FCCODES", LTYPE,
309: CCODES, "CCODES", LTYPE,
310: UNARY MINUS, "U-", UTYPE,
311: UNARY MUL, "U*", UTYPE,
312: UNARY AND, "U&", UTYPE,
313: UNARY CALL, "UCALL", UTYPE|CALLFLG,
314: UNARY FORTCALL, "UFCALL", UTYPE|CALLFLG,
315: NOT, "!", UTYPE|LOGFLG,
316: COMPL, "~", UTYPE,
317: FORCE, "FORCE", UTYPE,
318: INIT, "INIT", UTYPE,
319: SCONV, "SCONV", UTYPE,
320: PCONV, "PCONV", UTYPE,
321: PLUS, "+", BITYPE|FLOFLG|SIMPFLG|COMMFLG,
322: ASG PLUS, "+=", BITYPE|ASGFLG|ASGOPFLG|FLOFLG|SIMPFLG|COMMFLG,
323: MINUS, "-", BITYPE|FLOFLG|SIMPFLG,
324: ASG MINUS, "-=", BITYPE|FLOFLG|SIMPFLG|ASGFLG|ASGOPFLG,
325: MUL, "*", BITYPE|FLOFLG|MULFLG,
326: ASG MUL, "*=", BITYPE|FLOFLG|MULFLG|ASGFLG|ASGOPFLG,
327: AND, "&", BITYPE|SIMPFLG|COMMFLG,
328: ASG AND, "&=", BITYPE|SIMPFLG|COMMFLG|ASGFLG|ASGOPFLG,
329: QUEST, "?", BITYPE,
330: COLON, ":", BITYPE,
331: ANDAND, "&&", BITYPE|LOGFLG,
332: OROR, "||", BITYPE|LOGFLG,
333: CM, ",", BITYPE,
334: COMOP, ",OP", BITYPE,
335: ASSIGN, "=", BITYPE|ASGFLG,
336: DIV, "/", BITYPE|FLOFLG|MULFLG|DIVFLG,
337: ASG DIV, "/=", BITYPE|FLOFLG|MULFLG|DIVFLG|ASGFLG|ASGOPFLG,
338: MOD, "%", BITYPE|DIVFLG,
339: ASG MOD, "%=", BITYPE|DIVFLG|ASGFLG|ASGOPFLG,
340: LS, "<<", BITYPE|SHFFLG,
341: ASG LS, "<<=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG,
342: RS, ">>", BITYPE|SHFFLG,
343: ASG RS, ">>=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG,
344: OR, "|", BITYPE|COMMFLG|SIMPFLG,
345: ASG OR, "|=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG,
346: #ifdef VAX
347: ER, "^", BITYPE|COMMFLG|SIMPFLG,
348: ASG ER, "^=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG,
349: #else
350: ER, "^", BITYPE|COMMFLG,
351: ASG ER, "^=", BITYPE|COMMFLG|ASGFLG|ASGOPFLG,
352: #endif
353: INCR, "++", BITYPE|ASGFLG,
354: DECR, "--", BITYPE|ASGFLG,
355: STREF, "->", BITYPE,
356: CALL, "CALL", BITYPE|CALLFLG,
357: FORTCALL, "FCALL", BITYPE|CALLFLG,
358: EQ, "==", BITYPE|LOGFLG,
359: NE, "!=", BITYPE|LOGFLG,
360: LE, "<=", BITYPE|LOGFLG,
361: LT, "<", BITYPE|LOGFLG,
362: GE, ">", BITYPE|LOGFLG,
363: GT, ">", BITYPE|LOGFLG,
364: UGT, "UGT", BITYPE|LOGFLG,
365: UGE, "UGE", BITYPE|LOGFLG,
366: ULT, "ULT", BITYPE|LOGFLG,
367: ULE, "ULE", BITYPE|LOGFLG,
368: ARS, "A>>", BITYPE,
369: TYPE, "TYPE", LTYPE,
370: LB, "[", BITYPE,
371: CBRANCH, "CBRANCH", BITYPE,
372: FLD, "FLD", UTYPE,
373: PMCONV, "PMCONV", BITYPE,
374: PVCONV, "PVCONV", BITYPE,
375: RETURN, "RETURN", BITYPE|ASGFLG|ASGOPFLG,
376: CAST, "CAST", BITYPE|ASGFLG|ASGOPFLG,
377: GOTO, "GOTO", UTYPE,
378: STASG, "STASG", BITYPE|ASGFLG,
379: STARG, "STARG", UTYPE,
380: STCALL, "STCALL", BITYPE|CALLFLG,
381: UNARY STCALL, "USTCALL", UTYPE|CALLFLG,
382: CHK, "CHK", BITYPE,
383: FABS, "FABS", UTYPE|INTRFLG,
384: FCOS, "FCOS", UTYPE|INTRFLG,
385: FSIN, "FSIN", UTYPE|INTRFLG,
386: FTAN, "FTAN", UTYPE|INTRFLG,
387: FACOS, "FACOS", UTYPE|INTRFLG,
388: FASIN, "FASIN", UTYPE|INTRFLG,
389: FATAN, "FATAN", UTYPE|INTRFLG,
390: FCOSH, "FCOSH", UTYPE|INTRFLG,
391: FSINH, "FSINH", UTYPE|INTRFLG,
392: FTANH, "FTANH", UTYPE|INTRFLG,
393: FEXP, "FEXP", UTYPE|INTRFLG,
394: F10TOX, "F10TOX", UTYPE|INTRFLG,
395: F2TOX, "F2TOX", UTYPE|INTRFLG,
396: FLOGN, "FLOGN", UTYPE|INTRFLG,
397: FLOG10, "FLOG10", UTYPE|INTRFLG,
398: FLOG2, "FLOG2", UTYPE|INTRFLG,
399: FSQR, "FSQR", UTYPE|INTRFLG,
400: FSQRT, "FSQRT", UTYPE|INTRFLG,
401: FAINT, "FAINT", UTYPE|INTRFLG,
402: FANINT, "FANINT", UTYPE|INTRFLG,
403: FNINT, "FNINT", UTYPE,
404: -1, "", 0
405: };
406:
407: mkdope(){
408: register struct dopest *q;
409:
410: for( q = indope; q->dopeop >= 0; ++q ){
411: dope[q->dopeop] = q->dopeval;
412: opst[q->dopeop] = q->opst;
413: }
414: }
415: # ifndef BUG4
416: tprint( t ) TWORD t; { /* output a nice description of the type of t */
417:
418: static char * tnames[] = {
419: "undef",
420: "farg",
421: "char",
422: "short",
423: "int",
424: "long",
425: "float",
426: "double",
427: "strty",
428: "unionty",
429: "enumty",
430: "moety",
431: "uchar",
432: "ushort",
433: "unsigned",
434: "ulong",
435: "?", "?"
436: };
437:
438: for(;; t = DECREF(t) ){
439:
440: if( ISPTR(t) ) printf( "PTR " );
441: else if( ISFTN(t) ) printf( "FTN " );
442: else if( ISARY(t) ) printf( "ARY " );
443: else {
444: printf( "%s", tnames[t] );
445: return;
446: }
447: }
448: }
449: # endif
450:
451: #ifdef FLEXNAMES
452: #define NTSTRBUF 40
453: #define TSTRSZ 2048
454: char itstrbuf[TSTRSZ];
455: char *tstrbuf[NTSTRBUF] = { itstrbuf };
456: char **curtstr = tstrbuf;
457: int tstrused;
458:
459: char *
460: tstr(cp)
461: register char *cp;
462: {
463: register int i = strlen(cp);
464: register char *dp;
465:
466: if (tstrused + i >= TSTRSZ) {
467: if (++curtstr >= &tstrbuf[NTSTRBUF])
468: cerror("out of temporary string space");
469: tstrused = 0;
470: if (*curtstr == 0) {
471: dp = (char *)malloc(TSTRSZ);
472: *curtstr = dp;
473: }
474: }
475: strcpy(dp = *curtstr+tstrused, cp);
476: tstrused += i + 1;
477: return (dp);
478: }
479: #endif
480:
481: #ifdef malloc
482: #undef malloc
483: #endif malloc
484:
485: /*
486: * NOTE: malloc is defined as malloc_with_care everywhere but here.
487: */
488: char *
489: malloc_with_care(nbytes)
490: {
491: char *p;
492:
493: p = (char*)malloc(nbytes);
494: if (p == NULL) {
495: fatal("memory allocation exceeded");
496: exit(1);
497: }
498: return(p);
499: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.