c00.c (8502B)
1 /* C compiler 2 3 Copyright 1972 Bell Telephone Laboratories, Inc. 4 5 */ 6 7 ossiz 250; 8 ospace() {} /* fake */ 9 10 init(s, t) 11 char s[]; { 12 extern lookup, symbuf, namsiz; 13 char symbuf[], sp[]; 14 int np[], i; 15 16 i = namsiz; 17 sp = symbuf; 18 while(i--) 19 if ((*sp++ = *s++)=='\0') --s; 20 np = lookup(); 21 *np++ = 1; 22 *np = t; 23 } 24 25 main(argc, argv) 26 int argv[]; { 27 extern init, flush; 28 extern extdef, eof, open, creat; 29 extern fout, fin, error, exit, nerror, tmpfil; 30 31 if(argc<4) { 32 error("Arg count"); 33 exit(1); 34 } 35 if((fin=open(argv[1],0))<0) { 36 error("Can't find %s", argv[1]); 37 exit(1); 38 } 39 if((fout=creat(argv[2], 017))<0) { 40 error("Can't create %s", argv[2]); 41 exit(1); 42 } 43 tmpfil = argv[3]; 44 init("int", 0); 45 init("char", 1); 46 init("float", 2); 47 init("double", 3); 48 /* init("long", 4); */ 49 init("auto", 5); 50 init("extern", 6); 51 init("static", 7); 52 init("goto", 10); 53 init("return", 11); 54 init("if", 12); 55 init("while", 13); 56 init("else", 14); 57 init("switch", 15); 58 init("case", 16); 59 init("break", 17); 60 init("continue", 18); 61 init("do", 19); 62 init("default", 20); 63 while(!eof) { 64 extdef(); 65 blkend(); 66 } 67 flush(); 68 flshw(); 69 exit(nerror!=0); 70 } 71 72 lookup() { 73 extern hshtab[], hshsiz, pssiz, symbuf[]; 74 extern hshlen, hshused, exit, error, nwps; 75 auto i, j, np[], sp[], rp[]; 76 77 i = 0; 78 sp = symbuf; 79 j = nwps; 80 while(j--) 81 i =+ *sp++; 82 if (i<0) i = -i; 83 i =% hshsiz; 84 i =* pssiz; 85 while(*(np = &hshtab[i+4])) { 86 sp = symbuf; 87 j = nwps; 88 while(j--) 89 if (*np++ != *sp++) goto no; 90 return(&hshtab[i]); 91 no: if ((i =+ pssiz) >= hshlen) i = 0; 92 } 93 if(hshused++ > hshsiz) { 94 error("Symbol table overflow"); 95 exit(1); 96 } 97 rp = np = &hshtab[i]; 98 sp = symbuf; 99 j = 4; 100 while(j--) 101 *np++ = 0; 102 j = nwps; 103 while(j--) 104 *np++ = *sp++; 105 return(rp); 106 } 107 108 symbol() { 109 extern peeksym, peekc, eof, getchar, subseq, error, line; 110 extern csym[], getstr, symbuf, namsiz, lookup[], ctab, cval; 111 auto b, c; 112 char symbuf[], sp[], ctab[]; 113 114 if (peeksym>=0) { 115 c = peeksym; 116 peeksym = -1; 117 return(c); 118 } 119 if (peekc) { 120 c = peekc; 121 peekc = 0; 122 } else 123 if (eof) 124 return(0); else 125 c = getchar(); 126 loop: 127 switch(ctab[c]) { 128 129 case 125: /* newline */ 130 line++; 131 132 case 126: /* white space */ 133 c = getchar(); 134 goto loop; 135 136 case 0: /* EOF */ 137 eof++; 138 return(0); 139 140 case 40: /* + */ 141 return(subseq(c,40,30)); 142 143 case 41: /* - */ 144 return(subseq(c,41,31)); 145 146 case 80: /* = */ 147 if (subseq(' ',0,1)) return(80); 148 c = symbol(); 149 if (c>=40 & c<=49) 150 return(c+30); 151 if (c==80) 152 return(60); 153 peeksym = c; 154 return(80); 155 156 case 63: /* < */ 157 if (subseq(c,0,1)) return(46); 158 return(subseq('=',63,62)); 159 160 case 65: /* > */ 161 if (subseq(c,0,1)) return(45); 162 return(subseq('=',65,64)); 163 164 case 34: /* ! */ 165 return(subseq('=',34,61)); 166 167 case 43: /* / */ 168 if (subseq('*',1,0)) 169 return(43); 170 com: 171 c = getchar(); 172 com1: 173 if (c=='\0') { 174 eof++; 175 error("Nonterminated comment"); 176 return(0); 177 } 178 if (c=='\n') 179 line++; 180 if (c!='*') 181 goto com; 182 c = getchar(); 183 if (c!='/') 184 goto com1; 185 c = getchar(); 186 goto loop; 187 188 case 124: /* number */ 189 cval = 0; 190 if (c=='0') 191 b = 8; else 192 b = 10; 193 while(ctab[c]==124) { 194 cval = cval*b + c -'0'; 195 c = getchar(); 196 } 197 peekc = c; 198 return(21); 199 200 case 122: /* " */ 201 return(getstr()); 202 203 case 121: /* ' */ 204 return(getcc()); 205 206 case 123: /* letter */ 207 sp = symbuf; 208 while(ctab[c]==123 | ctab[c]==124) { 209 if (sp<symbuf+namsiz) *sp++ = c; 210 c = getchar(); 211 } 212 while(sp<symbuf+namsiz) 213 *sp++ = '\0'; 214 peekc = c; 215 csym = lookup(); 216 if (csym[0]==1) { /* keyword */ 217 cval = csym[1]; 218 return(19); 219 } 220 return(20); 221 222 case 127: /* unknown */ 223 error("Unknown character"); 224 c = getchar(); 225 goto loop; 226 227 } 228 return(ctab[c]); 229 } 230 231 subseq(c,a,b) { 232 extern getchar, peekc; 233 234 if (!peekc) 235 peekc = getchar(); 236 if (peekc != c) 237 return(a); 238 peekc = 0; 239 return(b); 240 } 241 getstr() { 242 extern isn, cval; 243 auto c; 244 245 printf(".data;L%d:.byte ", cval=isn++); 246 while((c=mapch('"')) >= 0) 247 printf("%o,", c); 248 printf("0;.even;.text\n"); 249 return(22); 250 } 251 252 getcc() 253 { 254 extern cval, ncpw; 255 auto c, cc; 256 char cp[]; 257 258 cval = 0; 259 cp = &cval; 260 cc = 0; 261 while((c=mapch('\'')) >= 0) 262 if(cc++ < ncpw) 263 *cp++ = c; 264 if(cc>ncpw) 265 error("Long character constant"); 266 return(21); 267 } 268 269 mapch(c) 270 { 271 extern peekc, line; 272 auto a; 273 274 if((a=getchar())==c) 275 return(-1); 276 switch(a) { 277 278 case '\n': 279 case 0: 280 error("Nonterminated string"); 281 peekc = a; 282 return(-1); 283 284 case '\\': 285 switch (a=getchar()) { 286 287 case 't': 288 return('\t'); 289 290 case 'n': 291 return('\n'); 292 293 case '0': 294 return('\0'); 295 296 case 'r': 297 return('\r'); 298 299 case '\n': 300 line++; 301 return('\n'); 302 } 303 304 } 305 return(a); 306 } 307 308 tree() { 309 extern symbol, block, csym[], ctyp, isn, 310 peeksym, opdope[], build, error, cp[], cmst[], 311 space, ospace, cval, ossiz, exit, errflush, cmsiz; 312 313 auto op[], opst[20], pp[], prst[20], andflg, o, 314 p, ps, os; 315 316 space = ospace; 317 op = opst; 318 pp = prst; 319 cp = cmst; 320 *op = 200; /* stack EOF */ 321 *pp = 06; 322 andflg = 0; 323 324 advanc: 325 switch (o=symbol()) { 326 327 /* name */ 328 case 20: 329 if (*csym==0) 330 if((peeksym=symbol())==6) 331 *csym = 6; /* extern */ 332 else { 333 if(csym[2]==0) /* unseen so far */ 334 csym[2] = isn++; 335 } 336 if(*csym==6) /* extern */ 337 *cp++ = block(5,20,csym[1],0,*csym, 338 csym[4],csym[5],csym[6],csym[7]); 339 else 340 *cp++ = block(2,20,csym[1],0,*csym,csym[2]); 341 goto tand; 342 343 /* short constant */ 344 case 21: 345 case21: 346 *cp++ = block(1,21,ctyp,0,cval); 347 goto tand; 348 349 /* string constant */ 350 case 22: 351 *cp++ = block(1,22,17,0,cval); 352 353 tand: 354 if(cp>=cmst+cmsiz) { 355 error("Expression overflow"); 356 exit(1); 357 } 358 if (andflg) 359 goto syntax; 360 andflg = 1; 361 goto advanc; 362 363 /* ++, -- */ 364 case 30: 365 case 31: 366 if (andflg) 367 o =+ 2; 368 goto oponst; 369 370 /* ! */ 371 case 34: 372 if (andflg) 373 goto syntax; 374 goto oponst; 375 376 /* - */ 377 case 41: 378 if (!andflg) { 379 peeksym = symbol(); 380 if (peeksym==21) { 381 peeksym = -1; 382 cval = -cval; 383 goto case21; 384 } 385 o = 37; 386 } 387 andflg = 0; 388 goto oponst; 389 390 /* & */ 391 /* * */ 392 case 47: 393 case 42: 394 if (andflg) 395 andflg = 0; else 396 if(o==47) 397 o = 35; 398 else 399 o = 36; 400 goto oponst; 401 402 /* ( */ 403 case 6: 404 if (andflg) { 405 o = symbol(); 406 if (o==7) 407 o = 101; else { 408 peeksym = o; 409 o = 100; 410 andflg = 0; 411 } 412 } 413 goto oponst; 414 415 /* ) */ 416 /* ] */ 417 case 5: 418 case 7: 419 if (!andflg) 420 goto syntax; 421 goto oponst; 422 } 423 424 /* binaries */ 425 if (!andflg) 426 goto syntax; 427 andflg = 0; 428 429 oponst: 430 p = (opdope[o]>>9) & 077; 431 opon1: 432 ps = *pp; 433 if (p>ps | p==ps & (opdope[o]&0200)!=0) { /* right-assoc */ 434 putin: 435 switch (o) { 436 437 case 6: /* ( */ 438 case 4: /* [ */ 439 case 100: /* call */ 440 p = 04; 441 } 442 if(op>=opst+20) { /* opstack size */ 443 error("expression overflow"); 444 exit(1); 445 } 446 *++op = o; 447 *++pp = p; 448 goto advanc; 449 } 450 --pp; 451 switch (os = *op--) { 452 453 /* EOF */ 454 case 200: 455 peeksym = o; 456 return(*--cp); 457 458 /* call */ 459 case 100: 460 if (o!=7) 461 goto syntax; 462 build(os); 463 goto advanc; 464 465 /* mcall */ 466 case 101: 467 *cp++ = 0; /* 0 arg call */ 468 os = 100; 469 goto fbuild; 470 471 /* ( */ 472 case 6: 473 if (o!=7) 474 goto syntax; 475 goto advanc; 476 477 /* [ */ 478 case 4: 479 if (o!=5) 480 goto syntax; 481 build(4); 482 goto advanc; 483 } 484 fbuild: 485 build(os); 486 goto opon1; 487 488 syntax: 489 error("Expression syntax"); 490 errflush(o); 491 return(0); 492 } 493 494 declare(kw) { 495 extern csym[], symbol, paraml[], parame[]; 496 extern error, cval, errflush, peeksym, exit; 497 int t[], n, o; 498 499 while((o=symbol())==20) { /* name */ 500 if(kw>=5) { /* type or sort? */ 501 if(*csym>0) 502 error("%p redeclared", csym[4]); 503 *csym = kw; 504 } else { 505 if ((csym[1]&017)!=0) 506 error("%p redeclared", &csym[4]); 507 csym[1] =| csym[1]&0760 | kw; 508 if (*csym==0) 509 *csym = -2; 510 } 511 while((o=symbol())==4) { /* [ */ 512 if((o=symbol())==21) { /* const */ 513 if(csym[1]>=020) 514 error("Bad vector"); 515 csym[3] = cval; 516 o = symbol(); 517 } 518 if (o!=5) /* ] */ 519 goto syntax; 520 csym[1] =+ 020; 521 } 522 if(kw==8) { /* parameter */ 523 *csym = -1; 524 if (paraml==0) 525 paraml = csym; 526 else 527 *parame = csym; 528 parame = csym; 529 } 530 if (o!=9) /* , */ 531 break; 532 } 533 if(o==1 & kw!=8 | o==7 & kw==8) 534 return; 535 syntax: 536 error("Declaration syntax"); 537 errflush(o); 538 } 539 540 /* storage */ 541 542 regtab 0; 543 efftab 1; 544 cctab 2; 545 sptab 3; 546 symbuf[4]; 547 pssiz 8; 548 namsiz 8; 549 nwps 4; 550 hshused 0; 551 hshsiz 100; 552 hshlen 800; /* 8*hshsiz */ 553 hshtab[800]; 554 space 0; 555 cp 0; 556 cmsiz 40; 557 cmst[40]; 558 ctyp 0; 559 isn 1; 560 swsiz 120; 561 swtab[120]; 562 swp 0; 563 contlab 0; 564 brklab 0; 565 deflab 0; 566 nreg 4; 567 maprel[] 60,61,64,65,62,63,68,69,66,67; 568 nauto 0; 569 stack 0; 570 peeksym 0177777; 571 peekc 0; 572 eof 0; 573 line 1; 574 csym 0; 575 cval 0; 576 ncpw 2; 577 nerror 0; 578 paraml; 579 parame; 580 tmpfil; 581