c00.c (11467B)
1 /* C compiler 2 3 Copyright 1972 Bell Telephone Laboratories, Inc. 4 5 */ 6 7 init(s, t) 8 char s[]; { 9 extern symbuf, namsiz; 10 char symbuf[], sp[]; 11 int np[], i; 12 13 i = namsiz; 14 sp = symbuf; 15 while(i--) 16 if ((*sp++ = *s++)=='\0') --s; 17 np = lookup(); 18 *np++ = 1; 19 *np = t; 20 } 21 22 main(argc, argv) 23 int argv[]; { 24 extern extdef, eof; 25 extern fout, fin, nerror, tmpfil, xdflg; 26 27 if(argc<4) { 28 error("Arg count"); 29 exit(1); 30 } 31 if((fin=open(argv[1],0))<0) { 32 error("Can't find %s", argv[1]); 33 exit(1); 34 } 35 if((fout=creat(argv[2], 017))<0) { 36 error("Can't create %s", argv[2]); 37 exit(1); 38 } 39 tmpfil = argv[3]; 40 xdflg++; 41 init("int", 0); 42 init("char", 1); 43 init("float", 2); 44 init("double", 3); 45 init("struct", 4); 46 init("auto", 5); 47 init("extern", 6); 48 init("static", 7); 49 init("goto", 10); 50 init("return", 11); 51 init("if", 12); 52 init("while", 13); 53 init("else", 14); 54 init("switch", 15); 55 init("case", 16); 56 init("break", 17); 57 init("continue", 18); 58 init("do", 19); 59 init("default", 20); 60 xdflg = 0; 61 while(!eof) { 62 extdef(); 63 blkend(); 64 } 65 flush(); 66 flshw(); 67 exit(nerror!=0); 68 } 69 70 lookup() { 71 extern hshtab, hshsiz, pssiz, symbuf, xdflg; 72 int hshtab[], symbuf[]; 73 extern hshlen, hshused, nwps; 74 auto i, j, np[], sp[], rp[]; 75 76 i = 0; 77 sp = symbuf; 78 j = nwps; 79 while(j--) 80 i =+ *sp++ & 077577; 81 if (i<0) i = -i; 82 i =% hshsiz; 83 i =* pssiz; 84 while(*(np = &hshtab[i+4])) { 85 sp = symbuf; 86 j = nwps; 87 while(j--) 88 if ((*np++&077577) != *sp++) goto no; 89 return(&hshtab[i]); 90 no: if ((i =+ pssiz) >= hshlen) i = 0; 91 } 92 if(++hshused > hshsiz) { 93 error("Symbol table overflow"); 94 exit(1); 95 } 96 rp = np = &hshtab[i]; 97 sp = symbuf; 98 j = 4; 99 while(j--) 100 *np++ = 0; 101 j = nwps; 102 while(j--) 103 *np++ = *sp++; 104 *np = 0; 105 if (xdflg) 106 rp[4] =| 0200; /* mark non-deletable */ 107 return(rp); 108 } 109 110 symbol() { 111 extern peeksym, peekc, eof, line; 112 extern csym, symbuf, namsiz, lookup, ctab, cval; 113 int csym[]; 114 extern isn, mosflg, xdflg; 115 auto b, c; 116 char symbuf[], sp[], ctab[]; 117 118 if (peeksym>=0) { 119 c = peeksym; 120 peeksym = -1; 121 if (c==20) 122 mosflg = 0; 123 return(c); 124 } 125 if (peekc) { 126 c = peekc; 127 peekc = 0; 128 } else 129 if (eof) 130 return(0); else 131 c = getchar(); 132 loop: 133 switch(ctab[c]) { 134 135 case 125: /* newline */ 136 line++; 137 138 case 126: /* white space */ 139 c = getchar(); 140 goto loop; 141 142 case 0: /* EOF */ 143 eof++; 144 return(0); 145 146 case 40: /* + */ 147 return(subseq(c,40,30)); 148 149 case 41: /* - */ 150 return(subseq(c,subseq('>',41,50),31)); 151 152 case 80: /* = */ 153 if (subseq(' ',0,1)) return(80); 154 c = symbol(); 155 if (c>=40 & c<=49) 156 return(c+30); 157 if (c==80) 158 return(60); 159 peeksym = c; 160 return(80); 161 162 case 63: /* < */ 163 if (subseq(c,0,1)) return(46); 164 return(subseq('=',63,62)); 165 166 case 65: /* > */ 167 if (subseq(c,0,1)) return(45); 168 return(subseq('=',65,64)); 169 170 case 34: /* ! */ 171 return(subseq('=',34,61)); 172 173 case 43: /* / */ 174 if (subseq('*',1,0)) 175 return(43); 176 com: 177 c = getchar(); 178 com1: 179 if (c=='\0') { 180 eof++; 181 error("Nonterminated comment"); 182 return(0); 183 } 184 if (c=='\n') 185 line++; 186 if (c!='*') 187 goto com; 188 c = getchar(); 189 if (c!='/') 190 goto com1; 191 c = getchar(); 192 goto loop; 193 194 case 120: /* . */ 195 case 124: /* number */ 196 peekc = c; 197 switch(c=getnum(c=='0'? 8:10)) { 198 case 25: /* float 0 */ 199 c = 23; 200 break; 201 202 case 23: /* float non 0 */ 203 cval = isn++; 204 } 205 return(c); 206 207 case 122: /* " */ 208 return(getstr()); 209 210 case 121: /* ' */ 211 return(getcc()); 212 213 case 123: /* letter */ 214 sp = symbuf; 215 if (mosflg) { 216 *sp++ = '.'; 217 mosflg = 0; 218 } 219 while(ctab[c]==123 | ctab[c]==124) { 220 if (sp<symbuf+namsiz) *sp++ = c; 221 c = getchar(); 222 } 223 while(sp<symbuf+namsiz) 224 *sp++ = '\0'; 225 peekc = c; 226 csym = lookup(); 227 if (csym[0]==1) { /* keyword */ 228 cval = csym[1]; 229 return(19); 230 } 231 return(20); 232 233 case 127: /* unknown */ 234 error("Unknown character"); 235 c = getchar(); 236 goto loop; 237 238 } 239 return(ctab[c]); 240 } 241 242 subseq(c,a,b) { 243 extern peekc; 244 245 if (!peekc) 246 peekc = getchar(); 247 if (peekc != c) 248 return(a); 249 peekc = 0; 250 return(b); 251 } 252 getstr() { 253 extern isn, cval, strflg; 254 auto c; 255 char t[], d[]; 256 257 t = ".text"; 258 d = ".data"; 259 printf("%s;L%d:.byte ", (strflg?t:d), cval=isn++); 260 while((c=mapch('"')) >= 0) 261 printf("%o,", c); 262 printf("0;.even;%s\n", (strflg?d:t)); 263 return(22); 264 } 265 266 getcc() 267 { 268 extern cval, ncpw; 269 auto c, cc; 270 char cp[]; 271 272 cval = 0; 273 cp = &cval; 274 cc = 0; 275 while((c=mapch('\'')) >= 0) 276 if(cc++ < ncpw) 277 *cp++ = c; 278 if(cc>ncpw) 279 error("Long character constant"); 280 return(21); 281 } 282 283 mapch(c) 284 { 285 extern peekc, line; 286 auto a; 287 288 if((a=getchar())==c) 289 return(-1); 290 switch(a) { 291 292 case '\n': 293 case 0: 294 error("Nonterminated string"); 295 peekc = a; 296 return(-1); 297 298 case '\\': 299 switch (a=getchar()) { 300 301 case 't': 302 return('\t'); 303 304 case 'n': 305 return('\n'); 306 307 case '0': 308 return('\0'); 309 310 case 'r': 311 return('\r'); 312 313 case '\n': 314 line++; 315 return('\n'); 316 } 317 318 } 319 return(a); 320 } 321 322 tree() { 323 extern csym, ctyp, isn, fcval, peeksym, opdope, cp, cmst; 324 int csym[], opdope[], cp[], cmst[]; 325 extern space, cval, ossiz, cmsiz, mosflg, osleft; 326 double fcval; 327 int space[]; 328 329 int op[], opst[20], pp[], prst[20], andflg, o, 330 p, ps, os; 331 332 osleft = ossiz; 333 space = 0; 334 *space++ = 0; 335 op = opst; 336 pp = prst; 337 cp = cmst; 338 *op = 200; /* stack EOF */ 339 *pp = 06; 340 andflg = 0; 341 342 advanc: 343 switch (o=symbol()) { 344 345 /* name */ 346 case 20: 347 if (*csym==0) 348 if((peeksym=symbol())==6) { /* ( */ 349 *csym = 6; /* extern */ 350 csym[1] = 020; /* int() */ 351 } else { 352 csym[1] = 030; /* array */ 353 if (csym[2]==0) 354 csym[2] = isn++; 355 } 356 *cp++ = block(2,20,csym[1],csym[3],*csym,0); 357 if (*csym==6) { /* external */ 358 o = 3; 359 while(++o<8) { 360 pblock(csym[o]); 361 if ((csym[o]&077400) == 0) 362 break; 363 } 364 } else 365 pblock(csym[2]); 366 goto tand; 367 368 /* short constant */ 369 case 21: 370 case21: 371 *cp++ = block(1,21,ctyp,0,cval); 372 goto tand; 373 374 /* floating constant */ 375 case 23: 376 *cp++ = block(1,23,3,0,cval); 377 if (cval) /* non-0 */ 378 printf(".data;L%d:%o;%o;%o;%o;.text\n",cval,fcval); 379 goto tand; 380 381 /* string constant: fake a static char array */ 382 case 22: 383 *cp++ = block(3, 20, 031, 1, 7, 0, cval); 384 385 tand: 386 if(cp>=cmst+cmsiz) { 387 error("Expression overflow"); 388 exit(1); 389 } 390 if (andflg) 391 goto syntax; 392 andflg = 1; 393 goto advanc; 394 395 /* ++, -- */ 396 case 30: 397 case 31: 398 if (andflg) 399 o =+ 2; 400 goto oponst; 401 402 /* ! */ 403 case 34: 404 /* ~ */ 405 case 38: 406 if (andflg) 407 goto syntax; 408 goto oponst; 409 410 /* - */ 411 case 41: 412 if (!andflg) { 413 peeksym = symbol(); 414 if (peeksym==21) { 415 peeksym = -1; 416 cval = -cval; 417 goto case21; 418 } 419 o = 37; 420 } 421 andflg = 0; 422 goto oponst; 423 424 /* & */ 425 /* * */ 426 case 47: 427 case 42: 428 if (andflg) 429 andflg = 0; else 430 if(o==47) 431 o = 35; 432 else 433 o = 36; 434 goto oponst; 435 436 /* ( */ 437 case 6: 438 if (andflg) { 439 o = symbol(); 440 if (o==7) 441 o = 101; else { 442 peeksym = o; 443 o = 100; 444 andflg = 0; 445 } 446 } 447 goto oponst; 448 449 /* ) */ 450 /* ] */ 451 case 5: 452 case 7: 453 if (!andflg) 454 goto syntax; 455 goto oponst; 456 457 case 39: /* . */ 458 mosflg++; 459 break; 460 461 } 462 /* binaries */ 463 if (!andflg) 464 goto syntax; 465 andflg = 0; 466 467 oponst: 468 p = (opdope[o]>>9) & 077; 469 opon1: 470 ps = *pp; 471 if (p>ps | p==ps & (opdope[o]&0200)!=0) { /* right-assoc */ 472 putin: 473 switch (o) { 474 475 case 6: /* ( */ 476 case 4: /* [ */ 477 case 100: /* call */ 478 p = 04; 479 } 480 if(op>=opst+20) { /* opstack size */ 481 error("expression overflow"); 482 exit(1); 483 } 484 *++op = o; 485 *++pp = p; 486 goto advanc; 487 } 488 --pp; 489 switch (os = *op--) { 490 491 /* EOF */ 492 case 200: 493 peeksym = o; 494 return(*--cp); 495 496 /* call */ 497 case 100: 498 if (o!=7) 499 goto syntax; 500 build(os); 501 goto advanc; 502 503 /* mcall */ 504 case 101: 505 *cp++ = block(0,0,0,0); /* 0 arg call */ 506 os = 100; 507 goto fbuild; 508 509 /* ( */ 510 case 6: 511 if (o!=7) 512 goto syntax; 513 goto advanc; 514 515 /* [ */ 516 case 4: 517 if (o!=5) 518 goto syntax; 519 build(4); 520 goto advanc; 521 } 522 fbuild: 523 build(os); 524 goto opon1; 525 526 syntax: 527 error("Expression syntax"); 528 errflush(o); 529 return(0); 530 } 531 532 scdeclare(kw) 533 { 534 extern csym, paraml, parame, peeksym; 535 int csym[], paraml[], parame[]; 536 int o; 537 538 while((o=symbol())==20) { /* name */ 539 if(*csym>0 & *csym!=kw) 540 redec(); 541 *csym = kw; 542 if(kw==8) { /* parameter */ 543 *csym = -1; 544 if (paraml==0) 545 paraml = csym; 546 else 547 *parame = csym; 548 parame = csym; 549 } 550 if ((o=symbol())!=9) /* , */ 551 break; 552 } 553 if(o==1 & kw!=8 | o==7 & kw==8) 554 return; 555 syntax: 556 decsyn(o); 557 } 558 559 tdeclare(kw, offset, mos) 560 { 561 int o, elsize, ds[]; 562 extern xdflg, peeksym, mosflg, defsym, csym; 563 int csym[], ssym[]; 564 565 if (kw == 4) { /* struct */ 566 ssym = 0; 567 ds = defsym; 568 mosflg = mos; 569 if ((o=symbol())==20) { /* name */ 570 ssym = csym; 571 o = symbol(); 572 } 573 mosflg = mos; 574 if (o != 6) { /* ( */ 575 if (ssym==0) 576 goto syntax; 577 if (*ssym!=8) /* class structname */ 578 error("Bad structure name"); 579 if (ssym[3]==0) { /* no size yet */ 580 kw = 5; /* deferred MOS */ 581 elsize = ssym; 582 } else 583 elsize = ssym[3]; 584 peeksym = o; 585 } else { 586 if (ssym) { 587 if (*ssym) 588 redec(); 589 *ssym = 8; 590 ssym[3] = 0; 591 } 592 elsize = declist(4); 593 if ((elsize&01) != 0) 594 elsize++; 595 defsym = ds; 596 if ((o = symbol()) != 7) /* ) */ 597 goto syntax; 598 if (ssym) 599 ssym[3] = elsize; 600 } 601 } 602 mosflg = mos; 603 if ((peeksym=symbol()) == 1) { /* ; */ 604 peeksym = -1; 605 mosflg = 0; 606 return(offset); 607 } 608 do { 609 offset =+ t1dec(kw, offset, mos, elsize); 610 if (xdflg & !mos) 611 return; 612 } while ((o=symbol()) == 9); /* , */ 613 if (o==1) 614 return(offset); 615 syntax: 616 decsyn(o); 617 } 618 619 t1dec(kw, offset, mos, elsize) 620 { 621 int type, nel, defsym[], t1; 622 extern defsym, mosflg; 623 624 nel = 0; 625 mosflg = mos; 626 if ((t1=getype(&nel)) < 0) 627 goto syntax; 628 type = 0; 629 do 630 type = type<<2 | (t1 & 03); 631 while(t1 =>> 2); 632 t1 = type<<3 | kw; 633 if (defsym[1] & defsym[1]!=t1) 634 redec(); 635 defsym[1] = t1; 636 defsym[3] = elsize; 637 elsize = length(defsym); 638 if (mos) { 639 if (*defsym) 640 redec(); 641 else 642 *defsym = 4; 643 if ((offset&1)!=0 & elsize!=1) 644 offset++; 645 defsym[2] = offset; 646 } else 647 if (*defsym == 0) 648 *defsym = -2; /* default auto */ 649 if (nel==0) 650 nel = 1; 651 defsym[8] = nel; 652 syntax: 653 return(nel*elsize); 654 } 655 656 getype(pnel) 657 int pnel[]; 658 { 659 int o, type; 660 extern cval, peeksym, xdflg, defsym, csym, pssiz; 661 int defsym[], csym[]; 662 663 switch(o=symbol()) { 664 665 case 42: /* * */ 666 return(getype(pnel)<<2 | 01); 667 668 case 6: /* ( */ 669 type = getype(pnel); 670 if ((o=symbol()) != 7) /* ) */ 671 goto syntax; 672 goto getf; 673 674 case 20: /* name */ 675 defsym = csym; 676 type = 0; 677 getf: 678 switch(o=symbol()) { 679 680 case 6: /* ( */ 681 if (xdflg) { 682 xdflg = 0; 683 o = defsym; 684 scdeclare(8); 685 defsym = o; 686 xdflg++; 687 } else 688 if ((o=symbol()) != 7) /* ) */ 689 goto syntax; 690 type = type<<2 | 02; 691 goto getf; 692 693 case 4: /* [ */ 694 if ((o=symbol()) != 5) { /* ] */ 695 if (o!=21) /* const */ 696 goto syntax; 697 *pnel = cval; 698 if ((o=symbol())!=5) 699 goto syntax; 700 } 701 type = type<<2 | 03; 702 goto getf; 703 } 704 peeksym = o; 705 return(type); 706 } 707 syntax: 708 decsyn(o); 709 return(-1); 710 } 711 712 decsyn(o) 713 { 714 error("Declaration syntax"); 715 errflush(o); 716 } 717 718 redec() 719 { 720 extern csym; 721 int csym[]; 722 723 error("%p redeclared", &csym[4]); 724 } 725 726 /* storage */ 727 728 regtab 0; 729 efftab 1; 730 cctab 2; 731 sptab 3; 732 symbuf[4]; 733 pssiz 9; 734 namsiz 8; 735 nwps 4; 736 hshused; 737 hshsiz 100; 738 hshlen 900; /* 9*hshsiz */ 739 hshtab[900]; 740 space; 741 cp; 742 cmsiz 40; 743 cmst[40]; 744 ctyp; 745 isn 1; 746 swsiz 120; 747 swtab[120]; 748 swp; 749 contlab; 750 brklab; 751 deflab; 752 nreg 4; 753 nauto; 754 stack; 755 peeksym 0177777; 756 peekc; 757 eof; 758 line 1; 759 defsym; 760 xdflg; 761 csym; 762 cval; 763 fcval 0; /* a double number */ 764 fc1 0; 765 fc2 0; 766 fc3 0; 767 ncpw 2; 768 nerror; 769 paraml; 770 parame; 771 tmpfil; 772 strflg; 773 ossiz 250; 774 osleft; 775 mosflg; 776 debug 0;