1 /* common.c 4.1 85/03/19 */ 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 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 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 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 walkf( t, f ) register NODE *t; int (*f)(); { 161 register opty; 162 163 opty = optype(t->in.op); 164 165 if( opty != LTYPE ) walkf( t->in.left, f ); 166 if( opty == BITYPE ) walkf( t->in.right, f ); 167 (*f)( t ); 168 } 169 170 171 172 int dope[ DSIZE ]; 173 char *opst[DSIZE]; 174 175 struct dopest { int dopeop; char opst[8]; int dopeval; } indope[] = { 176 177 NAME, "NAME", LTYPE, 178 STRING, "STRING", LTYPE, 179 REG, "REG", LTYPE, 180 OREG, "OREG", LTYPE, 181 ICON, "ICON", LTYPE, 182 FCON, "FCON", LTYPE, 183 DCON, "DCON", LTYPE, 184 CCODES, "CCODES", LTYPE, 185 UNARY MINUS, "U-", UTYPE, 186 UNARY MUL, "U*", UTYPE, 187 UNARY AND, "U&", UTYPE, 188 UNARY CALL, "UCALL", UTYPE|CALLFLG, 189 UNARY FORTCALL, "UFCALL", UTYPE|CALLFLG, 190 NOT, "!", UTYPE|LOGFLG, 191 COMPL, "~", UTYPE, 192 FORCE, "FORCE", UTYPE, 193 INIT, "INIT", UTYPE, 194 SCONV, "SCONV", UTYPE, 195 PCONV, "PCONV", UTYPE, 196 PLUS, "+", BITYPE|FLOFLG|SIMPFLG|COMMFLG, 197 ASG PLUS, "+=", BITYPE|ASGFLG|ASGOPFLG|FLOFLG|SIMPFLG|COMMFLG, 198 MINUS, "-", BITYPE|FLOFLG|SIMPFLG, 199 ASG MINUS, "-=", BITYPE|FLOFLG|SIMPFLG|ASGFLG|ASGOPFLG, 200 MUL, "*", BITYPE|FLOFLG|MULFLG, 201 ASG MUL, "*=", BITYPE|FLOFLG|MULFLG|ASGFLG|ASGOPFLG, 202 AND, "&", BITYPE|SIMPFLG|COMMFLG, 203 ASG AND, "&=", BITYPE|SIMPFLG|COMMFLG|ASGFLG|ASGOPFLG, 204 QUEST, "?", BITYPE, 205 COLON, ":", BITYPE, 206 ANDAND, "&&", BITYPE|LOGFLG, 207 OROR, "||", BITYPE|LOGFLG, 208 CM, ",", BITYPE, 209 COMOP, ",OP", BITYPE, 210 ASSIGN, "=", BITYPE|ASGFLG, 211 DIV, "/", BITYPE|FLOFLG|MULFLG|DIVFLG, 212 ASG DIV, "/=", BITYPE|FLOFLG|MULFLG|DIVFLG|ASGFLG|ASGOPFLG, 213 MOD, "%", BITYPE|DIVFLG, 214 ASG MOD, "%=", BITYPE|DIVFLG|ASGFLG|ASGOPFLG, 215 LS, "<<", BITYPE|SHFFLG, 216 ASG LS, "<<=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG, 217 RS, ">>", BITYPE|SHFFLG, 218 ASG RS, ">>=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG, 219 OR, "|", BITYPE|COMMFLG|SIMPFLG, 220 ASG OR, "|=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG, 221 ER, "^", BITYPE|COMMFLG|SIMPFLG, 222 ASG ER, "^=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG, 223 INCR, "++", BITYPE|ASGFLG, 224 DECR, "--", BITYPE|ASGFLG, 225 STREF, "->", BITYPE, 226 CALL, "CALL", BITYPE|CALLFLG, 227 FORTCALL, "FCALL", BITYPE|CALLFLG, 228 EQ, "==", BITYPE|LOGFLG, 229 NE, "!=", BITYPE|LOGFLG, 230 LE, "<=", BITYPE|LOGFLG, 231 LT, "<", BITYPE|LOGFLG, 232 GE, ">", BITYPE|LOGFLG, 233 GT, ">", BITYPE|LOGFLG, 234 UGT, "UGT", BITYPE|LOGFLG, 235 UGE, "UGE", BITYPE|LOGFLG, 236 ULT, "ULT", BITYPE|LOGFLG, 237 ULE, "ULE", BITYPE|LOGFLG, 238 #ifdef ARS 239 ARS, "A>>", BITYPE, 240 #endif 241 TYPE, "TYPE", LTYPE, 242 LB, "[", BITYPE, 243 CBRANCH, "CBRANCH", BITYPE, 244 FLD, "FLD", UTYPE, 245 PMCONV, "PMCONV", BITYPE, 246 PVCONV, "PVCONV", BITYPE, 247 RETURN, "RETURN", BITYPE|ASGFLG|ASGOPFLG, 248 CAST, "CAST", BITYPE|ASGFLG|ASGOPFLG, 249 GOTO, "GOTO", UTYPE, 250 STASG, "STASG", BITYPE|ASGFLG, 251 STARG, "STARG", UTYPE, 252 STCALL, "STCALL", BITYPE|CALLFLG, 253 UNARY STCALL, "USTCALL", UTYPE|CALLFLG, 254 255 -1, "", 0 256 }; 257 258 mkdope(){ 259 register struct dopest *q; 260 261 for( q = indope; q->dopeop >= 0; ++q ){ 262 dope[q->dopeop] = q->dopeval; 263 opst[q->dopeop] = q->opst; 264 } 265 } 266 # ifndef BUG4 267 tprint( t ) TWORD t; { /* output a nice description of the type of t */ 268 269 static char * tnames[] = { 270 "undef", 271 "farg", 272 "char", 273 "short", 274 "int", 275 "long", 276 "float", 277 "double", 278 "strty", 279 "unionty", 280 "enumty", 281 "moety", 282 "uchar", 283 "ushort", 284 "unsigned", 285 "ulong", 286 "?", "?" 287 }; 288 289 for(;; t = DECREF(t) ){ 290 291 if( ISPTR(t) ) printf( "PTR " ); 292 else if( ISFTN(t) ) printf( "FTN " ); 293 else if( ISARY(t) ) printf( "ARY " ); 294 else { 295 printf( "%s", tnames[t] ); 296 return; 297 } 298 } 299 } 300 # endif 301 302 #ifdef FLEXNAMES 303 #define NTSTRBUF 40 304 #define TSTRSZ 2048 305 char itstrbuf[TSTRSZ]; 306 char *tstrbuf[NTSTRBUF] = { itstrbuf }; 307 char **curtstr = tstrbuf; 308 int tstrused; 309 310 char * 311 tstr(cp) 312 register char *cp; 313 { 314 register int i = strlen(cp); 315 register char *dp; 316 317 if (tstrused + i >= TSTRSZ) { 318 if (++curtstr >= &tstrbuf[NTSTRBUF]) 319 cerror("out of temporary string space"); 320 tstrused = 0; 321 if (*curtstr == 0) { 322 dp = (char *)malloc(TSTRSZ); 323 if (dp == 0) 324 cerror("out of memory (tstr)"); 325 *curtstr = dp; 326 } 327 } 328 strcpy(dp = *curtstr+tstrused, cp); 329 tstrused += i + 1; 330 return (dp); 331 } 332 #endif 333