1: /* common.c 4.2.1 95/01/17 */ 2: 3: static char *StringFile = STRINGFILE; /* From Makefile -DSTRINGFILE= ... */ 4: 5: #ifdef PASS1COMMON 6: #include "pass1.h" 7: #else 8: #ifdef PASS2COMMON 9: #include "pass2.h" 10: #endif 11: #endif 12: #include <sys/file.h> 13: 14: #ifdef FORT 15: #undef BUFSTDERR 16: #endif 17: #ifndef ONEPASS 18: #undef BUFSTDERR 19: #endif 20: 21: int nerrors = 0; /* number of errors */ 22: 23: extern OFFSZ offsz; 24: 25: /* 26: * this strangeness is due to offsets being measured in terms of bits 27: * rather than bytes. normally "i=16" and "off=0100000" are returned, 28: * but this is not enough to measure structures/arrays greater than 29: * 32k bits (4kb). 30: */ 31: 32: OFFSZ caloff(){ 33: register i; 34: OFFSZ temp; 35: OFFSZ off; 36: #ifndef pdp11 37: temp = 1; 38: i = 0; 39: do { 40: temp <<= 1; 41: ++i; 42: } while( temp != 0 ); 43: off = 1 << (i-1); 44: #else 45: off = 02000000L; /* enough for 64kb */ 46: #endif 47: return (off); 48: } 49: 50: NODE *lastfree; /* pointer to last free node; (for allocator) */ 51: 52: /* VARARGS1 */ 53: uerror(s, a ) 54: unsigned short s; 55: void *a; 56: { /* nonfatal error message */ 57: char msg[256]; 58: 59: /* the routine 'where' is different for pass 1 and pass 2; 60: /* it tells where the error took place */ 61: 62: ++nerrors; 63: where('u'); 64: errprep(s, msg); 65: fprintf(stderr, msg, a ); 66: fprintf(stderr, "\n" ); 67: #ifdef BUFSTDERR 68: fflush(stderr); 69: #endif 70: if (nerrors > 30) cerror("too many errors"); 71: } 72: 73: /* VARARGS1 */ 74: cerror(s, a, b, c ) 75: unsigned short s; /* stringfile offset */ 76: void *a, *b, *c; 77: { /* compiler error: die */ 78: char msg[256]; 79: 80: where('c'); 81: errprep(s, msg); 82: fprintf(stderr, "compiler error: " ); 83: fprintf(stderr, msg, a, b, c ); 84: fprintf(stderr, "\n" ); 85: /* give the compiler the benefit of the doubt */ 86: if (nerrors && nerrors <= 30) 87: fprintf(stderr,"cannot recover from earlier errors: goodbye!\n"); 88: #ifdef BUFSTDERR 89: fflush(stderr); 90: #endif 91: exit(1); 92: } 93: 94: int Wflag = 0; /* Non-zero means do not print warnings */ 95: 96: /* VARARGS1 */ 97: werror(s, a, b ) 98: unsigned short s; 99: void *a, *b; 100: { /* warning */ 101: char msg[256]; 102: 103: if (Wflag) return; 104: where('w'); 105: errprep(s, msg); 106: fprintf(stderr, "warning: " ); 107: fprintf(stderr, msg, a, b ); 108: fprintf(stderr, "\n" ); 109: #ifdef BUFSTDERR 110: fflush(stderr); 111: #endif 112: } 113: 114: errprep(soff, buf) 115: unsigned short soff; 116: char *buf; 117: { 118: static int errfd = -1; 119: 120: if (errfd < 0) 121: { 122: errfd = open(StringFile, O_RDONLY, 0); 123: if (errfd < 0) 124: { 125: fprintf(stderr, "can't open %s\n", StringFile); 126: fflush(stderr); 127: exit(1); 128: } 129: } 130: (void)lseek(errfd, (long)soff, L_SET); 131: (void)read(errfd, buf, 256); 132: } 133: 134: tinit(){ /* initialize expression tree search */ 135: 136: register NODE *p; 137: 138: for( p=node; p<= &node[TREESZ-1]; ++p ) p->in.op = FREE; 139: lastfree = node; 140: 141: } 142: 143: # define TNEXT(p) (p== &node[TREESZ-1]?node:p+1) 144: 145: NODE * 146: talloc(){ 147: register NODE *p, *q; 148: 149: q = lastfree; 150: for( p = TNEXT(q); p!=q; p= TNEXT(p)) 151: if( p->in.op ==FREE ) return(lastfree=p); 152: 153: cerror("out of tree space; simplify expression"); 154: /* NOTREACHED */ 155: } 156: 157: tcheck(){ /* ensure that all nodes have been freed */ 158: 159: register NODE *p; 160: 161: if( !nerrors ) 162: for( p=node; p<= &node[TREESZ-1]; ++p ) 163: if( p->in.op != FREE ) cerror("wasted space: %o", p ); 164: tinit(); 165: #ifdef FLEXNAMES 166: freetstr(); 167: #endif 168: } 169: tfree( p ) NODE *p; { 170: /* free the tree p */ 171: extern tfree1(); 172: 173: if( p->in.op != FREE ) walkf( p, tfree1 ); 174: 175: } 176: 177: tfree1(p) NODE *p; { 178: if( p == 0 ) cerror("freeing blank tree!"); 179: else p->in.op = FREE; 180: } 181: 182: fwalk( t, f, down ) register NODE *t; int (*f)(); { 183: 184: int down1, down2; 185: 186: more: 187: down1 = down2 = 0; 188: 189: (*f)( t, down, &down1, &down2 ); 190: 191: switch( optype( t->in.op ) ){ 192: 193: case BITYPE: 194: fwalk( t->in.left, f, down1 ); 195: t = t->in.right; 196: down = down2; 197: goto more; 198: 199: case UTYPE: 200: t = t->in.left; 201: down = down1; 202: goto more; 203: 204: } 205: } 206: 207: #ifndef vax 208: walkf( t, f ) register NODE *t; int (*f)(); { 209: register opty; 210: 211: opty = optype(t->in.op); 212: 213: if( opty != LTYPE ) walkf( t->in.left, f ); 214: if( opty == BITYPE ) walkf( t->in.right, f ); 215: (*f)( t ); 216: } 217: #else 218: #define NR 100 219: 220: /* 221: * Deliberately avoids recursion -- use this version on machines with 222: * expensive procedure calls. 223: */ 224: walkf(t, f) 225: register NODE *t; 226: register int (*f)(); 227: { 228: register int i = 1; 229: register int opty = optype(t->in.op); 230: static NODE *at[NR]; 231: static int ao[NR]; 232: 233: #define PUSH(dir, state) \ 234: (ao[i] = state, at[i++] = t, t = t->in.dir, opty = optype(t->in.op)) 235: #define POP() \ 236: (opty = ao[--i], t = at[i]) 237: 238: do { 239: switch (opty) { 240: case LTYPE: (*f)(t); POP(); break; 241: case UTYPE: PUSH(left, LTYPE); break; 242: case BITYPE: PUSH(left, BITYPE+1); break; 243: case BITYPE+1: PUSH(right, LTYPE); break; 244: default: 245: cerror("bad op type in walkf"); 246: } 247: if (i >= NR) { 248: walkf(t, f); 249: POP(); 250: } 251: } while (i > 0); 252: } 253: #undef NR 254: #undef PUSH 255: #undef POP 256: #endif 257: 258: 259: 260: int dope[ DSIZE ]; 261: char *opst[DSIZE]; 262: 263: struct dopest { int dopeop; char *opst; int dopeval; } indope[] = { 264: 265: NAME, "NAME", LTYPE, 266: STRING, "STRING", LTYPE, 267: REG, "REG", LTYPE, 268: OREG, "OREG", LTYPE, 269: ICON, "ICON", LTYPE, 270: FCON, "FCON", LTYPE, 271: DCON, "DCON", LTYPE, 272: CCODES, "CCODES", LTYPE, 273: UNARY MINUS, "U-", UTYPE, 274: UNARY MUL, "U*", UTYPE, 275: UNARY AND, "U&", UTYPE, 276: UNARY CALL, "UCALL", UTYPE|CALLFLG, 277: UNARY FORTCALL, "UFCALL", UTYPE|CALLFLG, 278: NOT, "!", UTYPE|LOGFLG, 279: COMPL, "~", UTYPE, 280: FORCE, "FORCE", UTYPE, 281: INIT, "INIT", UTYPE, 282: SCONV, "SCONV", UTYPE, 283: PCONV, "PCONV", UTYPE, 284: PLUS, "+", BITYPE|FLOFLG|SIMPFLG|COMMFLG, 285: ASG PLUS, "+=", BITYPE|ASGFLG|ASGOPFLG|FLOFLG|SIMPFLG|COMMFLG, 286: MINUS, "-", BITYPE|FLOFLG|SIMPFLG, 287: ASG MINUS, "-=", BITYPE|FLOFLG|SIMPFLG|ASGFLG|ASGOPFLG, 288: MUL, "*", BITYPE|FLOFLG|MULFLG, 289: ASG MUL, "*=", BITYPE|FLOFLG|MULFLG|ASGFLG|ASGOPFLG, 290: AND, "&", BITYPE|SIMPFLG|COMMFLG, 291: ASG AND, "&=", BITYPE|SIMPFLG|COMMFLG|ASGFLG|ASGOPFLG, 292: QUEST, "?", BITYPE, 293: COLON, ":", BITYPE, 294: ANDAND, "&&", BITYPE|LOGFLG, 295: OROR, "||", BITYPE|LOGFLG, 296: CM, ",", BITYPE, 297: COMOP, ",OP", BITYPE, 298: ASSIGN, "=", BITYPE|ASGFLG, 299: DIV, "/", BITYPE|FLOFLG|MULFLG|DIVFLG, 300: ASG DIV, "/=", BITYPE|FLOFLG|MULFLG|DIVFLG|ASGFLG|ASGOPFLG, 301: MOD, "%", BITYPE|DIVFLG, 302: ASG MOD, "%=", BITYPE|DIVFLG|ASGFLG|ASGOPFLG, 303: LS, "<<", BITYPE|SHFFLG, 304: ASG LS, "<<=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG, 305: RS, ">>", BITYPE|SHFFLG, 306: ASG RS, ">>=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG, 307: OR, "|", BITYPE|COMMFLG|SIMPFLG, 308: ASG OR, "|=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG, 309: ER, "^", BITYPE|COMMFLG|SIMPFLG, 310: ASG ER, "^=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG, 311: INCR, "++", BITYPE|ASGFLG, 312: DECR, "--", BITYPE|ASGFLG, 313: STREF, "->", BITYPE, 314: CALL, "CALL", BITYPE|CALLFLG, 315: FORTCALL, "FCALL", BITYPE|CALLFLG, 316: EQ, "==", BITYPE|LOGFLG, 317: NE, "!=", BITYPE|LOGFLG, 318: LE, "<=", BITYPE|LOGFLG, 319: LT, "<", BITYPE|LOGFLG, 320: GE, ">", BITYPE|LOGFLG, 321: GT, ">", BITYPE|LOGFLG, 322: UGT, "UGT", BITYPE|LOGFLG, 323: UGE, "UGE", BITYPE|LOGFLG, 324: ULT, "ULT", BITYPE|LOGFLG, 325: ULE, "ULE", BITYPE|LOGFLG, 326: #ifdef ARS 327: ARS, "A>>", BITYPE, 328: #endif 329: TYPE, "TYPE", LTYPE, 330: LB, "[", BITYPE, 331: CBRANCH, "CBRANCH", BITYPE, 332: FLD, "FLD", UTYPE, 333: PMCONV, "PMCONV", BITYPE, 334: PVCONV, "PVCONV", BITYPE, 335: RETURN, "RETURN", BITYPE|ASGFLG|ASGOPFLG, 336: CAST, "CAST", BITYPE|ASGFLG|ASGOPFLG, 337: GOTO, "GOTO", UTYPE, 338: STASG, "STASG", BITYPE|ASGFLG, 339: STARG, "STARG", UTYPE, 340: STCALL, "STCALL", BITYPE|CALLFLG, 341: UNARY STCALL, "USTCALL", UTYPE|CALLFLG, 342: 343: -1, "", 0 344: }; 345: 346: mkdope(){ 347: register struct dopest *q; 348: 349: for( q = indope; q->dopeop >= 0; ++q ){ 350: dope[q->dopeop] = q->dopeval; 351: opst[q->dopeop] = q->opst; 352: } 353: } 354: # ifndef BUG4 355: tprint( t ) TWORD t; { /* output a nice description of the type of t */ 356: 357: static char * tnames[] = { 358: "undef", 359: "farg", 360: "char", 361: "short", 362: "int", 363: "long", 364: "float", 365: "double", 366: "strty", 367: "unionty", 368: "enumty", 369: "moety", 370: "uchar", 371: "ushort", 372: "unsigned", 373: "ulong", 374: "?", "?" 375: }; 376: 377: for(;; t = DECREF(t) ){ 378: 379: if( ISPTR(t) ) printf( "PTR " ); 380: else if( ISFTN(t) ) printf( "FTN " ); 381: else if( ISARY(t) ) printf( "ARY " ); 382: else { 383: printf( "%s", tnames[t] ); 384: return; 385: } 386: } 387: } 388: # endif 389: 390: #ifdef FLEXNAMES 391: #define NTSTRBUF 25 /* was 40 */ 392: #define TSTRSZ 512 /* was 2048 */ 393: char itstrbuf[TSTRSZ]; 394: char *tstrbuf[NTSTRBUF] = { itstrbuf }; 395: char **curtstr = tstrbuf; 396: int tstrused; 397: 398: char * 399: tstr(cp) 400: register char *cp; 401: { 402: register int i = strlen(cp); 403: register char *dp; 404: 405: if (tstrused + i >= TSTRSZ) { 406: if (++curtstr >= &tstrbuf[NTSTRBUF]) 407: cerror("out of temporary string space"); 408: tstrused = 0; 409: if (*curtstr == 0) { 410: dp = (char *)malloc(TSTRSZ); 411: if (dp == 0) 412: cerror("out of memory (tstr)"); 413: *curtstr = dp; 414: } 415: } 416: strcpy(dp = *curtstr+tstrused, cp); 417: tstrused += i + 1; 418: return (dp); 419: } 420: #endif