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 380