1: # 2: /* C compiler 3: * 4: * 5: */ 6: 7: #include "c0.h" 8: 9: /* 10: * Process a single external definition 11: */ 12: extdef() 13: { 14: register o; 15: int sclass, scflag, *cb; 16: struct hshtab typer; 17: register struct hshtab *ds; 18: 19: if(((o=symbol())==EOFC) || o==SEMI) 20: return; 21: peeksym = o; 22: sclass = 0; 23: blklev = 0; 24: if (getkeywords(&sclass, &typer)==0) { 25: sclass = EXTERN; 26: if (peeksym!=NAME) 27: goto syntax; 28: } 29: scflag = 0; 30: if (sclass==DEFXTRN) { 31: scflag++; 32: sclass = EXTERN; 33: } 34: if (sclass!=EXTERN && sclass!=STATIC && sclass!=TYPEDEF) 35: error("Illegal storage class"); 36: do { 37: defsym = 0; 38: paraml = 0; 39: parame = 0; 40: if (sclass==TYPEDEF) { 41: decl1(TYPEDEF, &typer, 0, NULL); 42: continue; 43: } 44: decl1(EXTERN, &typer, 0, NULL); 45: if ((ds=defsym)==0) 46: return; 47: funcsym = ds; 48: if ((ds->type&XTYPE)==FUNC) { 49: if ((peeksym=symbol())==LBRACE || peeksym==KEYW 50: || (peeksym==NAME && csym->hclass==TYPEDEF)) { 51: funcblk.type = decref(ds->type); 52: funcblk.strp = ds->strp; 53: setinit(ds); 54: outcode("BS", SYMDEF, sclass==EXTERN?ds->name:""); 55: cfunc(); 56: return; 57: } 58: if (paraml) 59: error("Inappropriate parameters"); 60: } else if ((o=symbol())==COMMA || o==SEMI) { 61: peeksym = o; 62: o = (length(ds)+ALIGN) & ~ALIGN; 63: if (sclass==STATIC) { 64: setinit(ds); 65: outcode("BSBBSBN", SYMDEF, "", BSS, NLABEL, ds->name, SSPACE, o); 66: } else if (scflag) 67: outcode("BSN", CSPACE, ds->name, o); 68: } else { 69: if (o!=ASSIGN) 70: peeksym = o; 71: setinit(ds); 72: if (sclass==EXTERN) 73: outcode("BS", SYMDEF, ds->name); 74: outcode("BBS", DATA, NLABEL, ds->name); 75: cb = funcbase; 76: if (cinit(ds, 1, sclass) & ALIGN) 77: outcode("B", EVEN); 78: if (maxdecl > cb) 79: cb = maxdecl; 80: funcbase = cb; 81: } 82: } while ((o=symbol())==COMMA); 83: if (o==SEMI) 84: return; 85: syntax: 86: if (o==RBRACE) { 87: error("Too many }'s"); 88: peeksym = 0; 89: return; 90: } 91: error("External definition syntax"); 92: errflush(o); 93: statement(); 94: } 95: 96: /* 97: * Process a function definition. 98: */ 99: cfunc() 100: { 101: register int *cb; 102: register sloc; 103: 104: sloc = isn; 105: isn =+ 2; 106: outcode("BBS", PROG, RLABEL, funcsym->name); 107: if (proflg) 108: outcode("BN", PROFIL, isn++); 109: cb = curbase; 110: regvar = 5; 111: autolen = STAUTO; 112: maxauto = STAUTO; 113: blklev = 1; 114: declist(ARG); 115: outcode("B", SAVE); 116: funchead(); 117: branch(sloc); 118: label(sloc+1); 119: retlab = isn++; 120: blklev = 0; 121: if ((peeksym = symbol()) != LBRACE) 122: error("Compound statement required"); 123: statement(); 124: outcode("BNB", LABEL, retlab, RETRN); 125: label(sloc); 126: outcode("BN", SETSTK, -maxauto); 127: branch(sloc+1); 128: if (cb < maxdecl) 129: cb = maxdecl; 130: curbase = funcbase = cb; 131: } 132: 133: /* 134: * Process the initializers for an external definition. 135: */ 136: cinit(anp, flex, sclass) 137: struct hshtab *anp; 138: { 139: register struct phshtab *np; 140: register nel, ninit; 141: int width, isarray, o, brace, realtype, *cb; 142: struct tnode *s; 143: 144: cb = funcbase; 145: np = gblock(sizeof(*np)); 146: funcbase = curbase; 147: cpysymb(np, anp); 148: realtype = np->type; 149: isarray = 0; 150: if ((realtype&XTYPE) == ARRAY) 151: isarray++; 152: else 153: flex = 0; 154: width = length(np); 155: nel = 1; 156: /* 157: * If it's an array, find the number of elements. 158: * temporarily modify to look like kind of thing it's 159: * an array of. 160: */ 161: if (sclass==AUTO) 162: if (isarray || realtype==STRUCT) 163: error("No auto. aggregate initialization"); 164: if (isarray) { 165: np->type = decref(realtype); 166: np->subsp++; 167: if (width==0 && flex==0) 168: error("0-length row: %.8s", anp->name); 169: o = length(np); 170: /* nel = ldiv(0, width, o); */ 171: nel = (unsigned)width/o; 172: width = o; 173: } 174: brace = 0; 175: if ((peeksym=symbol())==LBRACE && (isarray || np->type!=STRUCT)) { 176: peeksym = -1; 177: brace++; 178: } 179: ninit = 0; 180: do { 181: if ((o=symbol())==RBRACE) 182: break; 183: peeksym = o; 184: if (o==STRING && realtype==ARRAY+CHAR) { 185: if (sclass==AUTO) 186: error("No strings in automatic"); 187: peeksym = -1; 188: putstr(0, flex?10000:nel); 189: ninit =+ nchstr; 190: o = symbol(); 191: break; 192: } else if (np->type==STRUCT) { 193: strinit(np, sclass); 194: } else if ((np->type&ARRAY)==ARRAY || peeksym==LBRACE) 195: cinit(np, 0, sclass); 196: else { 197: initflg++; 198: s = tree(); 199: initflg = 0; 200: if (np->hflag&FFIELD) 201: error("No field initialization"); 202: *cp++ = nblock(np); 203: *cp++ = s; 204: build(ASSIGN); 205: if (sclass==AUTO||sclass==REG) 206: rcexpr(*--cp); 207: else if (sclass==ENUMCON) { 208: if (s->op!=CON) 209: error("Illegal enum constant for %.8s", anp->name); 210: anp->hoffset = s->value; 211: } else 212: rcexpr(block(INIT,np->type,NULL,NULL,(*--cp)->tr2)); 213: } 214: ninit++; 215: if ((ninit&077)==0 && sclass==EXTERN) 216: outcode("BS", SYMDEF, ""); 217: } while ((o=symbol())==COMMA && (ninit<nel || brace || flex)); 218: if (brace==0 || o!=RBRACE) 219: peeksym = o; 220: /* 221: * If there are too few initializers, allocate 222: * more storage. 223: * If there are too many initializers, extend 224: * the declared size for benefit of "sizeof" 225: */ 226: if (ninit<nel && sclass!=AUTO) 227: outcode("BN", SSPACE, (nel-ninit)*width); 228: else if (ninit>nel) { 229: if (flex && nel==0) { 230: np->subsp[-1] = ninit; 231: } else 232: error("Too many initializers: %.8s", anp->name); 233: nel = ninit; 234: } 235: curbase = funcbase = cb; 236: return(nel*width); 237: } 238: 239: /* 240: * Initialize a structure 241: */ 242: strinit(np, sclass) 243: struct tnode *np; 244: { 245: register struct hshtab **mlp; 246: static zerloc; 247: register int o, brace; 248: 249: if ((mlp = np->strp->memlist)==NULL) { 250: mlp = &zerloc; 251: error("Undefined structure initialization"); 252: } 253: brace = 0; 254: if ((o = symbol()) == LBRACE) 255: brace++; 256: else 257: peeksym = o; 258: do { 259: if ((o=symbol()) == RBRACE) 260: break; 261: peeksym = o; 262: if (*mlp==0) { 263: error("Too many structure initializers"); 264: cinit(&funcblk, 0, sclass); 265: } else 266: cinit(*mlp++, 0, sclass); 267: if (*mlp == &structhole) { 268: outcode("B", EVEN); 269: mlp++; 270: } 271: } while ((o=symbol())==COMMA && (*mlp || brace)); 272: if (sclass!=AUTO && sclass!=REG) { 273: if (*mlp) 274: outcode("BN", SSPACE, np->strp->ssize - (*mlp)->hoffset); 275: outcode("B", EVEN); 276: } 277: if (o!=RBRACE || brace==0) 278: peeksym = o; 279: } 280: 281: /* 282: * Mark already initialized 283: */ 284: setinit(anp) 285: struct hshtab *anp; 286: { 287: register struct hshtab *np; 288: 289: np = anp; 290: if (np->hflag&FINIT) 291: error("%s multiply defined", np->name); 292: np->hflag =| FINIT; 293: } 294: 295: /* 296: * Process one statement in a function. 297: */ 298: statement() 299: { 300: register o, o1, o2; 301: int o3; 302: struct tnode *np; 303: int sauto, sreg; 304: 305: stmt: 306: switch(o=symbol()) { 307: 308: case EOFC: 309: error("Unexpected EOF"); 310: case SEMI: 311: return; 312: 313: case LBRACE: 314: sauto = autolen; 315: sreg = regvar; 316: blockhead(); 317: while (!eof) { 318: if ((o=symbol())==RBRACE) { 319: autolen = sauto; 320: if (sreg!=regvar) 321: outcode("BN", SETREG, sreg); 322: regvar = sreg; 323: blkend(); 324: return; 325: } 326: peeksym = o; 327: statement(); 328: } 329: error("Missing '}'"); 330: return; 331: 332: case KEYW: 333: switch(cval) { 334: 335: case GOTO: 336: if (o1 = simplegoto()) 337: branch(o1); 338: else 339: dogoto(); 340: goto semi; 341: 342: case RETURN: 343: doret(); 344: goto semi; 345: 346: case IF: 347: np = pexpr(); 348: o2 = 0; 349: if ((o1=symbol())==KEYW) switch (cval) { 350: case GOTO: 351: if (o2=simplegoto()) 352: goto simpif; 353: cbranch(np, o2=isn++, 0); 354: dogoto(); 355: label(o2); 356: goto hardif; 357: 358: case RETURN: 359: if (nextchar()==';') { 360: o2 = retlab; 361: goto simpif; 362: } 363: cbranch(np, o1=isn++, 0); 364: doret(); 365: label(o1); 366: o2++; 367: goto hardif; 368: 369: case BREAK: 370: o2 = brklab; 371: goto simpif; 372: 373: case CONTIN: 374: o2 = contlab; 375: simpif: 376: chconbrk(o2); 377: cbranch(np, o2, 1); 378: hardif: 379: if ((o=symbol())!=SEMI) 380: goto syntax; 381: if ((o1=symbol())==KEYW && cval==ELSE) 382: goto stmt; 383: peeksym = o1; 384: return; 385: } 386: peeksym = o1; 387: cbranch(np, o1=isn++, 0); 388: statement(); 389: if ((o=symbol())==KEYW && cval==ELSE) { 390: o2 = isn++; 391: branch(o2); 392: label(o1); 393: statement(); 394: label(o2); 395: return; 396: } 397: peeksym = o; 398: label(o1); 399: return; 400: 401: case WHILE: 402: o1 = contlab; 403: o2 = brklab; 404: label(contlab = isn++); 405: cbranch(pexpr(), brklab=isn++, 0); 406: statement(); 407: branch(contlab); 408: label(brklab); 409: contlab = o1; 410: brklab = o2; 411: return; 412: 413: case BREAK: 414: chconbrk(brklab); 415: branch(brklab); 416: goto semi; 417: 418: case CONTIN: 419: chconbrk(contlab); 420: branch(contlab); 421: goto semi; 422: 423: case DO: 424: o1 = contlab; 425: o2 = brklab; 426: contlab = isn++; 427: brklab = isn++; 428: label(o3 = isn++); 429: statement(); 430: label(contlab); 431: contlab = o1; 432: if ((o=symbol())==KEYW && cval==WHILE) { 433: cbranch(tree(), o3, 1); 434: label(brklab); 435: brklab = o2; 436: goto semi; 437: } 438: goto syntax; 439: 440: case CASE: 441: o1 = conexp(); 442: if ((o=symbol())!=COLON) 443: goto syntax; 444: if (swp==0) { 445: error("Case not in switch"); 446: goto stmt; 447: } 448: if(swp>=swtab+SWSIZ) { 449: error("Switch table overflow"); 450: } else { 451: swp->swlab = isn; 452: (swp++)->swval = o1; 453: label(isn++); 454: } 455: goto stmt; 456: 457: case SWITCH: 458: o1 = brklab; 459: brklab = isn++; 460: np = pexpr(); 461: chkw(np, -1); 462: rcexpr(block(RFORCE,0,NULL,NULL,np)); 463: pswitch(); 464: brklab = o1; 465: return; 466: 467: case DEFAULT: 468: if (swp==0) 469: error("Default not in switch"); 470: if (deflab) 471: error("More than 1 'default'"); 472: if ((o=symbol())!=COLON) 473: goto syntax; 474: label(deflab = isn++); 475: goto stmt; 476: 477: case FOR: 478: o1 = contlab; 479: o2 = brklab; 480: contlab = isn++; 481: brklab = isn++; 482: if (o=forstmt()) 483: goto syntax; 484: label(brklab); 485: contlab = o1; 486: brklab = o2; 487: return; 488: 489: case ELSE: 490: error("Inappropriate 'else'"); 491: statement(); 492: return; 493: } 494: error("Unknown keyword"); 495: goto syntax; 496: 497: case NAME: 498: if (nextchar()==':') { 499: peekc = 0; 500: o1 = csym; 501: if (o1->hclass>0) { 502: if (o1->hblklev==0) { 503: pushdecl(o1); 504: o1->hoffset = 0; 505: } else { 506: defsym = o1; 507: redec(); 508: goto stmt; 509: } 510: } 511: o1->hclass = STATIC; 512: o1->htype = ARRAY; 513: o1->hflag =| FLABL; 514: if (o1->hoffset==0) 515: o1->hoffset = isn++; 516: label(o1->hoffset); 517: goto stmt; 518: } 519: } 520: peeksym = o; 521: rcexpr(tree()); 522: 523: semi: 524: if ((o=symbol())==SEMI) 525: return; 526: syntax: 527: error("Statement syntax"); 528: errflush(o); 529: } 530: 531: /* 532: * Process a for statement. 533: */ 534: forstmt() 535: { 536: register int l, o, sline; 537: int sline1, *ss; 538: struct tnode *st; 539: 540: if ((o=symbol()) != LPARN) 541: return(o); 542: if ((o=symbol()) != SEMI) { /* init part */ 543: peeksym = o; 544: rcexpr(tree()); 545: if ((o=symbol()) != SEMI) 546: return(o); 547: } 548: label(contlab); 549: if ((o=symbol()) != SEMI) { /* test part */ 550: peeksym = o; 551: cbranch(tree(), brklab, 0); 552: if ((o=symbol()) != SEMI) 553: return(o); 554: } 555: if ((peeksym=symbol()) == RPARN) { /* incr part */ 556: peeksym = -1; 557: statement(); 558: branch(contlab); 559: return(0); 560: } 561: l = contlab; 562: contlab = isn++; 563: st = tree(); 564: sline = line; 565: if ((o=symbol()) != RPARN) 566: return(o); 567: ss = funcbase; 568: funcbase = curbase; 569: statement(); 570: sline1 = line; 571: line = sline; 572: label(contlab); 573: rcexpr(st); 574: line = sline1; 575: if (ss < maxdecl) 576: ss = maxdecl; 577: curbase = funcbase = ss; 578: branch(l); 579: return(0); 580: } 581: 582: /* 583: * A parenthesized expression, 584: * as after "if". 585: */ 586: struct tnode * 587: pexpr() 588: { 589: register o, t; 590: 591: if ((o=symbol())!=LPARN) 592: goto syntax; 593: t = tree(); 594: if ((o=symbol())!=RPARN) 595: goto syntax; 596: return(t); 597: syntax: 598: error("Statement syntax"); 599: errflush(o); 600: return(0); 601: } 602: 603: /* 604: * The switch statement, which involves collecting the 605: * constants and labels for the cases. 606: */ 607: pswitch() 608: { 609: register struct swtab *cswp, *sswp; 610: int dl, swlab; 611: 612: cswp = sswp = swp; 613: if (swp==0) 614: cswp = swp = swtab; 615: branch(swlab=isn++); 616: dl = deflab; 617: deflab = 0; 618: statement(); 619: branch(brklab); 620: label(swlab); 621: if (deflab==0) 622: deflab = brklab; 623: outcode("BNN", SWIT, deflab, line); 624: for (; cswp < swp; cswp++) 625: outcode("NN", cswp->swlab, cswp->swval); 626: outcode("0"); 627: label(brklab); 628: deflab = dl; 629: swp = sswp; 630: } 631: 632: /* 633: * funchead is called at the start of each function 634: * to process the arguments, which have been linked in a list. 635: * This list is necessary because in 636: * f(a, b) float b; int a; ... 637: * the names are seen before the types. 638: */ 639: /* 640: * Structure resembling a block for a register variable. 641: */ 642: struct hshtab hreg { REG, 0, 0, NULL, NULL, 0 }; 643: struct tnode areg { NAME, 0, NULL, NULL, &hreg}; 644: funchead() 645: { 646: register pl; 647: register struct hshtab *cs; 648: struct tnode *bstack[2]; 649: 650: pl = STARG; 651: while(paraml) { 652: parame->hoffset = 0; 653: cs = paraml; 654: paraml = paraml->hoffset; 655: if (cs->htype==FLOAT) 656: cs->htype = DOUBLE; 657: cs->hoffset = pl; 658: if ((cs->htype&XTYPE) == ARRAY) { 659: cs->htype =- (ARRAY-PTR); /* set ptr */ 660: cs->subsp++; /* pop dims */ 661: } 662: pl =+ rlength(cs); 663: if (cs->hclass==AREG && (hreg.hoffset=goodreg(cs))>=0) { 664: bstack[0] = &areg; 665: bstack[1] = nblock(cs); 666: cp = &bstack[2]; 667: areg.type = cs->htype; 668: cs->hclass = AUTO; 669: build(ASSIGN); 670: rcexpr(bstack[0]); 671: cs->hoffset = hreg.hoffset; 672: cs->hclass = REG; 673: } else 674: cs->hclass = AUTO; 675: prste(cs); 676: } 677: for (cs=hshtab; cs<hshtab+HSHSIZ; cs++) { 678: if (cs->name[0] == '\0') 679: continue; 680: if (cs->hclass == ARG || cs->hclass==AREG) 681: error("Not an argument: %.8s", cs->name); 682: } 683: outcode("BN", SETREG, regvar); 684: } 685: 686: blockhead() 687: { 688: register r; 689: 690: r = regvar; 691: blklev++; 692: declist(0); 693: if (r != regvar) 694: outcode("BN", SETREG, regvar); 695: } 696: 697: /* 698: * After the end of a block, delete local 699: * symbols; save those that are external. 700: * Also complain about undefined labels. 701: */ 702: blkend() 703: { 704: register struct hshtab *cs, *ncs; 705: struct hshtab *endcs; 706: register i; 707: 708: blklev--; 709: for (cs=hshtab; cs->name[0] && cs<hshtab+HSHSIZ-1; ++cs) 710: ; 711: endcs = cs; 712: do if (cs->name[0]) { 713: if (cs->hblklev <= blklev) 714: continue; 715: if ((cs->hclass!=EXTERN || blklev!=0) 716: && ((cs->hflag&FLABL)==0 || blklev==0)) { 717: if (cs->hclass==0) 718: error("%.8s undefined", cs->name); 719: if ((ncs = cs->hpdown)==NULL) { 720: cs->name[0] = '\0'; 721: hshused--; 722: cs->hflag =& FKEYW; 723: } else { 724: cpysymb(cs, ncs); 725: } 726: continue; 727: } 728: /* 729: * Retained name; must rehash. 730: */ 731: for (i=0; i<NCPS; i++) 732: symbuf[i] = cs->name[i]; 733: mossym = cs->hflag&FMOS; 734: lookup(); 735: if ((ncs=csym) != cs) { 736: cs->name[0] = '\0'; 737: hshused--; 738: i = ncs->hflag; 739: cpysymb(ncs, cs); 740: ncs->hflag =| i&FKEYW; 741: cs->hflag =& FKEYW; 742: } 743: if (ncs->hblklev>1 || (ncs->hblklev>0 && ncs->hclass==EXTERN)) 744: ncs->hblklev--; 745: } while ((cs = (cs<&hshtab[HSHSIZ-1])? ++cs: hshtab) != endcs); 746: } 747: 748: /* 749: * write out special definitions of local symbols for 750: * benefit of the debugger. None of these are used 751: * by the assembler except to save them. 752: */ 753: prste(acs) 754: struct hshtab *acs; 755: { 756: register struct hshtab *cs; 757: register nkind; 758: 759: cs = acs; 760: switch (cs->hclass) { 761: case REG: 762: nkind = RNAME; 763: break; 764: 765: case AUTO: 766: nkind = ANAME; 767: break; 768: 769: case STATIC: 770: nkind = SNAME; 771: break; 772: 773: default: 774: return; 775: 776: } 777: outcode("BSN", nkind, cs->name, cs->hoffset); 778: } 779: 780: /* 781: * In case of error, skip to the next 782: * statement delimiter. 783: */ 784: errflush(ao) 785: { 786: register o; 787: 788: o = ao; 789: while(o>RBRACE) /* ; { } */ 790: o = symbol(); 791: peeksym = o; 792: }