|
|
1.1 ! root 1: /* @(#)common 1.1 86/02/03 SMI */ ! 2: ! 3: #ifdef FORT ! 4: #undef BUFSTDERR ! 5: #endif ! 6: #ifndef ONEPASS ! 7: #undef BUFSTDERR ! 8: #endif ! 9: # ifndef EXIT ! 10: # define EXIT exit ! 11: # endif ! 12: ! 13: int nerrors = 0; /* number of errors */ ! 14: int errline = -1; /* where last error took place */ ! 15: ! 16: extern unsigned int offsz; ! 17: ! 18: unsigned caloff(){ ! 19: register i; ! 20: unsigned int temp; ! 21: unsigned int off; ! 22: temp = 1; ! 23: i = 0; ! 24: do { ! 25: temp <<= 1; ! 26: ++i; ! 27: } while( temp > 0 ); ! 28: off = 1 << (i-1); ! 29: return (off); ! 30: } ! 31: ! 32: /* VARARGS1 */ ! 33: uerror( s, a ) char *s; { /* nonfatal error message */ ! 34: /* the routine where is different for pass 1 and pass 2; ! 35: /* it tells where the error took place */ ! 36: ! 37: fflush( stdout ); ! 38: ++nerrors; ! 39: errline = lineno; ! 40: where('u'); ! 41: fprintf( stderr, s, a ); ! 42: fprintf( stderr, "\n" ); ! 43: #ifdef BUFSTDERR ! 44: fflush(stderr); ! 45: #endif ! 46: if( nerrors > 30 ) fatal( "too many errors"); ! 47: } ! 48: ! 49: /* VARARGS1 */ ! 50: cerror( s, a, b, c ) char *s; { /* compiler error: die */ ! 51: fflush( stdout ); ! 52: where('c'); ! 53: if( nerrors && nerrors <= 30 ){ /* give the compiler the benefit of the doubt */ ! 54: fprintf( stderr, "cannot recover from earlier errors: goodbye!\n" ); ! 55: } ! 56: else { ! 57: fprintf( stderr, "compiler error: " ); ! 58: fprintf( stderr, s, a, b, c ); ! 59: fprintf( stderr, "\n" ); ! 60: } ! 61: #ifdef BUFSTDERR ! 62: fflush(stderr); ! 63: #endif ! 64: EXIT(1); ! 65: } ! 66: ! 67: fatal( s, a, b, c ) char *s; { /* non-compiler but fatal error: die */ ! 68: fflush( stdout ); ! 69: where('f'); ! 70: fprintf( stderr, "fatal error: " ); ! 71: fprintf( stderr, s, a, b, c ); ! 72: fprintf( stderr, "\n" ); ! 73: #ifdef BUFSTDERR ! 74: fflush(stderr); ! 75: #endif ! 76: EXIT(1); ! 77: } ! 78: int Wflag = 0; /* Non-zero means do not print warnings */ ! 79: ! 80: /* VARARGS1 */ ! 81: werror( s, a, b ) char *s; { /* warning */ ! 82: if(Wflag) return; ! 83: fflush( stdout ); ! 84: where('w'); ! 85: fprintf( stderr, "warning: " ); ! 86: fprintf( stderr, s, a, b ); ! 87: fprintf( stderr, "\n" ); ! 88: #ifdef BUFSTDERR ! 89: fflush(stderr); ! 90: #endif ! 91: } ! 92: ! 93: /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ! 94: ! 95: #ifdef TESTALLOC ! 96: /* ! 97: * this enables us to test ! 98: * tree allocation without having ! 99: * to construct bizarre test programs ! 100: */ ! 101: #undef TREESZ ! 102: #define TREESZ 16 ! 103: #endif TESTALLOC ! 104: ! 105: #define MAXTSEG 64 /* max # of tree segments */ ! 106: static NODE treespace[TREESZ]; /* initial tree space */ ! 107: static NODE *treeseg[MAXTSEG] = {treespace};/* table of seg pointers */ ! 108: static NODE **activeseg = &treeseg[0]; /* ptr to active seg slot */ ! 109: static NODE *node = treespace; /* ptr to active segment */ ! 110: static NODE *nextfree = treespace; /* ptr to next free node */ ! 111: static int nsegs = 1; /* # of allocated segments */ ! 112: static int recycling = 0; /* =1 if using old nodes */ ! 113: ! 114: /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ! 115: ! 116: static NODE * ! 117: tsegalloc() ! 118: { ! 119: NODE *newseg; ! 120: if ( activeseg == &treeseg[nsegs-1] ) { ! 121: /* ! 122: * no unused segments; allocate a new one ! 123: */ ! 124: if (nsegs == MAXTSEG) { ! 125: cerror("out of tree space; try simplifying"); ! 126: /*NOTREACHED*/ ! 127: } ! 128: newseg = (NODE *)malloc(TREESZ*sizeof(NODE)); ! 129: *++activeseg = newseg; ! 130: nsegs++; ! 131: } else { ! 132: /* ! 133: * segment already allocated; use it ! 134: */ ! 135: newseg = *++activeseg; ! 136: if (newseg == NIL) { ! 137: cerror("tree space allocation"); ! 138: /*NOTREACHED*/ ! 139: } ! 140: } ! 141: return newseg; ! 142: } ! 143: ! 144: /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ! 145: ! 146: tinit() ! 147: { ! 148: /* initialize tree space allocation */ ! 149: activeseg = &treeseg[0]; /* ptr to active seg slot */ ! 150: node = *activeseg; /* ptr to active segment */ ! 151: nextfree = node; /* ptr to next free node */ ! 152: recycling = 0; ! 153: } ! 154: ! 155: /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ! 156: ! 157: #define TNEXT(p) (p == &node[TREESZ]? node : p+1) ! 158: ! 159: /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ! 160: ! 161: NODE * ! 162: talloc() ! 163: { ! 164: register NODE *p, *q; ! 165: static NODE *lastfrag; ! 166: ! 167: if ( nextfree < &node[TREESZ] ) ! 168: return nextfree++; ! 169: if ( !recycling ) { ! 170: recycling = 1; ! 171: lastfrag = node; ! 172: } ! 173: q = lastfrag; ! 174: for( p = TNEXT(q); p != q; p = TNEXT(p) ) { ! 175: if (p->tn.op == FREE) { ! 176: return lastfrag = p; ! 177: } ! 178: } ! 179: /* ! 180: * current tree space segment is full; ! 181: * get a new one. ! 182: */ ! 183: nextfree = node = tsegalloc(); ! 184: recycling = 0; ! 185: return nextfree++; ! 186: } ! 187: ! 188: /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ! 189: ! 190: tcheck() ! 191: { ! 192: /* ! 193: * ensure that all nodes have been freed. Note that in the ! 194: * C compiler, some nodes remain active until the end of the ! 195: * current function, so this should not be called until then. ! 196: * In the backend-only configuration (fort) this is called ! 197: * on a statement-by-statement basis. ! 198: */ ! 199: ! 200: register NODE *p; ! 201: register NODE *limit; ! 202: NODE **seg; ! 203: ! 204: if( !nerrors ) { ! 205: /* ! 206: * all segments below the top one must be scanned ! 207: * from beginning to end. The top one need only ! 208: * be scanned up to the high-water mark (nextfree) ! 209: */ ! 210: for( seg = &treeseg[0]; seg < activeseg; seg++ ) { ! 211: limit = *seg + TREESZ; ! 212: for (p = *seg; p < limit; p++ ) { ! 213: if( p->in.op != FREE ) { ! 214: cerror( "wasted space: %#x", p ); ! 215: } ! 216: } ! 217: } ! 218: limit = nextfree; ! 219: for( p=node; p < limit; ++p ) { ! 220: if( p->in.op != FREE ) { ! 221: cerror( "wasted space: %#x", p ); ! 222: } ! 223: } ! 224: } ! 225: tinit(); ! 226: #ifdef FLEXNAMES ! 227: freetstr(); ! 228: #endif ! 229: } ! 230: ! 231: /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ! 232: ! 233: tfree(p) ! 234: register NODE *p; ! 235: { ! 236: if (p == NIL) ! 237: return; ! 238: again: ! 239: switch(optype(p->in.op)) { ! 240: case UTYPE: ! 241: tfree(p->in.left); ! 242: /*fall through*/ ! 243: case LTYPE: ! 244: p->in.op = FREE; ! 245: return; ! 246: case BITYPE: ! 247: tfree(p->in.left); ! 248: p->in.op = FREE; ! 249: p = p->in.right; ! 250: goto again; ! 251: } ! 252: } ! 253: ! 254: fwalk( t, f, down ) register NODE *t; int (*f)(); { ! 255: ! 256: int down1, down2; ! 257: ! 258: more: ! 259: down1 = down2 = 0; ! 260: ! 261: (*f)( t, down, &down1, &down2 ); ! 262: ! 263: switch( optype( t->in.op ) ){ ! 264: ! 265: case BITYPE: ! 266: fwalk( t->in.left, f, down1 ); ! 267: t = t->in.right; ! 268: down = down2; ! 269: goto more; ! 270: ! 271: case UTYPE: ! 272: t = t->in.left; ! 273: down = down1; ! 274: goto more; ! 275: ! 276: } ! 277: } ! 278: ! 279: walkf( t, f ) ! 280: register NODE *t; ! 281: int (*f)(); ! 282: { ! 283: switch(optype(t->in.op)) { ! 284: case LTYPE: ! 285: break; ! 286: case UTYPE: ! 287: walkf(t->in.left, f); ! 288: break; ! 289: default: ! 290: walkf(t->in.left, f); ! 291: walkf(t->in.right, f); ! 292: break; ! 293: } ! 294: (*f)( t ); ! 295: } ! 296: ! 297: int dope[ DSIZE ]; ! 298: char *opst[DSIZE]; ! 299: ! 300: struct dopest { int dopeop; char opst[8]; int dopeval; } indope[] = { ! 301: ! 302: NAME, "NAME", LTYPE, ! 303: STRING, "STRING", LTYPE, ! 304: REG, "REG", LTYPE, ! 305: OREG, "OREG", LTYPE, ! 306: ICON, "ICON", LTYPE, ! 307: FCON, "FCON", LTYPE, ! 308: FCCODES, "FCCODES", LTYPE, ! 309: CCODES, "CCODES", LTYPE, ! 310: UNARY MINUS, "U-", UTYPE, ! 311: UNARY MUL, "U*", UTYPE, ! 312: UNARY AND, "U&", UTYPE, ! 313: UNARY CALL, "UCALL", UTYPE|CALLFLG, ! 314: UNARY FORTCALL, "UFCALL", UTYPE|CALLFLG, ! 315: NOT, "!", UTYPE|LOGFLG, ! 316: COMPL, "~", UTYPE, ! 317: FORCE, "FORCE", UTYPE, ! 318: INIT, "INIT", UTYPE, ! 319: SCONV, "SCONV", UTYPE, ! 320: PCONV, "PCONV", UTYPE, ! 321: PLUS, "+", BITYPE|FLOFLG|SIMPFLG|COMMFLG, ! 322: ASG PLUS, "+=", BITYPE|ASGFLG|ASGOPFLG|FLOFLG|SIMPFLG|COMMFLG, ! 323: MINUS, "-", BITYPE|FLOFLG|SIMPFLG, ! 324: ASG MINUS, "-=", BITYPE|FLOFLG|SIMPFLG|ASGFLG|ASGOPFLG, ! 325: MUL, "*", BITYPE|FLOFLG|MULFLG, ! 326: ASG MUL, "*=", BITYPE|FLOFLG|MULFLG|ASGFLG|ASGOPFLG, ! 327: AND, "&", BITYPE|SIMPFLG|COMMFLG, ! 328: ASG AND, "&=", BITYPE|SIMPFLG|COMMFLG|ASGFLG|ASGOPFLG, ! 329: QUEST, "?", BITYPE, ! 330: COLON, ":", BITYPE, ! 331: ANDAND, "&&", BITYPE|LOGFLG, ! 332: OROR, "||", BITYPE|LOGFLG, ! 333: CM, ",", BITYPE, ! 334: COMOP, ",OP", BITYPE, ! 335: ASSIGN, "=", BITYPE|ASGFLG, ! 336: DIV, "/", BITYPE|FLOFLG|MULFLG|DIVFLG, ! 337: ASG DIV, "/=", BITYPE|FLOFLG|MULFLG|DIVFLG|ASGFLG|ASGOPFLG, ! 338: MOD, "%", BITYPE|DIVFLG, ! 339: ASG MOD, "%=", BITYPE|DIVFLG|ASGFLG|ASGOPFLG, ! 340: LS, "<<", BITYPE|SHFFLG, ! 341: ASG LS, "<<=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG, ! 342: RS, ">>", BITYPE|SHFFLG, ! 343: ASG RS, ">>=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG, ! 344: OR, "|", BITYPE|COMMFLG|SIMPFLG, ! 345: ASG OR, "|=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG, ! 346: #ifdef VAX ! 347: ER, "^", BITYPE|COMMFLG|SIMPFLG, ! 348: ASG ER, "^=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG, ! 349: #else ! 350: ER, "^", BITYPE|COMMFLG, ! 351: ASG ER, "^=", BITYPE|COMMFLG|ASGFLG|ASGOPFLG, ! 352: #endif ! 353: INCR, "++", BITYPE|ASGFLG, ! 354: DECR, "--", BITYPE|ASGFLG, ! 355: STREF, "->", BITYPE, ! 356: CALL, "CALL", BITYPE|CALLFLG, ! 357: FORTCALL, "FCALL", BITYPE|CALLFLG, ! 358: EQ, "==", BITYPE|LOGFLG, ! 359: NE, "!=", BITYPE|LOGFLG, ! 360: LE, "<=", BITYPE|LOGFLG, ! 361: LT, "<", BITYPE|LOGFLG, ! 362: GE, ">", BITYPE|LOGFLG, ! 363: GT, ">", BITYPE|LOGFLG, ! 364: UGT, "UGT", BITYPE|LOGFLG, ! 365: UGE, "UGE", BITYPE|LOGFLG, ! 366: ULT, "ULT", BITYPE|LOGFLG, ! 367: ULE, "ULE", BITYPE|LOGFLG, ! 368: ARS, "A>>", BITYPE, ! 369: TYPE, "TYPE", LTYPE, ! 370: LB, "[", BITYPE, ! 371: CBRANCH, "CBRANCH", BITYPE, ! 372: FLD, "FLD", UTYPE, ! 373: PMCONV, "PMCONV", BITYPE, ! 374: PVCONV, "PVCONV", BITYPE, ! 375: RETURN, "RETURN", BITYPE|ASGFLG|ASGOPFLG, ! 376: CAST, "CAST", BITYPE|ASGFLG|ASGOPFLG, ! 377: GOTO, "GOTO", UTYPE, ! 378: STASG, "STASG", BITYPE|ASGFLG, ! 379: STARG, "STARG", UTYPE, ! 380: STCALL, "STCALL", BITYPE|CALLFLG, ! 381: UNARY STCALL, "USTCALL", UTYPE|CALLFLG, ! 382: CHK, "CHK", BITYPE, ! 383: FABS, "FABS", UTYPE|INTRFLG, ! 384: FCOS, "FCOS", UTYPE|INTRFLG, ! 385: FSIN, "FSIN", UTYPE|INTRFLG, ! 386: FTAN, "FTAN", UTYPE|INTRFLG, ! 387: FACOS, "FACOS", UTYPE|INTRFLG, ! 388: FASIN, "FASIN", UTYPE|INTRFLG, ! 389: FATAN, "FATAN", UTYPE|INTRFLG, ! 390: FCOSH, "FCOSH", UTYPE|INTRFLG, ! 391: FSINH, "FSINH", UTYPE|INTRFLG, ! 392: FTANH, "FTANH", UTYPE|INTRFLG, ! 393: FEXP, "FEXP", UTYPE|INTRFLG, ! 394: F10TOX, "F10TOX", UTYPE|INTRFLG, ! 395: F2TOX, "F2TOX", UTYPE|INTRFLG, ! 396: FLOGN, "FLOGN", UTYPE|INTRFLG, ! 397: FLOG10, "FLOG10", UTYPE|INTRFLG, ! 398: FLOG2, "FLOG2", UTYPE|INTRFLG, ! 399: FSQR, "FSQR", UTYPE|INTRFLG, ! 400: FSQRT, "FSQRT", UTYPE|INTRFLG, ! 401: FAINT, "FAINT", UTYPE|INTRFLG, ! 402: FANINT, "FANINT", UTYPE|INTRFLG, ! 403: FNINT, "FNINT", UTYPE, ! 404: -1, "", 0 ! 405: }; ! 406: ! 407: mkdope(){ ! 408: register struct dopest *q; ! 409: ! 410: for( q = indope; q->dopeop >= 0; ++q ){ ! 411: dope[q->dopeop] = q->dopeval; ! 412: opst[q->dopeop] = q->opst; ! 413: } ! 414: } ! 415: # ifndef BUG4 ! 416: tprint( t ) TWORD t; { /* output a nice description of the type of t */ ! 417: ! 418: static char * tnames[] = { ! 419: "undef", ! 420: "farg", ! 421: "char", ! 422: "short", ! 423: "int", ! 424: "long", ! 425: "float", ! 426: "double", ! 427: "strty", ! 428: "unionty", ! 429: "enumty", ! 430: "moety", ! 431: "uchar", ! 432: "ushort", ! 433: "unsigned", ! 434: "ulong", ! 435: "?", "?" ! 436: }; ! 437: ! 438: for(;; t = DECREF(t) ){ ! 439: ! 440: if( ISPTR(t) ) printf( "PTR " ); ! 441: else if( ISFTN(t) ) printf( "FTN " ); ! 442: else if( ISARY(t) ) printf( "ARY " ); ! 443: else { ! 444: printf( "%s", tnames[t] ); ! 445: return; ! 446: } ! 447: } ! 448: } ! 449: # endif ! 450: ! 451: #ifdef FLEXNAMES ! 452: #define NTSTRBUF 40 ! 453: #define TSTRSZ 2048 ! 454: char itstrbuf[TSTRSZ]; ! 455: char *tstrbuf[NTSTRBUF] = { itstrbuf }; ! 456: char **curtstr = tstrbuf; ! 457: int tstrused; ! 458: ! 459: char * ! 460: tstr(cp) ! 461: register char *cp; ! 462: { ! 463: register int i = strlen(cp); ! 464: register char *dp; ! 465: ! 466: if (tstrused + i >= TSTRSZ) { ! 467: if (++curtstr >= &tstrbuf[NTSTRBUF]) ! 468: cerror("out of temporary string space"); ! 469: tstrused = 0; ! 470: if (*curtstr == 0) { ! 471: dp = (char *)malloc(TSTRSZ); ! 472: *curtstr = dp; ! 473: } ! 474: } ! 475: strcpy(dp = *curtstr+tstrused, cp); ! 476: tstrused += i + 1; ! 477: return (dp); ! 478: } ! 479: #endif ! 480: ! 481: #ifdef malloc ! 482: #undef malloc ! 483: #endif malloc ! 484: ! 485: /* ! 486: * NOTE: malloc is defined as malloc_with_care everywhere but here. ! 487: */ ! 488: char * ! 489: malloc_with_care(nbytes) ! 490: { ! 491: char *p; ! 492: ! 493: p = (char*)malloc(nbytes); ! 494: if (p == NULL) { ! 495: fatal("memory allocation exceeded"); ! 496: exit(1); ! 497: } ! 498: return(p); ! 499: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.