|
|
1.1 root 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:
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:
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 *
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:
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: }
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:
162: #ifndef vax
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: */
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:
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;
354: char *malloc();
355: char *strcpy();
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) {
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.