1: #
   2: /* C compiler
   3:  *
   4:  *
   5:  */
   6: 
   7: #include "c0h.c"
   8: 
   9: /*
  10:  * Process a single external definition
  11:  */
  12: extdef()
  13: {
  14:     register o, elsize;
  15:     int type, sclass;
  16:     register struct hshtab *ds;
  17: 
  18:     if(((o=symbol())==EOF) || o==SEMI)
  19:         return;
  20:     peeksym = o;
  21:     type = INT;
  22:     sclass = EXTERN;
  23:     xdflg = FNDEL;
  24:     if ((elsize = getkeywords(&sclass, &type)) == -1 && peeksym!=NAME)
  25:         goto syntax;
  26:     if (type==STRUCT)
  27:         blkhed();
  28:     do {
  29:         defsym = 0;
  30:         decl1(EXTERN, type, 0, elsize);
  31:         if ((ds=defsym)==0)
  32:             return;
  33:         funcsym = ds;
  34:         ds->hflag =| FNDEL;
  35:         outcode("BS", SYMDEF, ds->name);
  36:         xdflg = 0;
  37:         if ((ds->type&XTYPE)==FUNC) {
  38:             if ((peeksym=symbol())==LBRACE || peeksym==KEYW) {
  39:                 funcblk.type = decref(ds->type);
  40:                 cfunc(ds->name);
  41:                 return;
  42:             }
  43:         } else
  44:             cinit(ds);
  45:     } while ((o=symbol())==COMMA);
  46:     if (o==SEMI)
  47:         return;
  48: syntax:
  49:     if (o==RBRACE) {
  50:         error("Too many }'s");
  51:         peeksym = 0;
  52:         return;
  53:     }
  54:     error("External definition syntax");
  55:     errflush(o);
  56:     statement(0);
  57: }
  58: 
  59: /*
  60:  * Process a function definition.
  61:  */
  62: cfunc(cs)
  63: char *cs;
  64: {
  65:     register savdimp;
  66: 
  67:     savdimp = dimp;
  68:     outcode("BBS", PROG, RLABEL, cs);
  69:     declist(ARG);
  70:     regvar = 5;
  71:     retlab = isn++;
  72:     if ((peeksym = symbol()) != LBRACE)
  73:         error("Compound statement required");
  74:     statement(1);
  75:     outcode("BNB", LABEL, retlab, RETRN);
  76:     dimp = savdimp;
  77: }
  78: 
  79: /*
  80:  * Process the initializers for an external definition.
  81:  */
  82: cinit(ds)
  83: struct hshtab *ds;
  84: {
  85:     register basetype, nel, ninit;
  86:     int o, width, realwidth;
  87: 
  88:     nel = 1;
  89:     basetype = ds->type;
  90:     /*
  91: 	 * If it's an array, find the number of elements.
  92: 	 * "basetype" is the type of thing it's an array of.
  93: 	 */
  94:     while ((basetype&XTYPE)==ARRAY) {
  95:         if ((nel = dimtab[ds->ssp&0377])==0)
  96:             nel = 1;
  97:         basetype = decref(basetype);
  98:     }
  99:     realwidth = width = length(ds) / nel;
 100:     /*
 101: 	 * Pretend a structure is kind of an array of integers.
 102: 	 * This is a kludge.
 103: 	 */
 104:     if (basetype==STRUCT) {
 105:         nel =* realwidth/2;
 106:         width = 2;
 107:     }
 108:     if ((peeksym=symbol())==COMMA || peeksym==SEMI) {
 109:         outcode("BSN",CSPACE,ds->name,(nel*width+ALIGN)&~ALIGN);
 110:         return;
 111:     }
 112:     ninit = 0;
 113:     outcode("BBS", DATA, NLABEL, ds->name);
 114:     if ((o=symbol())==LBRACE) {
 115:         do
 116:             ninit = cinit1(ds, basetype, width, ninit, nel);
 117:         while ((o=symbol())==COMMA);
 118:         if (o!=RBRACE)
 119:             peeksym = o;
 120:     } else {
 121:         peeksym = o;
 122:         ninit = cinit1(ds, basetype, width, 0, nel);
 123:     }
 124:     /*
 125: 	 * Above we pretended that a structure was a bunch of integers.
 126: 	 * Readjust in accordance with reality.
 127: 	 * First round up partial initializations.
 128: 	 */
 129:     if (basetype==STRUCT) {
 130:         if (o = 2*ninit % realwidth)
 131:             outcode("BN", SSPACE, realwidth-o);
 132:         ninit = (2*ninit+realwidth-2) / realwidth;
 133:         nel =/ realwidth/2;
 134:     }
 135:     /*
 136: 	 * If there are too few initializers, allocate
 137: 	 * more storage.
 138: 	 * If there are too many initializers, extend
 139: 	 * the declared size for benefit of "sizeof"
 140: 	 */
 141:     if (ninit<nel)
 142:         outcode("BN", SSPACE, (nel-ninit)*realwidth);
 143:     else if (ninit>nel) {
 144:         if ((ds->type&XTYPE)==ARRAY)
 145:             dimtab[ds->ssp&0377] = ninit;
 146:         nel = ninit;
 147:     }
 148:     /*
 149: 	 * If it's not an array, only one initializer is allowed.
 150: 	 */
 151:     if (ninit>1 && (ds->type&XTYPE)!=ARRAY)
 152:         error("Too many initializers");
 153:     if (((nel&width)&ALIGN))
 154:         outcode("B", EVEN);
 155: }
 156: 
 157: /*
 158:  * Process a single expression in a sequence of initializers
 159:  * for an external. Mainly, it's for checking
 160:  * type compatibility.
 161:  */
 162: cinit1(ds, type, awidth, aninit, nel)
 163: struct hshtab *ds;
 164: {
 165:     float sf;
 166:     register struct tnode *s;
 167:     register width, ninit;
 168: 
 169:     width = awidth;
 170:     ninit = aninit;
 171:     if ((peeksym=symbol())==STRING && type==CHAR) {
 172:         peeksym = -1;
 173:         if (ninit)
 174:             bxdec();
 175:         putstr(0);
 176:         if (nel>nchstr) {
 177:             strflg++;
 178:             outcode("BN", SSPACE, nel-nchstr);
 179:             strflg = 0;
 180:             nchstr = nel;
 181:         }
 182:         return(nchstr);
 183:     }
 184:     if (peeksym==RBRACE)
 185:         return(ninit);
 186:     initflg++;
 187:     s = tree();
 188:     initflg = 0;
 189:     switch(width) {
 190: 
 191:     case 1:
 192:         if (s->op != CON)
 193:             goto bad;
 194:         outcode("B1N0", BDATA, s->value);
 195:         break;
 196: 
 197:     case 2:
 198:         if (s->op==CON) {
 199:             outcode("B1N0", WDATA, s->value);
 200:             break;
 201:         }
 202:         if (s->op==FCON || s->op==SFCON) {
 203:             if (type==STRUCT) {
 204:                 ninit =+ 3;
 205:                 goto prflt;
 206:             }
 207:             goto bad;
 208:         }
 209:         rcexpr(block(1,INIT,0,0,s));
 210:         break;
 211: 
 212:     case 4:
 213:         sf = fcval;
 214:         outcode("B1N1N0", WDATA, sf);
 215:         goto flt;
 216: 
 217:     case 8:
 218:     prflt:
 219:         outcode("B1N1N1N1N0", WDATA, fcval);
 220:     flt:
 221:         if (s->op==FCON || s->op==SFCON)
 222:             break;
 223: 
 224:     default:
 225:     bad:
 226:         bxdec();
 227: 
 228:     }
 229:     return(++ninit);
 230: }
 231: 
 232: bxdec()
 233: {
 234:     error("Inconsistent external initialization");
 235: }
 236: 
 237: /*
 238:  * Process one statement in a function.
 239:  */
 240: statement(d)
 241: {
 242:     register o, o1, o2;
 243:     int o3, o4;
 244:     struct tnode *np;
 245: 
 246: stmt:
 247:     switch(o=symbol()) {
 248: 
 249:     case EOF:
 250:         error("Unexpected EOF");
 251:     case SEMI:
 252:         return;
 253: 
 254:     case LBRACE:
 255:         if (d) {
 256:             if (proflg)
 257:                 outcode("BN", PROFIL, isn++);
 258:             outcode("BN", SAVE, blkhed());
 259:         }
 260:         while (!eof) {
 261:             if ((o=symbol())==RBRACE)
 262:                 return;
 263:             peeksym = o;
 264:             statement(0);
 265:         }
 266:         error("Missing '}'");
 267:         return;
 268: 
 269:     case KEYW:
 270:         switch(cval) {
 271: 
 272:         case GOTO:
 273:             if (o1 = simplegoto())
 274:                 branch(o1);
 275:             else
 276:                 dogoto();
 277:             goto semi;
 278: 
 279:         case RETURN:
 280:             doret();
 281:             goto semi;
 282: 
 283:         case IF:
 284:             np = pexpr();
 285:             o2 = 0;
 286:             if ((o1=symbol())==KEYW) switch (cval) {
 287:             case GOTO:
 288:                 if (o2=simplegoto())
 289:                     goto simpif;
 290:                 cbranch(np, o2=isn++, 0);
 291:                 dogoto();
 292:                 label(o2);
 293:                 goto hardif;
 294: 
 295:             case RETURN:
 296:                 if (nextchar()==';') {
 297:                     o2 = retlab;
 298:                     goto simpif;
 299:                 }
 300:                 cbranch(np, o1=isn++, 0);
 301:                 doret();
 302:                 label(o1);
 303:                 o2++;
 304:                 goto hardif;
 305: 
 306:             case BREAK:
 307:                 o2 = brklab;
 308:                 goto simpif;
 309: 
 310:             case CONTIN:
 311:                 o2 = contlab;
 312:             simpif:
 313:                 chconbrk(o2);
 314:                 cbranch(np, o2, 1);
 315:             hardif:
 316:                 if ((o=symbol())!=SEMI)
 317:                     goto syntax;
 318:                 if ((o1=symbol())==KEYW && cval==ELSE)
 319:                     goto stmt;
 320:                 peeksym = o1;
 321:                 return;
 322:             }
 323:             peeksym = o1;
 324:             cbranch(np, o1=isn++, 0);
 325:             statement(0);
 326:             if ((o=symbol())==KEYW && cval==ELSE) {
 327:                 o2 = isn++;
 328:                 branch(o2);
 329:                 label(o1);
 330:                 statement(0);
 331:                 label(o2);
 332:                 return;
 333:             }
 334:             peeksym = o;
 335:             label(o1);
 336:             return;
 337: 
 338:         case WHILE:
 339:             o1 = contlab;
 340:             o2 = brklab;
 341:             label(contlab = isn++);
 342:             cbranch(pexpr(), brklab=isn++, 0);
 343:             statement(0);
 344:             branch(contlab);
 345:             label(brklab);
 346:             contlab = o1;
 347:             brklab = o2;
 348:             return;
 349: 
 350:         case BREAK:
 351:             chconbrk(brklab);
 352:             branch(brklab);
 353:             goto semi;
 354: 
 355:         case CONTIN:
 356:             chconbrk(contlab);
 357:             branch(contlab);
 358:             goto semi;
 359: 
 360:         case DO:
 361:             o1 = contlab;
 362:             o2 = brklab;
 363:             contlab = isn++;
 364:             brklab = isn++;
 365:             label(o3 = isn++);
 366:             statement(0);
 367:             label(contlab);
 368:             contlab = o1;
 369:             if ((o=symbol())==KEYW && cval==WHILE) {
 370:                 cbranch(tree(), o3, 1);
 371:                 label(brklab);
 372:                 brklab = o2;
 373:                 goto semi;
 374:             }
 375:             goto syntax;
 376: 
 377:         case CASE:
 378:             o1 = conexp();
 379:             if ((o=symbol())!=COLON)
 380:                 goto syntax;
 381:             if (swp==0) {
 382:                 error("Case not in switch");
 383:                 goto stmt;
 384:             }
 385:             if(swp>=swtab+swsiz) {
 386:                 error("Switch table overflow");
 387:             } else {
 388:                 swp->swlab = isn;
 389:                 (swp++)->swval = o1;
 390:                 label(isn++);
 391:             }
 392:             goto stmt;
 393: 
 394:         case SWITCH:
 395:             o1 = brklab;
 396:             brklab = isn++;
 397:             np = pexpr();
 398:             chkw(np, -1);
 399:             rcexpr(block(1,RFORCE,0,0,np));
 400:             pswitch();
 401:             brklab = o1;
 402:             return;
 403: 
 404:         case DEFAULT:
 405:             if (swp==0)
 406:                 error("Default not in switch");
 407:             if ((o=symbol())!=COLON)
 408:                 goto syntax;
 409:             label(deflab = isn++);
 410:             goto stmt;
 411: 
 412:         case FOR:
 413:             o1 = contlab;
 414:             o2 = brklab;
 415:             contlab = isn++;
 416:             brklab = isn++;
 417:             if (o=forstmt())
 418:                 goto syntax;
 419:             label(brklab);
 420:             contlab = o1;
 421:             brklab = o2;
 422:             return;
 423:         }
 424: 
 425:         error("Unknown keyword");
 426:         goto syntax;
 427: 
 428:     case NAME:
 429:         if (nextchar()==':') {
 430:             peekc = 0;
 431:             o1 = csym;
 432:             if (o1->hclass>0) {
 433:                 error("Redefinition");
 434:                 goto stmt;
 435:             }
 436:             o1->hclass = STATIC;
 437:             o1->htype = ARRAY;
 438:             if (o1->hoffset==0)
 439:                 o1->hoffset = isn++;
 440:             label(o1->hoffset);
 441:             goto stmt;
 442:         }
 443:     }
 444:     peeksym = o;
 445:     rcexpr(tree());
 446: 
 447: semi:
 448:     if ((o=symbol())==SEMI)
 449:         return;
 450: syntax:
 451:     error("Statement syntax");
 452:     errflush(o);
 453: }
 454: 
 455: /*
 456:  * Process a for statement.
 457:  */
 458: forstmt()
 459: {
 460:     register int l, o, sline;
 461:     int sline1, *ss;
 462:     struct tnode *st;
 463: 
 464:     if ((o=symbol()) != LPARN)
 465:         return(o);
 466:     if ((o=symbol()) != SEMI) {     /* init part */
 467:         peeksym = o;
 468:         rcexpr(tree());
 469:         if ((o=symbol()) != SEMI)
 470:             return(o);
 471:     }
 472:     label(contlab);
 473:     if ((o=symbol()) != SEMI) {     /* test part */
 474:         peeksym = o;
 475:         rcexpr(block(1,CBRANCH,tree(),brklab,0));
 476:         if ((o=symbol()) != SEMI)
 477:             return(o);
 478:     }
 479:     if ((peeksym=symbol()) == RPARN) {  /* incr part */
 480:         peeksym = -1;
 481:         statement(0);
 482:         branch(contlab);
 483:         return(0);
 484:     }
 485:     l = contlab;
 486:     contlab = isn++;
 487:     st = tree();
 488:     sline = line;
 489:     if ((o=symbol()) != RPARN)
 490:         return(o);
 491:     ss = treespace;
 492:     treespace = space;
 493:     statement(0);
 494:     sline1 = line;
 495:     line = sline;
 496:     label(contlab);
 497:     rcexpr(st);
 498:     line = sline1;
 499:     treespace = ss;
 500:     branch(l);
 501:     return(0);
 502: }
 503: 
 504: /*
 505:  * A parenthesized expression,
 506:  * as after "if".
 507:  */
 508: pexpr()
 509: {
 510:     register o, t;
 511: 
 512:     if ((o=symbol())!=LPARN)
 513:         goto syntax;
 514:     t = tree();
 515:     if ((o=symbol())!=RPARN)
 516:         goto syntax;
 517:     return(t);
 518: syntax:
 519:     error("Statement syntax");
 520:     errflush(o);
 521:     return(0);
 522: }
 523: 
 524: /*
 525:  * The switch stateent, which involves collecting the
 526:  * constants and labels for the cases.
 527:  */
 528: pswitch()
 529: {
 530:     register struct swtab *cswp, *sswp;
 531:     int dl, swlab;
 532: 
 533:     cswp = sswp = swp;
 534:     if (swp==0)
 535:         cswp = swp = swtab;
 536:     branch(swlab=isn++);
 537:     dl = deflab;
 538:     deflab = 0;
 539:     statement(0);
 540:     branch(brklab);
 541:     label(swlab);
 542:     if (deflab==0)
 543:         deflab = brklab;
 544:     outcode("BNN", SWIT, deflab, line);
 545:     for (; cswp < swp; cswp++)
 546:         outcode("NN", cswp->swlab, cswp->swval);
 547:     outcode("0");
 548:     label(brklab);
 549:     deflab = dl;
 550:     swp = sswp;
 551: }
 552: 
 553: /*
 554:  * blkhed is called at the start of each function.
 555:  * It reads the declarations at the start;
 556:  * then assigns storage locations for the
 557:  * parameters (which have been linked into a list,
 558:  * in order of appearance).
 559:  * This list is necessary because in
 560:  * f(a, b) float b; int a; ...
 561:  * the names are seen before the types.
 562:  * Also, the routine adjusts structures involved
 563:  * in some kind of forward-referencing.
 564:  */
 565: blkhed()
 566: {
 567:     register pl;
 568:     register struct hshtab *cs;
 569: 
 570:     autolen = 6;
 571:     declist(0);
 572:     pl = 4;
 573:     while(paraml) {
 574:         parame->hoffset = 0;
 575:         cs = paraml;
 576:         paraml = paraml->hoffset;
 577:         if (cs->htype==FLOAT)
 578:             cs->htype = DOUBLE;
 579:         cs->hoffset = pl;
 580:         cs->hclass = AUTO;
 581:         if ((cs->htype&XTYPE) == ARRAY) {
 582:             cs->htype =- (ARRAY-PTR);   /* set ptr */
 583:             cs->ssp++;      /* pop dims */
 584:         }
 585:         pl =+ rlength(cs);
 586:     }
 587:     for (cs=hshtab; cs<hshtab+hshsiz; cs++) {
 588:         if (cs->name[0] == '\0')
 589:             continue;
 590:         /* check tagged structure */
 591:         if (cs->hclass>KEYWC && (cs->htype&TYPE)==RSTRUCT) {
 592:             cs->lenp = dimtab[cs->lenp&0377]->lenp;
 593:             cs->htype = cs->htype&~TYPE | STRUCT;
 594:         }
 595:         if (cs->hclass == STRTAG && dimtab[cs->lenp&0377]==0)
 596:             error("Undefined structure: %.8s", cs->name);
 597:         if (cs->hclass == ARG)
 598:             error("Not an argument: %.8s", cs->name);
 599:         if (stflg)
 600:             prste(cs);
 601:     }
 602:     space = treespace;
 603:     outcode("BN", SETREG, regvar);
 604:     return(autolen);
 605: }
 606: 
 607: /*
 608:  * After a function definition, delete local
 609:  * symbols.
 610:  * Also complain about undefineds.
 611:  */
 612: blkend() {
 613:     register struct hshtab *cs;
 614: 
 615:     for (cs=hshtab; cs<hshtab+hshsiz; cs++) {
 616:         if (cs->name[0]) {
 617:             if (cs->hclass==0 && (cs->hflag&FNUND)==0) {
 618:                 error("%.8s undefined", cs->name);
 619:                 cs->hflag =| FNUND;
 620:             }
 621:             if((cs->hflag&FNDEL)==0) {
 622:                 cs->name[0] = '\0';
 623:                 hshused--;
 624:                 cs->hflag =& ~(FNUND|FFIELD);
 625:             }
 626:         }
 627:     }
 628: }
 629: 
 630: /*
 631:  * write out special definitions of local symbols for
 632:  * benefit of the debugger.  None of these are used
 633:  * by the assembler except to save them.
 634:  */
 635: prste(acs)
 636: {
 637:     register struct hshtab *cs;
 638:     register nkind;
 639: 
 640:     cs = acs;
 641:     switch (cs->hclass) {
 642:     case REG:
 643:         nkind = RNAME;
 644:         break;
 645: 
 646:     case AUTO:
 647:         nkind = ANAME;
 648:         break;
 649: 
 650:     case STATIC:
 651:         nkind = SNAME;
 652:         break;
 653: 
 654:     default:
 655:         return;
 656: 
 657:     }
 658:     outcode("BSN", nkind, cs->name, cs->hoffset);
 659: }
 660: 
 661: /*
 662:  * In case of error, skip to the next
 663:  * statement delimiter.
 664:  */
 665: errflush(ao)
 666: {
 667:     register o;
 668: 
 669:     o = ao;
 670:     while(o>RBRACE) /* ; { } */
 671:         o = symbol();
 672:     peeksym  = o;
 673: }

Defined functions

blkend defined in line 612; used 1 times
blkhed defined in line 565; used 2 times
bxdec defined in line 232; used 2 times
cfunc defined in line 62; used 1 times
  • in line 40
cinit defined in line 82; used 1 times
  • in line 44
cinit1 defined in line 162; used 2 times
errflush defined in line 665; used 5 times
extdef defined in line 12; used 1 times
forstmt defined in line 458; used 1 times
pexpr defined in line 508; used 3 times
prste defined in line 635; used 1 times
pswitch defined in line 528; used 1 times
statement defined in line 240; used 10 times
Last modified: 1975-07-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1467
Valid CSS Valid XHTML 1.0 Strict