| 1 | #ifdef FORT |
| 2 | #undef BUFSTDERR |
| 3 | #endif |
| 4 | #ifndef ONEPASS |
| 5 | #undef BUFSTDERR |
| 6 | #endif |
| 7 | # ifndef EXIT |
| 8 | # define EXIT exit |
| 9 | # endif |
| 10 | |
| 11 | int nerrors = 0; /* number of errors */ |
| 12 | |
| 13 | extern unsigned int offsz; |
| 14 | |
| 15 | unsigned caloff(){ |
| 16 | register i; |
| 17 | unsigned int temp; |
| 18 | unsigned int off; |
| 19 | temp = 1; |
| 20 | i = 0; |
| 21 | do { |
| 22 | temp <<= 1; |
| 23 | ++i; |
| 24 | } while( temp > 0 ); |
| 25 | off = 1 << (i-1); |
| 26 | return (off); |
| 27 | } |
| 28 | |
| 29 | NODE *lastfree; /* pointer to last free node; (for allocator) */ |
| 30 | |
| 31 | /* VARARGS1 */ |
| 32 | uerror( s, a ) char *s; { /* nonfatal error message */ |
| 33 | /* the routine where is different for pass 1 and pass 2; |
| 34 | /* it tells where the error took place */ |
| 35 | |
| 36 | ++nerrors; |
| 37 | where('u'); |
| 38 | fprintf( stderr, s, a ); |
| 39 | fprintf( stderr, "\n" ); |
| 40 | #ifdef BUFSTDERR |
| 41 | fflush(stderr); |
| 42 | #endif |
| 43 | if( nerrors > 30 ) cerror( "too many errors"); |
| 44 | } |
| 45 | |
| 46 | /* VARARGS1 */ |
| 47 | cerror( s, a, b, c ) char *s; { /* compiler error: die */ |
| 48 | where('c'); |
| 49 | if( nerrors && nerrors <= 30 ){ /* give the compiler the benefit of the doubt */ |
| 50 | fprintf( stderr, "cannot recover from earlier errors: goodbye!\n" ); |
| 51 | } |
| 52 | else { |
| 53 | fprintf( stderr, "compiler error: " ); |
| 54 | fprintf( stderr, s, a, b, c ); |
| 55 | fprintf( stderr, "\n" ); |
| 56 | } |
| 57 | #ifdef BUFSTDERR |
| 58 | fflush(stderr); |
| 59 | #endif |
| 60 | EXIT(1); |
| 61 | } |
| 62 | |
| 63 | int Wflag = 0; /* Non-zero means do not print warnings */ |
| 64 | |
| 65 | /* VARARGS1 */ |
| 66 | werror( s, a, b ) char *s; { /* warning */ |
| 67 | if(Wflag) return; |
| 68 | where('w'); |
| 69 | fprintf( stderr, "warning: " ); |
| 70 | fprintf( stderr, s, a, b ); |
| 71 | fprintf( stderr, "\n" ); |
| 72 | #ifdef BUFSTDERR |
| 73 | fflush(stderr); |
| 74 | #endif |
| 75 | } |
| 76 | |
| 77 | tinit(){ /* initialize expression tree search */ |
| 78 | |
| 79 | NODE *p; |
| 80 | |
| 81 | for( p=node; p<= &node[TREESZ-1]; ++p ) p->in.op = FREE; |
| 82 | lastfree = node; |
| 83 | |
| 84 | } |
| 85 | |
| 86 | # define TNEXT(p) (p== &node[TREESZ-1]?node:p+1) |
| 87 | |
| 88 | NODE * |
| 89 | talloc(){ |
| 90 | NODE *p, *q; |
| 91 | |
| 92 | q = lastfree; |
| 93 | for( p = TNEXT(q); p!=q; p= TNEXT(p)) |
| 94 | if( p->in.op ==FREE ) return(lastfree=p); |
| 95 | |
| 96 | cerror( "out of tree space; simplify expression"); |
| 97 | /* NOTREACHED */ |
| 98 | } |
| 99 | |
| 100 | tcheck(){ /* ensure that all nodes have been freed */ |
| 101 | |
| 102 | NODE *p; |
| 103 | |
| 104 | if( !nerrors ) |
| 105 | for( p=node; p<= &node[TREESZ-1]; ++p ) |
| 106 | if( p->in.op != FREE ) cerror( "wasted space: %o", p ); |
| 107 | tinit(); |
| 108 | #ifdef FLEXNAMES |
| 109 | freetstr(); |
| 110 | #endif |
| 111 | } |
| 112 | tfree( p ) NODE *p; { |
| 113 | /* free the tree p */ |
| 114 | extern tfree1(); |
| 115 | |
| 116 | if( p->in.op != FREE ) walkf( p, tfree1 ); |
| 117 | |
| 118 | } |
| 119 | |
| 120 | tfree1(p) NODE *p; { |
| 121 | if( p == 0 ) cerror( "freeing blank tree!"); |
| 122 | else p->in.op = FREE; |
| 123 | } |
| 124 | |
| 125 | fwalk( t, f, down ) register NODE *t; int (*f)(); { |
| 126 | |
| 127 | int down1, down2; |
| 128 | |
| 129 | more: |
| 130 | down1 = down2 = 0; |
| 131 | |
| 132 | (*f)( t, down, &down1, &down2 ); |
| 133 | |
| 134 | switch( optype( t->in.op ) ){ |
| 135 | |
| 136 | case BITYPE: |
| 137 | fwalk( t->in.left, f, down1 ); |
| 138 | t = t->in.right; |
| 139 | down = down2; |
| 140 | goto more; |
| 141 | |
| 142 | case UTYPE: |
| 143 | t = t->in.left; |
| 144 | down = down1; |
| 145 | goto more; |
| 146 | |
| 147 | } |
| 148 | } |
| 149 | |
| 150 | walkf( t, f ) register NODE *t; int (*f)(); { |
| 151 | register opty; |
| 152 | |
| 153 | opty = optype(t->in.op); |
| 154 | |
| 155 | if( opty != LTYPE ) walkf( t->in.left, f ); |
| 156 | if( opty == BITYPE ) walkf( t->in.right, f ); |
| 157 | (*f)( t ); |
| 158 | } |
| 159 | |
| 160 | |
| 161 | |
| 162 | int dope[ DSIZE ]; |
| 163 | char *opst[DSIZE]; |
| 164 | |
| 165 | struct dopest { int dopeop; char opst[8]; int dopeval; } indope[] = { |
| 166 | |
| 167 | NAME, "NAME", LTYPE, |
| 168 | STRING, "STRING", LTYPE, |
| 169 | REG, "REG", LTYPE, |
| 170 | OREG, "OREG", LTYPE, |
| 171 | ICON, "ICON", LTYPE, |
| 172 | FCON, "FCON", LTYPE, |
| 173 | CCODES, "CCODES", LTYPE, |
| 174 | UNARY MINUS, "U-", UTYPE, |
| 175 | UNARY MUL, "U*", UTYPE, |
| 176 | UNARY AND, "U&", UTYPE, |
| 177 | UNARY CALL, "UCALL", UTYPE|CALLFLG, |
| 178 | UNARY FORTCALL, "UFCALL", UTYPE|CALLFLG, |
| 179 | NOT, "!", UTYPE|LOGFLG, |
| 180 | COMPL, "~", UTYPE, |
| 181 | FORCE, "FORCE", UTYPE, |
| 182 | INIT, "INIT", UTYPE, |
| 183 | SCONV, "SCONV", UTYPE, |
| 184 | PCONV, "PCONV", UTYPE, |
| 185 | PLUS, "+", BITYPE|FLOFLG|SIMPFLG|COMMFLG, |
| 186 | ASG PLUS, "+=", BITYPE|ASGFLG|ASGOPFLG|FLOFLG|SIMPFLG|COMMFLG, |
| 187 | MINUS, "-", BITYPE|FLOFLG|SIMPFLG, |
| 188 | ASG MINUS, "-=", BITYPE|FLOFLG|SIMPFLG|ASGFLG|ASGOPFLG, |
| 189 | MUL, "*", BITYPE|FLOFLG|MULFLG, |
| 190 | ASG MUL, "*=", BITYPE|FLOFLG|MULFLG|ASGFLG|ASGOPFLG, |
| 191 | AND, "&", BITYPE|SIMPFLG|COMMFLG, |
| 192 | ASG AND, "&=", BITYPE|SIMPFLG|COMMFLG|ASGFLG|ASGOPFLG, |
| 193 | QUEST, "?", BITYPE, |
| 194 | COLON, ":", BITYPE, |
| 195 | ANDAND, "&&", BITYPE|LOGFLG, |
| 196 | OROR, "||", BITYPE|LOGFLG, |
| 197 | CM, ",", BITYPE, |
| 198 | COMOP, ",OP", BITYPE, |
| 199 | ASSIGN, "=", BITYPE|ASGFLG, |
| 200 | DIV, "/", BITYPE|FLOFLG|MULFLG|DIVFLG, |
| 201 | ASG DIV, "/=", BITYPE|FLOFLG|MULFLG|DIVFLG|ASGFLG|ASGOPFLG, |
| 202 | MOD, "%", BITYPE|DIVFLG, |
| 203 | ASG MOD, "%=", BITYPE|DIVFLG|ASGFLG|ASGOPFLG, |
| 204 | LS, "<<", BITYPE|SHFFLG, |
| 205 | ASG LS, "<<=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG, |
| 206 | RS, ">>", BITYPE|SHFFLG, |
| 207 | ASG RS, ">>=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG, |
| 208 | OR, "|", BITYPE|COMMFLG|SIMPFLG, |
| 209 | ASG OR, "|=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG, |
| 210 | ER, "^", BITYPE|COMMFLG|SIMPFLG, |
| 211 | ASG ER, "^=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG, |
| 212 | INCR, "++", BITYPE|ASGFLG, |
| 213 | DECR, "--", BITYPE|ASGFLG, |
| 214 | STREF, "->", BITYPE, |
| 215 | CALL, "CALL", BITYPE|CALLFLG, |
| 216 | FORTCALL, "FCALL", BITYPE|CALLFLG, |
| 217 | EQ, "==", BITYPE|LOGFLG, |
| 218 | NE, "!=", BITYPE|LOGFLG, |
| 219 | LE, "<=", BITYPE|LOGFLG, |
| 220 | LT, "<", BITYPE|LOGFLG, |
| 221 | GE, ">", BITYPE|LOGFLG, |
| 222 | GT, ">", BITYPE|LOGFLG, |
| 223 | UGT, "UGT", BITYPE|LOGFLG, |
| 224 | UGE, "UGE", BITYPE|LOGFLG, |
| 225 | ULT, "ULT", BITYPE|LOGFLG, |
| 226 | ULE, "ULE", BITYPE|LOGFLG, |
| 227 | ARS, "A>>", BITYPE, |
| 228 | TYPE, "TYPE", LTYPE, |
| 229 | LB, "[", BITYPE, |
| 230 | CBRANCH, "CBRANCH", BITYPE, |
| 231 | FLD, "FLD", UTYPE, |
| 232 | PMCONV, "PMCONV", BITYPE, |
| 233 | PVCONV, "PVCONV", BITYPE, |
| 234 | RETURN, "RETURN", BITYPE|ASGFLG|ASGOPFLG, |
| 235 | CAST, "CAST", BITYPE|ASGFLG|ASGOPFLG, |
| 236 | GOTO, "GOTO", UTYPE, |
| 237 | STASG, "STASG", BITYPE|ASGFLG, |
| 238 | STARG, "STARG", UTYPE, |
| 239 | STCALL, "STCALL", BITYPE|CALLFLG, |
| 240 | UNARY STCALL, "USTCALL", UTYPE|CALLFLG, |
| 241 | |
| 242 | -1, 0 |
| 243 | }; |
| 244 | |
| 245 | mkdope(){ |
| 246 | register struct dopest *q; |
| 247 | |
| 248 | for( q = indope; q->dopeop >= 0; ++q ){ |
| 249 | dope[q->dopeop] = q->dopeval; |
| 250 | opst[q->dopeop] = q->opst; |
| 251 | } |
| 252 | } |
| 253 | # ifndef BUG4 |
| 254 | tprint( t ) TWORD t; { /* output a nice description of the type of t */ |
| 255 | |
| 256 | static char * tnames[] = { |
| 257 | "undef", |
| 258 | "farg", |
| 259 | "char", |
| 260 | "short", |
| 261 | "int", |
| 262 | "long", |
| 263 | "float", |
| 264 | "double", |
| 265 | "strty", |
| 266 | "unionty", |
| 267 | "enumty", |
| 268 | "moety", |
| 269 | "uchar", |
| 270 | "ushort", |
| 271 | "unsigned", |
| 272 | "ulong", |
| 273 | "?", "?" |
| 274 | }; |
| 275 | |
| 276 | for(;; t = DECREF(t) ){ |
| 277 | |
| 278 | if( ISPTR(t) ) printf( "PTR " ); |
| 279 | else if( ISFTN(t) ) printf( "FTN " ); |
| 280 | else if( ISARY(t) ) printf( "ARY " ); |
| 281 | else { |
| 282 | printf( "%s", tnames[t] ); |
| 283 | return; |
| 284 | } |
| 285 | } |
| 286 | } |
| 287 | # endif |
| 288 | |
| 289 | #ifdef FLEXNAMES |
| 290 | #define NTSTRBUF 40 |
| 291 | #define TSTRSZ 2048 |
| 292 | char itstrbuf[TSTRSZ]; |
| 293 | char *tstrbuf[NTSTRBUF] = { itstrbuf }; |
| 294 | char **curtstr = tstrbuf; |
| 295 | int tstrused; |
| 296 | |
| 297 | char * |
| 298 | tstr(cp) |
| 299 | register char *cp; |
| 300 | { |
| 301 | register int i = strlen(cp); |
| 302 | register char *dp; |
| 303 | |
| 304 | if (tstrused + i >= TSTRSZ) { |
| 305 | if (++curtstr >= &tstrbuf[NTSTRBUF]) |
| 306 | cerror("out of temporary string space"); |
| 307 | tstrused = 0; |
| 308 | if (*curtstr == 0) { |
| 309 | dp = (char *)malloc(TSTRSZ); |
| 310 | if (dp == 0) |
| 311 | cerror("out of memory (tstr)"); |
| 312 | *curtstr = dp; |
| 313 | } |
| 314 | } |
| 315 | strcpy(dp = *curtstr+tstrused, cp); |
| 316 | tstrused += i + 1; |
| 317 | return (dp); |
| 318 | } |
| 319 | #endif |