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