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 11int nerrors = 0; /* number of errors */ 12 13extern unsigned int offsz; 14 15unsigned 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 29NODE *lastfree; /* pointer to last free node; (for allocator) */ 30 31 /* VARARGS1 */ 32uerror( 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 */ 47cerror( 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 63int Wflag = 0; /* Non-zero means do not print warnings */ 64 65 /* VARARGS1 */ 66werror( 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 77tinit(){ /* 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 88NODE * 89talloc(){ 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 100tcheck(){ /* 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 } 112tfree( p ) NODE *p; { 113 /* free the tree p */ 114 extern tfree1(); 115 116 if( p->in.op != FREE ) walkf( p, tfree1 ); 117 118 } 119 120tfree1(p) NODE *p; { 121 if( p == 0 ) cerror( "freeing blank tree!"); 122 else p->in.op = FREE; 123 } 124 125fwalk( 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 150walkf( 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 162int dope[ DSIZE ]; 163char *opst[DSIZE]; 164 165struct 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 DCON, "DCON", LTYPE, 174 CCODES, "CCODES", LTYPE, 175 UNARY MINUS, "U-", UTYPE, 176 UNARY MUL, "U*", UTYPE, 177 UNARY AND, "U&", UTYPE, 178 UNARY CALL, "UCALL", UTYPE|CALLFLG, 179 UNARY FORTCALL, "UFCALL", UTYPE|CALLFLG, 180 NOT, "!", UTYPE|LOGFLG, 181 COMPL, "~", UTYPE, 182 FORCE, "FORCE", UTYPE, 183 INIT, "INIT", UTYPE, 184 SCONV, "SCONV", UTYPE, 185 PCONV, "PCONV", UTYPE, 186 PLUS, "+", BITYPE|FLOFLG|SIMPFLG|COMMFLG, 187 ASG PLUS, "+=", BITYPE|ASGFLG|ASGOPFLG|FLOFLG|SIMPFLG|COMMFLG, 188 MINUS, "-", BITYPE|FLOFLG|SIMPFLG, 189 ASG MINUS, "-=", BITYPE|FLOFLG|SIMPFLG|ASGFLG|ASGOPFLG, 190 MUL, "*", BITYPE|FLOFLG|MULFLG, 191 ASG MUL, "*=", BITYPE|FLOFLG|MULFLG|ASGFLG|ASGOPFLG, 192 AND, "&", BITYPE|SIMPFLG|COMMFLG, 193 ASG AND, "&=", BITYPE|SIMPFLG|COMMFLG|ASGFLG|ASGOPFLG, 194 QUEST, "?", BITYPE, 195 COLON, ":", BITYPE, 196 ANDAND, "&&", BITYPE|LOGFLG, 197 OROR, "||", BITYPE|LOGFLG, 198 CM, ",", BITYPE, 199 COMOP, ",OP", BITYPE, 200 ASSIGN, "=", BITYPE|ASGFLG, 201 DIV, "/", BITYPE|FLOFLG|MULFLG|DIVFLG, 202 ASG DIV, "/=", BITYPE|FLOFLG|MULFLG|DIVFLG|ASGFLG|ASGOPFLG, 203 MOD, "%", BITYPE|DIVFLG, 204 ASG MOD, "%=", BITYPE|DIVFLG|ASGFLG|ASGOPFLG, 205 LS, "<<", BITYPE|SHFFLG, 206 ASG LS, "<<=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG, 207 RS, ">>", BITYPE|SHFFLG, 208 ASG RS, ">>=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG, 209 OR, "|", BITYPE|COMMFLG|SIMPFLG, 210 ASG OR, "|=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG, 211 ER, "^", BITYPE|COMMFLG|SIMPFLG, 212 ASG ER, "^=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG, 213 INCR, "++", BITYPE|ASGFLG, 214 DECR, "--", BITYPE|ASGFLG, 215 STREF, "->", BITYPE, 216 CALL, "CALL", BITYPE|CALLFLG, 217 FORTCALL, "FCALL", BITYPE|CALLFLG, 218 EQ, "==", BITYPE|LOGFLG, 219 NE, "!=", BITYPE|LOGFLG, 220 LE, "<=", BITYPE|LOGFLG, 221 LT, "<", BITYPE|LOGFLG, 222 GE, ">", BITYPE|LOGFLG, 223 GT, ">", BITYPE|LOGFLG, 224 UGT, "UGT", BITYPE|LOGFLG, 225 UGE, "UGE", BITYPE|LOGFLG, 226 ULT, "ULT", BITYPE|LOGFLG, 227 ULE, "ULE", BITYPE|LOGFLG, 228 ARS, "A>>", BITYPE, 229 TYPE, "TYPE", LTYPE, 230 LB, "[", BITYPE, 231 CBRANCH, "CBRANCH", BITYPE, 232 FLD, "FLD", UTYPE, 233 PMCONV, "PMCONV", BITYPE, 234 PVCONV, "PVCONV", BITYPE, 235 RETURN, "RETURN", BITYPE|ASGFLG|ASGOPFLG, 236 CAST, "CAST", BITYPE|ASGFLG|ASGOPFLG, 237 GOTO, "GOTO", UTYPE, 238 STASG, "STASG", BITYPE|ASGFLG, 239 STARG, "STARG", UTYPE, 240 STCALL, "STCALL", BITYPE|CALLFLG, 241 UNARY STCALL, "USTCALL", UTYPE|CALLFLG, 242 243 -1, "", 0 244}; 245 246mkdope(){ 247 register struct dopest *q; 248 249 for( q = indope; q->dopeop >= 0; ++q ){ 250 dope[q->dopeop] = q->dopeval; 251 opst[q->dopeop] = q->opst; 252 } 253 } 254# ifndef BUG4 255tprint( t ) TWORD t; { /* output a nice description of the type of t */ 256 257 static char * tnames[] = { 258 "undef", 259 "farg", 260 "char", 261 "short", 262 "int", 263 "long", 264 "float", 265 "double", 266 "strty", 267 "unionty", 268 "enumty", 269 "moety", 270 "uchar", 271 "ushort", 272 "unsigned", 273 "ulong", 274 "?", "?" 275 }; 276 277 for(;; t = DECREF(t) ){ 278 279 if( ISPTR(t) ) printf( "PTR " ); 280 else if( ISFTN(t) ) printf( "FTN " ); 281 else if( ISARY(t) ) printf( "ARY " ); 282 else { 283 printf( "%s", tnames[t] ); 284 return; 285 } 286 } 287 } 288# endif 289 290#ifdef FLEXNAMES 291#define NTSTRBUF 40 292#define TSTRSZ 2048 293char itstrbuf[TSTRSZ]; 294char *tstrbuf[NTSTRBUF] = { itstrbuf }; 295char **curtstr = tstrbuf; 296int tstrused; 297 298char * 299tstr(cp) 300 register char *cp; 301{ 302 register int i = strlen(cp); 303 register char *dp; 304 305 if (tstrused + i >= TSTRSZ) { 306 if (++curtstr >= &tstrbuf[NTSTRBUF]) 307 cerror("out of temporary string space"); 308 tstrused = 0; 309 if (*curtstr == 0) { 310 dp = (char *)malloc(TSTRSZ); 311 if (dp == 0) 312 cerror("out of memory (tstr)"); 313 *curtstr = dp; 314 } 315 } 316 strcpy(dp = *curtstr+tstrused, cp); 317 tstrused += i + 1; 318 return (dp); 319} 320#endif 321