c10.c (7185B)
1 /* 2 3 C compiler, part 2 4 5 Copyright 1972 Bell Telephone Laboratories, Inc. 6 7 */ 8 9 ospace() {} /* fake */ 10 11 waste() /* waste space */ 12 { 13 waste(waste(waste),waste(waste),waste(waste)); 14 waste(waste(waste),waste(waste),waste(waste)); 15 waste(waste(waste),waste(waste),waste(waste)); 16 waste(waste(waste),waste(waste),waste(waste)); 17 waste(waste(waste),waste(waste),waste(waste)); 18 waste(waste(waste),waste(waste),waste(waste)); 19 waste(waste(waste),waste(waste),waste(waste)); 20 waste(waste(waste),waste(waste),waste(waste)); 21 } 22 main(argc, argv) 23 char argv[][]; 24 { 25 extern fout, fin, nerror, line; 26 extern getwrd, rcexpr, ospace, tmpfil; 27 extern cctab[], regtab[], efftab[], sptab[]; 28 int sp[], c, table[], tabtab[3][], tree; 29 30 if (argc<4) { 31 error("Arg count"); 32 exit(1); 33 } 34 if((fin=open(argv[1],0))<0) { 35 error("Cant't find %s", argv[1]); 36 exit(1); 37 } 38 if((fout=creat(argv[3],017))<0) { 39 error("Can't create %s", argv[3]); 40 exit(1); 41 } 42 tmpfil = argv[2]; 43 44 tabtab[0] = regtab; 45 tabtab[1] = efftab; 46 tabtab[2] = cctab; 47 tabtab[3] = sptab; 48 while(c=getchar()) { 49 if(c=='#') { 50 sp = ospace; 51 c = getwrd(); 52 tree = getwrd(); 53 table = tabtab[getwrd()]; 54 line = getwrd(); 55 while(c--) 56 *sp++ = getwrd(); 57 rcexpr(tree, table, 0); 58 } else 59 putchar(c); 60 } 61 flush(); 62 exit(nerror!=0); 63 } 64 65 match(tree, table, nreg) 66 int tree[], table[]; { 67 extern opdope[], dcalc, notcompat; 68 int op, d1, d2, t1, t2, p1[], p2[]; 69 char mp[]; 70 71 if (tree==0) 72 return(0); 73 op = *tree; 74 if (op>=29) /* if not leaf */ 75 p1 = tree[3]; 76 else 77 p1 = tree; 78 t1 = p1[1]; 79 d1 = dcalc(p1, nreg); 80 if ((opdope[op]&01)!=0) { /* binary? */ 81 p2 = tree[4]; 82 t2 = p2[1]; 83 d2 = dcalc(p2, nreg); 84 } 85 while(*table) { 86 if (*table++ == op) goto foundop; 87 table++; 88 } 89 return(0); 90 foundop: 91 table = *table; 92 nxtry: 93 mp = table; 94 if (*mp == 0) 95 return(0); 96 if (d1 > (*mp&077) | (*mp>=0100)&(*p1!=36)) 97 goto notyet; 98 if (notcompat(t1, mp[1])) 99 goto notyet; 100 if ((opdope[op]&01)!=0 & p2!=0) { 101 if (d2 > (mp[2]&077) | (mp[2]>=0100)&(*p2!=36)) 102 goto notyet; 103 if (notcompat(t2,mp[3])) 104 goto notyet; 105 } 106 now: 107 return(table[2]); 108 notyet: 109 table = table+3; 110 goto nxtry; 111 } 112 113 rcexpr(tree, table, reg) 114 int tree[]; { 115 extern cexpr, regtab, cctab, sptab, printf, error; 116 extern jumpc, cbranch; 117 118 if(tree==0) 119 return; 120 if(*tree >= 103) { 121 (*tree==103?jumpc:cbranch)(tree[1],tree[2],tree[3],0); 122 return; 123 } 124 if (cexpr(tree, table, reg)) 125 return; 126 if (table!=regtab) 127 if(cexpr(tree, regtab, reg)) { 128 if (table==sptab) 129 printf("mov r%d,-(sp)\n", reg); 130 if (table==cctab) 131 printf("tst r%d\n", reg); 132 return; 133 } 134 error("No match for op %d", *tree); 135 } 136 137 cexpr(tree, table, reg) 138 int tree[][], table[]; { 139 extern match, nreg, printf, pname, putchar, regtab; 140 extern sptab, cctab, rcexpr, prins, rlength, popstk; 141 extern collcon, isn, label, branch, cbranch, fltmod; 142 int p1[], p2[], c, r, p[], otable[], ctable[], regtab[], cctab[]; 143 char string[], match[]; 144 145 if ((c = *tree)==100) { /* call */ 146 p1 = tree[3]; 147 p2 = tree[4]; 148 r = 0; 149 if(p2) { 150 while (*p2==9) { /* comma */ 151 rcexpr(p2[4], sptab, 0); 152 r =+ rlength((p=p2[4])[1]); 153 p2 = p2[3]; 154 } 155 rcexpr(p2, sptab, 0); 156 r =+ rlength(p2[1]); 157 } 158 *tree = 101; 159 tree[2] = r; /* save arg length */ 160 } 161 if(c==90) { /* ? */ 162 cbranch(tree[3], c=isn++, 0, reg); 163 rcexpr(tree[4][3], table, reg); 164 branch(r=isn++, 0); 165 label(c); 166 rcexpr(tree[4][4], table, reg); 167 label(r); 168 return(1); 169 } 170 if ((string=match(tree, table, nreg-reg))==0) 171 return(0); 172 p1 = tree[3]; 173 p2 = tree[4]; 174 loop: 175 switch(c = *string++) { 176 177 case '\0': 178 p = tree; 179 if (*p==101 & p[2]>0) { 180 popstk(p[2]); 181 } 182 return(1); 183 184 /* A1 */ 185 case 'A': 186 p = tree[3]; 187 goto adr; 188 189 /* A2 */ 190 case 'B': 191 p = tree[4]; 192 goto adr; 193 194 /* A */ 195 case 'O': 196 p = tree; 197 adr: 198 pname(p); 199 goto loop; 200 201 /* I */ 202 case 'M': 203 if ((c = *string)=='\'') 204 string++; else 205 c = 0; 206 prins(*tree, c); 207 goto loop; 208 209 /* B1 */ 210 case 'C': 211 p = tree[3]; 212 goto pbyte; 213 214 /* BF */ 215 case 'P': 216 p = tree; 217 goto pb1; 218 219 /* B2 */ 220 case 'D': 221 p = tree[4]; 222 pbyte: 223 if (p[1]==1) /* char type? */ 224 putchar('b'); 225 pb1: 226 if (isfloat(p)) 227 putchar('f'); 228 goto loop; 229 230 /* BE */ 231 case 'L': 232 if (tree[3][1]==1 | tree[4][1]==1) 233 putchar('b'); 234 goto loop; 235 236 /* C1 */ 237 case 'E': 238 p = p1[3]; 239 goto const; 240 241 /* C2 */ 242 case 'F': 243 p = p2[3]; 244 const: 245 printf("%o", p); 246 goto loop; 247 248 /* F */ 249 case 'G': 250 p = p1; 251 goto subtre; 252 253 /* S */ 254 case 'K': 255 p = p2; 256 goto subtre; 257 258 /* H */ 259 case 'H': 260 p = tree; 261 262 subtre: 263 ctable = regtab; 264 r = reg; 265 c = *string++ - 'A'; 266 if ((c&02)!=0) 267 ctable = sptab; 268 if ((c&04)!=0) 269 ctable = cctab; 270 if((c&010)!=0) 271 r = reg+1; 272 if((c&01)!=0) 273 if(*p==36) { 274 p = p[3]; 275 if(collcon(p) & ctable!=sptab) 276 p = p[3]; 277 } 278 rcexpr(p, ctable, r); 279 goto loop; 280 281 /* R */ 282 case 'I': 283 r = reg; 284 goto preg; 285 286 /* R1 */ 287 case 'J': 288 r = reg+1; 289 preg: 290 printf("r%d", r); 291 goto loop; 292 293 case '#': 294 p = p1[3]; 295 goto nmbr; 296 297 case '"': 298 p = p2[3]; 299 goto nmbr; 300 case '~': 301 p = tree[3]; 302 303 nmbr: 304 if(collcon(p)) { 305 c = *p; 306 if(r = (p=p[4])[3]) 307 printf("%o", c==40?r:-r); 308 } 309 goto loop; 310 311 /* M */ 312 case 'N': 313 if ((c=isfloat(tree, &string))==fltmod) 314 goto loop; 315 printf((fltmod=c)==2?"setf\n":"setd\n"); 316 goto loop; 317 318 /* Z */ 319 case 'Z': 320 printf("$%o", p1[4]); 321 goto loop; 322 } 323 putchar(c); 324 goto loop; 325 } 326 327 pname(p) 328 int p[][][]; { 329 extern putchar, printf, error; 330 char np[]; 331 int i; 332 333 loop: 334 switch(*p) { 335 336 case 21: /* const */ 337 printf("$%o", p[3]); 338 return; 339 340 case 22: /* string */ 341 printf("$l%d", p[3]); 342 return; 343 344 case 20: /* name */ 345 switch(p[3]) { 346 347 case 5: /* auto, param */ 348 printf("%o(r5)", p[4]); 349 return; 350 351 /* extern */ 352 case 6: 353 printf("%p", &p[4]); 354 return; 355 356 } 357 printf("L%d", p[4]); 358 return; 359 360 case 35: /* & */ 361 putchar('$'); 362 p = p[3]; 363 goto loop; 364 365 case 36: /* * */ 366 putchar('*'); 367 p = p[3]; 368 goto loop; 369 } 370 error("pname called illegally"); 371 } 372 373 dcalc(p, nreg) 374 int p[]; { 375 int op, t; 376 377 if (p==0) 378 return(0); 379 op = *p; 380 switch (op) { 381 382 case 20: /* name */ 383 case 22: /* string */ 384 case 23: /* float */ 385 case 24: /* double */ 386 return(12); 387 388 case 21: /* short constant */ 389 return(p[3]==0? 4:8); 390 391 case 35: /* & */ 392 return(12); 393 394 case 36: /* * */ 395 if ((op=dcalc(p[3], nreg))<16) 396 return(16); 397 } 398 399 def: 400 return(p[2]<=nreg? 20: 24); 401 } 402 403 notcompat(at, st) { 404 405 if (st==0) /* word, byte */ 406 return(at>1 & at<16); 407 if (st==1) /* word */ 408 return(at>0 & at<16); 409 st =- 2; 410 if (st==2 & at==3) 411 at = 2; 412 return(st != at); 413 } 414 415 prins(op, c) { 416 extern instab[], printf; 417 int insp[]; 418 419 insp = instab; 420 while(*insp) { 421 if (*insp++ == op) { 422 if ((c = insp[c!=0])==0) 423 goto err; 424 printf("%s", c); 425 return; 426 } else 427 insp = insp + 2; 428 } 429 err: 430 error("No match' for op %d", op); 431 } 432 433 collcon(p) 434 int p[]; { 435 int p1[]; 436 437 if(*p==40 | *p==41) 438 if(*(p1=p[4])==21) 439 return(1); 440 return(0); 441 } 442 443 isfloat(t, s) 444 int t[]; 445 char s[][]; 446 { 447 extern opdope[]; 448 int rt; 449 450 rt = **s - '0'; 451 if (rt==2 | rt==4) { 452 (*s)++; 453 return(rt>2?3:2); 454 } 455 if ((opdope[t[0]]&010)!=0) /* relational */ 456 t = t[3]; 457 if ((rt=t[1])>=2 & rt<=3) 458 return(rt); 459 return(0); 460 } 461 462 nreg 4; 463 isn 10000; 464 namsiz 8; 465 line; 466 tmpfil; 467 nerror; 468 fltmod; 469