1 /* common.c 4.3 87/12/09 */ 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 ) return(lastfree=p); 105 106 cerror( "out of tree space; simplify expression"); 107 /* NOTREACHED */ 108 } 109 110 tcheck(){ /* ensure that all nodes have been freed */ 111 112 register NODE *p; 113 114 if( !nerrors ) 115 for( p=node; p<= &node[TREESZ-1]; ++p ) 116 if( p->in.op != FREE ) cerror( "wasted space: %o", p ); 117 tinit(); 118 #ifdef FLEXNAMES 119 freetstr(); 120 #endif 121 } 122 tfree( p ) NODE *p; { 123 /* free the tree p */ 124 extern tfree1(); 125 126 if( p->in.op != FREE ) walkf( p, tfree1 ); 127 128 } 129 130 tfree1(p) NODE *p; { 131 if( p == 0 ) cerror( "freeing blank tree!"); 132 else p->in.op = FREE; 133 } 134 135 fwalk( t, f, down ) register NODE *t; int (*f)(); { 136 137 int down1, down2; 138 139 more: 140 down1 = down2 = 0; 141 142 (*f)( t, down, &down1, &down2 ); 143 144 switch( optype( t->in.op ) ){ 145 146 case BITYPE: 147 fwalk( t->in.left, f, down1 ); 148 t = t->in.right; 149 down = down2; 150 goto more; 151 152 case UTYPE: 153 t = t->in.left; 154 down = down1; 155 goto more; 156 157 } 158 } 159 160 #ifndef vax 161 walkf( t, f ) register NODE *t; int (*f)(); { 162 register opty; 163 164 opty = optype(t->in.op); 165 166 if( opty != LTYPE ) walkf( t->in.left, f ); 167 if( opty == BITYPE ) walkf( t->in.right, f ); 168 (*f)( t ); 169 } 170 #else 171 #define NR 100 172 173 /* 174 * Deliberately avoids recursion -- use this version on machines with 175 * expensive procedure calls. 176 */ 177 walkf(t, f) 178 register NODE *t; 179 register int (*f)(); 180 { 181 register int i = 1; 182 register int opty = optype(t->in.op); 183 static NODE *at[NR]; 184 static int ao[NR]; 185 186 #define PUSH(dir, state) \ 187 (ao[i] = state, at[i++] = t, t = t->in.dir, opty = optype(t->in.op)) 188 #define POP() \ 189 (opty = ao[--i], t = at[i]) 190 191 do { 192 switch (opty) { 193 case LTYPE: (*f)(t); POP(); break; 194 case UTYPE: PUSH(left, LTYPE); break; 195 case BITYPE: PUSH(left, BITYPE+1); break; 196 case BITYPE+1: PUSH(right, LTYPE); break; 197 default: 198 cerror("bad op type in walkf"); 199 } 200 if (i >= NR) { 201 walkf(t, f); 202 POP(); 203 } 204 } while (i > 0); 205 } 206 #undef NR 207 #undef PUSH 208 #undef POP 209 #endif 210 211 212 213 int dope[ DSIZE ]; 214 char *opst[DSIZE]; 215 216 struct dopest { int dopeop; char opst[8]; int dopeval; } indope[] = { 217 218 NAME, "NAME", LTYPE, 219 STRING, "STRING", LTYPE, 220 REG, "REG", LTYPE, 221 OREG, "OREG", LTYPE, 222 ICON, "ICON", LTYPE, 223 FCON, "FCON", LTYPE, 224 DCON, "DCON", LTYPE, 225 CCODES, "CCODES", LTYPE, 226 UNARY MINUS, "U-", UTYPE, 227 UNARY MUL, "U*", UTYPE, 228 UNARY AND, "U&", UTYPE, 229 UNARY CALL, "UCALL", UTYPE|CALLFLG, 230 UNARY FORTCALL, "UFCALL", UTYPE|CALLFLG, 231 NOT, "!", UTYPE|LOGFLG, 232 COMPL, "~", UTYPE, 233 FORCE, "FORCE", UTYPE, 234 INIT, "INIT", UTYPE, 235 SCONV, "SCONV", UTYPE, 236 PCONV, "PCONV", UTYPE, 237 PLUS, "+", BITYPE|FLOFLG|SIMPFLG|COMMFLG, 238 ASG PLUS, "+=", BITYPE|ASGFLG|ASGOPFLG|FLOFLG|SIMPFLG|COMMFLG, 239 MINUS, "-", BITYPE|FLOFLG|SIMPFLG, 240 ASG MINUS, "-=", BITYPE|FLOFLG|SIMPFLG|ASGFLG|ASGOPFLG, 241 MUL, "*", BITYPE|FLOFLG|MULFLG, 242 ASG MUL, "*=", BITYPE|FLOFLG|MULFLG|ASGFLG|ASGOPFLG, 243 AND, "&", BITYPE|SIMPFLG|COMMFLG, 244 ASG AND, "&=", BITYPE|SIMPFLG|COMMFLG|ASGFLG|ASGOPFLG, 245 QUEST, "?", BITYPE, 246 COLON, ":", BITYPE, 247 ANDAND, "&&", BITYPE|LOGFLG, 248 OROR, "||", BITYPE|LOGFLG, 249 CM, ",", BITYPE, 250 COMOP, ",OP", BITYPE, 251 ASSIGN, "=", BITYPE|ASGFLG, 252 DIV, "/", BITYPE|FLOFLG|MULFLG|DIVFLG, 253 ASG DIV, "/=", BITYPE|FLOFLG|MULFLG|DIVFLG|ASGFLG|ASGOPFLG, 254 MOD, "%", BITYPE|DIVFLG, 255 ASG MOD, "%=", BITYPE|DIVFLG|ASGFLG|ASGOPFLG, 256 LS, "<<", BITYPE|SHFFLG, 257 ASG LS, "<<=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG, 258 RS, ">>", BITYPE|SHFFLG, 259 ASG RS, ">>=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG, 260 OR, "|", BITYPE|COMMFLG|SIMPFLG, 261 ASG OR, "|=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG, 262 ER, "^", BITYPE|COMMFLG|SIMPFLG, 263 ASG ER, "^=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG, 264 INCR, "++", BITYPE|ASGFLG, 265 DECR, "--", BITYPE|ASGFLG, 266 STREF, "->", BITYPE, 267 CALL, "CALL", BITYPE|CALLFLG, 268 FORTCALL, "FCALL", BITYPE|CALLFLG, 269 EQ, "==", BITYPE|LOGFLG, 270 NE, "!=", BITYPE|LOGFLG, 271 LE, "<=", BITYPE|LOGFLG, 272 LT, "<", BITYPE|LOGFLG, 273 GE, ">", BITYPE|LOGFLG, 274 GT, ">", BITYPE|LOGFLG, 275 UGT, "UGT", BITYPE|LOGFLG, 276 UGE, "UGE", BITYPE|LOGFLG, 277 ULT, "ULT", BITYPE|LOGFLG, 278 ULE, "ULE", BITYPE|LOGFLG, 279 #ifdef ARS 280 ARS, "A>>", BITYPE, 281 #endif 282 TYPE, "TYPE", LTYPE, 283 LB, "[", BITYPE, 284 CBRANCH, "CBRANCH", BITYPE, 285 FLD, "FLD", UTYPE, 286 PMCONV, "PMCONV", BITYPE, 287 PVCONV, "PVCONV", BITYPE, 288 RETURN, "RETURN", BITYPE|ASGFLG|ASGOPFLG, 289 CAST, "CAST", BITYPE|ASGFLG|ASGOPFLG, 290 GOTO, "GOTO", UTYPE, 291 STASG, "STASG", BITYPE|ASGFLG, 292 STARG, "STARG", UTYPE, 293 STCALL, "STCALL", BITYPE|CALLFLG, 294 UNARY STCALL, "USTCALL", UTYPE|CALLFLG, 295 296 -1, "", 0 297 }; 298 299 mkdope(){ 300 register struct dopest *q; 301 302 for( q = indope; q->dopeop >= 0; ++q ){ 303 dope[q->dopeop] = q->dopeval; 304 opst[q->dopeop] = q->opst; 305 } 306 } 307 # ifndef BUG4 308 tprint( t ) TWORD t; { /* output a nice description of the type of t */ 309 310 static char * tnames[] = { 311 "undef", 312 "farg", 313 "char", 314 "short", 315 "int", 316 "long", 317 "float", 318 "double", 319 "strty", 320 "unionty", 321 "enumty", 322 "moety", 323 "uchar", 324 "ushort", 325 "unsigned", 326 "ulong", 327 "?", "?" 328 }; 329 330 for(;; t = DECREF(t) ){ 331 332 if( ISPTR(t) ) printf( "PTR " ); 333 else if( ISFTN(t) ) printf( "FTN " ); 334 else if( ISARY(t) ) printf( "ARY " ); 335 else { 336 printf( "%s", tnames[t] ); 337 return; 338 } 339 } 340 } 341 # endif 342 343 #ifdef FLEXNAMES 344 #define NTSTRBUF 40 345 #define TSTRSZ 2048 346 char itstrbuf[TSTRSZ]; 347 char *tstrbuf[NTSTRBUF] = { itstrbuf }; 348 char **curtstr = tstrbuf; 349 int tstrused; 350 char *malloc(); 351 char *strcpy(); 352 353 char * 354 tstr(cp) 355 register char *cp; 356 { 357 register int i = strlen(cp); 358 register char *dp; 359 360 if (tstrused + i >= TSTRSZ) { 361 if (++curtstr >= &tstrbuf[NTSTRBUF]) 362 cerror("out of temporary string space"); 363 tstrused = 0; 364 if (*curtstr == 0) { 365 dp = malloc(TSTRSZ); 366 if (dp == 0) 367 cerror("out of memory (tstr)"); 368 *curtstr = dp; 369 } 370 } 371 (void) strcpy(dp = *curtstr+tstrused, cp); 372 tstrused += i + 1; 373 return (dp); 374 } 375 #endif 376