# 2.11BSD#431 - /usr/src/lib/ccom/c04.c

##### Functions

    branch            X
    cbranch           X
    chconbrk          X
    decref            X
    dogoto            X
    doret             X
    hash              X
    incref            X
    label             X
    length            X
    nextchar          X
    outcode           X
    plength           X
    rcexpr            X
    rlength           X
    simplegoto        X
    spnextchar        X
    treeout           X

       1: /*
       2:  * C compiler
       3:  */
       4:
       5: #include "c0.h"
       6:
       7: /*
       8:  * Reduce the degree-of-reference by one.
       9:  * e.g. turn "ptr-to-int" into "int".
      10:  */
      11: decref(t)
      12: register int t;
      13: {
      14:     if ((t & ~TYPE) == 0) {
      15:         error("Illegal indirection");
      16:         return(t);
      17:     }
      18:     return((t>>TYLEN) & ~TYPE | t&TYPE);
      19: }
      20:
      21: /*
      22:  * Increase the degree of reference by
      23:  * one; e.g. turn "int" to "ptr-to-int".
      24:  */
      25: incref(t)
      26: register int t;
      27: {
      28:     return(((t&~TYPE)<<TYLEN) | (t&TYPE) | PTR);
      29: }
      30:
      31: /*
      32:  * Make a tree that causes a branch to lbl
      33:  * if the tree's value is non-zero together with the cond.
      34:  */
      35: cbranch(t, lbl, cond)
      36: union tree *t;
      37: {
      38:     treeout(t, 0);
      39:     outcode("BNNN", CBRANCH, lbl, cond, line);
      40: }
      41:
      42: /*
      43:  * Write out a tree.
      44:  */
      45: rcexpr(tp)
      46: register union tree *tp;
      47: {
      48:     /*
      49: 	 * Special optimization
      50: 	 */
      51:     if (tp->t.op==INIT && tp->t.tr1->t.op==CON) {
      52:         if (tp->t.type==CHAR || tp->t.type==UNCHAR) {
      53:             outcode("B1N0", BDATA, tp->t.tr1->c.value);
      54:             return;
      55:         } else if (tp->t.type==INT || tp->t.type==UNSIGN) {
      56:             outcode("BN", SINIT, tp->t.tr1->c.value);
      57:             return;
      58:         }
      59:     }
      60:     treeout(tp, 0);
      61:     outcode("BN", EXPR, line);
      62: }
      63:
      64: treeout(tp, isstruct)
      65: register union tree *tp;
      66: {
      67:     register struct nmlist *hp;
      68:     register nextisstruct;
      69:
      70:     if (tp == NULL || tp->t.op==NULLOP) {
      71:         outcode("B", XNULLOP);
      72:         return;
      73:     }
      74:     nextisstruct = tp->t.type==STRUCT;
      75:     switch(tp->t.op) {
      76:
      77:     case NAME:
      78:         hp = &tp->t.tr1->n;
      79:         if (hp->hclass==TYPEDEF)
      80:             error("Illegal use of type name");
      81:         outcode("BNN", NAME, hp->hclass==0?STATIC:hp->hclass, tp->t.type);
      82:         if (hp->hclass==EXTERN)
      83:             outcode("S", hp->name);
      84:         else
      85:             outcode("N", hp->hoffset);
      86:         break;
      87:
      88:     case LCON:
      89:         outcode("BNNN", tp->l.op, tp->l.type, (unsigned short)(tp->l.lvalue>>16),
      90:            (unsigned short)tp->l.lvalue);
      91:         break;
      92:
      93:     case CON:
      94:         outcode("BNN", tp->c.op, tp->c.type, tp->c.value);
      95:         break;
      96:
      97:     case FCON:
      98:         outcode("BNF", tp->f.op, tp->f.type, tp->f.cstr);
      99:         break;
     100:
     101:     case STRING:
     102:         outcode("BNNN", NAME, STATIC, tp->t.type, tp->t.tr1);
     103:         break;
     104:
     105:     case FSEL:
     106:         treeout(tp->t.tr1, nextisstruct);
     107:         outcode("BNNN", tp->t.op, tp->t.type,
     108:            tp->t.tr2->fld.bitoffs, tp->t.tr2->fld.flen);
     109:         break;
     110:
     111:     case ETYPE:
     112:         error("Illegal use of type");
     113:         break;
     114:
     115:     case AMPER:
     116:         treeout(tp->t.tr1, 1);
     117:         outcode("BN", tp->t.op, tp->t.type);
     118:         break;
     119:
     120:
     121:     case CALL:
     122:         treeout(tp->t.tr1, 1);
     123:         treeout(tp->t.tr2, 0);
     124:         outcode("BN", CALL, tp->t.type);
     125:         break;
     126:
     127:     default:
     128:         treeout(tp->t.tr1, nextisstruct);
     129:         if (opdope[tp->t.op]&BINARY)
     130:             treeout(tp->t.tr2, nextisstruct);
     131:         outcode("BN", tp->t.op, tp->t.type);
     132:         break;
     133:     }
     134:     if (nextisstruct && isstruct==0)
     135:         outcode("BNN", STRASG, STRUCT, tp->t.strp->S.ssize);
     136: }
     137:
     138: /*
     139:  * Generate a branch
     140:  */
     141: branch(lab)
     142: {
     143:     outcode("BN", BRANCH, lab);
     144: }
     145:
     146: /*
     147:  * Generate a label
     148:  */
     149: label(l)
     150: {
     151:     outcode("BN", LABEL, l);
     152: }
     153:
     154: /*
     155:  * ap is a tree node whose type
     156:  * is some kind of pointer; return the size of the object
     157:  * to which the pointer points.
     158:  */
     159: plength(p)
     160: register union tree *p;
     161: {
     162:     register t, l;
     163:
     164:     if (p==0 || ((t=p->t.type)&~TYPE) == 0)     /* not a reference */
     165:         return(1);
     166:     p->t.type = decref(t);
     167:     l = length(p);
     168:     p->t.type = t;
     169:     return(l);
     170: }
     171:
     172: /*
     173:  * return the number of bytes in the object
     174:  * whose tree node is acs.
     175:  */
     176: length(cs)
     177: union tree *cs;
     178: {
     179:     register t, elsz;
     180:     long n;
     181:     int nd;
     182:
     183:     t = cs->t.type;
     184:     n = 1;
     185:     nd = 0;
     186:     while ((t&XTYPE) == ARRAY) {
     187:         t = decref(t);
     188:         n *= cs->t.subsp[nd++];
     189:     }
     190:     if ((t&~TYPE)==FUNC)
     191:         return(0);
     192:     if (t>=PTR)
     193:         elsz = SZPTR;
     194:     else switch(t&TYPE) {
     195:
     196:     case VOID:
     197:         error("Illegal use of void object");
     198:         return(2);
     199:
     200:     case INT:
     201:     case UNSIGN:
     202:         elsz = SZINT;
     203:         break;
     204:
     205:     case CHAR:
     206:     case UNCHAR:
     207:         elsz = 1;
     208:         break;
     209:
     210:     case FLOAT:
     211:         elsz = SZFLOAT;
     212:         break;
     213:
     214:     case UNLONG:
     215:     case LONG:
     216:         elsz = SZLONG;
     217:         break;
     218:
     219:     case DOUBLE:
     220:         elsz = SZDOUB;
     221:         break;
     222:
     223:     case STRUCT:
     224:         if ((elsz = cs->t.strp->S.ssize) == 0)
     225:             error("Undefined structure");
     226:         break;
     227:     default:
     228:         error("Compiler error (length)");
     229:         return(0);
     230:     }
     231:     n *= elsz;
     232:     if (n >= (unsigned)50000)
     233:         werror("very large data structure");
     234:     return(n);
     235: }
     236:
     237: /*
     238:  * The number of bytes in an object, rounded up to a word.
     239:  */
     240: rlength(cs)
     241: union tree *cs;
     242: {
     243:     return((length(cs)+ALIGN) & ~ALIGN);
     244: }
     245:
     246: /*
     247:  * After an "if (...) goto", look to see if the transfer
     248:  * is to a simple label.
     249:  */
     250: simplegoto()
     251: {
     252:     register struct nmlist *csp;
     253:
     254:     if ((peeksym=symbol())==NAME && nextchar()==';') {
     255:         csp = csym;
     256:         if (csp->hblklev == 0)
     257:             csp = pushdecl(csp);
     258:         if (csp->hclass==0 && csp->htype==0) {
     259:             csp->htype = ARRAY;
     260:             csp->hflag |= FLABL;
     261:             if (csp->hoffset==0)
     262:                 csp->hoffset = isn++;
     263:         }
     264:         if ((csp->hclass==0||csp->hclass==STATIC)
     265:          &&  csp->htype==ARRAY) {
     266:             peeksym = -1;
     267:             return(csp->hoffset);
     268:         }
     269:     }
     270:     return(0);
     271: }
     272:
     273: /*
     274:  * Return the next non-white-space character
     275:  */
     276: nextchar()
     277: {
     278:     while (spnextchar()==' ')
     279:         peekc = 0;
     280:     return(peekc);
     281: }
     282:
     283: /*
     284:  * Return the next character, translating all white space
     285:  * to blank and handling line-ends.
     286:  */
     287: spnextchar()
     288: {
     289:     register c;
     290:
     291:     if ((c = peekc)==0)
     292:         c = getchar();
     293:     if (c=='\t' || c=='\014')   /* FF */
     294:         c = ' ';
     295:     else if (c=='\n') {
     296:         c = ' ';
     297:         line++;
     298:     }
     299:     peekc = c;
     300:     return(c);
     301: }
     302:
     303: /*
     304:  * is a break or continue legal?
     305:  */
     306: chconbrk(l)
     307: {
     308:     if (l==0)
     309:         error("Break/continue error");
     310: }
     311:
     312: /*
     313:  * The goto statement.
     314:  */
     315: dogoto()
     316: {
     317:     register union tree *np;
     318:     register char *st;
     319:
     320:     st = starttree();
     321:     *cp++ = tree(0);
     322:     build(STAR);
     323:     chkw(np = *--cp, -1);
     324:     rcexpr(block(JUMP, 0, (int *)NULL, (union str *)NULL, np, TNULL));
     325:     endtree(st);
     326: }
     327:
     328: /*
     329:  * The return statement, which has to convert
     330:  * the returned object to the function's type.
     331:  */
     332: doret()
     333: {
     334:     if (nextchar() != ';') {
     335:         register char *st;
     336:
     337:         st = starttree();
     338:         *cp++ = (union tree *)&funcblk;
     339:         *cp++ = tree(0);
     340:         build(ASSIGN);
     341:         cp[-1] = cp[-1]->t.tr2;
     342:         build(RFORCE);
     343:         rcexpr(*--cp);
     344:         endtree(st);
     345:     }
     346:     branch(retlab);
     347: }
     348:
     349: /*
     350:  * Write a character on the error output.
     351:  */
     352: /*
     353:  * Coded output:
     354:  *   B: beginning of line; an operator
     355:  *   N: a number
     356:  *   S: a symbol (external)
     357:  *   1: number 1
     358:  *   0: number 0
     359:  */
     360: /* VARARGS1 */
     361: outcode(s, a)
     362: char *s;
     363: {
     364:     register *ap;
     365:     register FILE *bufp;
     366:     register char *np;
     367:     int n;
     368:
     369:     bufp = stdout;
     370:     if (strflg)
     371:         bufp = sbufp;
     372:     ap = &a;
     373:     for (;;) switch(*s++) {
     374:     case 'B':
     375:         fputc(*ap++, bufp);
     376:         fputc(0376, bufp);
     377:         continue;
     378:
     379:     case 'N':
     380:         fputc(*ap, bufp);
     381:         fputc(*ap++>>8, bufp);
     382:         continue;
     383:
     384:     case 'F':
     385:         np = (char *)*ap++;
     386:         n = 1000;
     387:         goto str;
     388:
     389:     case 'S':
     390:         np = (char *)*ap++;
     391:         n = MAXCPS-1;
     392:         if (*np)
     393:             fputc('_', bufp);
     394:     str:
     395:         while(n-- && *np) {
     396:             fputc(*np++ & 0177, bufp);
     397:         }
     398:         fputc(0, bufp);
     399:         continue;
     400:
     401:     case '1':
     402:         fputc(1, bufp);
     403:         fputc(0, bufp);
     404:         continue;
     405:
     406:     case '0':
     407:         fputc(0, bufp);
     408:         fputc(0, bufp);
     409:         continue;
     410:
     411:     case '\0':
     412:         if (ferror(bufp)) {
     413:             error("Write error on temp");
     414:             exit(1);
     415:         }
     416:         return;
     417:
     418:     default:
     419:         error("Botch in outcode");
     420:     }
     421: }
     422:
     423: unsigned int
     424: hash(sp)
     425: register char *sp;
     426: {
     427:     register unsigned int h;
     428:
     429:     h = 0;
     430:     for (; *sp; sp++) {
     431:         h += h;
     432:         h += *sp;
     433:     }
     434:     return(h%HSHSIZ);
     435: }

#### Defined functions

branch defined in line 141; used 17 times

- in line 346
- in /usr/src/lib/ccom/c02.c line 113, 124, 334, 407, 425, 434-439(2), 581-583(2), 609-613(3), 654-658(2)
- in /usr/src/lib/ccom/c10.c line 487, 500

cbranch defined in line 35; used 9 times

- in /usr/src/lib/ccom/c02.c line 369, 379, 393, 403, 423, 453, 606
- in /usr/src/lib/ccom/c10.c line 485, 496

chconbrk defined in line 306; used 3 times

- in /usr/src/lib/ccom/c02.c line 392, 433-438(2)

decref defined in line 11; used 11 times

- in line 166, 187
- in /usr/src/lib/ccom/c01.c line 116, 138, 144, 446, 488
- in /usr/src/lib/ccom/c02.c line 49, 157
- in /usr/src/lib/ccom/c03.c line 682
- in /usr/src/lib/ccom/c10.c line 1123

dogoto defined in line 315; used 2 times

- in /usr/src/lib/ccom/c02.c line 336, 370

doret defined in line 332; used 2 times

- in /usr/src/lib/ccom/c02.c line 340, 380

hash defined in line 423; used 4 times

- in /usr/src/lib/ccom/c0.h line 486
- in /usr/src/lib/ccom/c00.c line 114, 138
- in /usr/src/lib/ccom/c03.c line 553

incref defined in line 25; used 7 times

- in /usr/src/lib/ccom/c01.c line 149, 160, 183, 448, 465, 917
- in /usr/src/lib/ccom/c10.c line 1125

label defined in line 149; used 26 times

- in /usr/src/lib/ccom/c02.c line 114, 121, 371, 381, 408-414(3), 422-426(2), 448-454(3), 474, 501, 545, 582-584(2), 604, 611-614(2), 659, 666
- in /usr/src/lib/ccom/c10.c line 488-490(2), 501-505(2)

length defined in line 176; used 8 times

- in line 167, 243
- in /usr/src/lib/ccom/c01.c line 40
- in /usr/src/lib/ccom/c02.c line 60, 146, 161
- in /usr/src/lib/ccom/c03.c line 257, 445

nextchar defined in line 276; used 6 times

- in line 254, 334
- in /usr/src/lib/ccom/c00.c line 617
- in /usr/src/lib/ccom/c02.c line 375, 527
- in /usr/src/lib/ccom/c03.c line 586

outcode defined in line 361; used 55 times

- in line 39, 53-61(3), 71, 81-107(8), 117, 124, 131-135(2), 143, 151
- in /usr/src/lib/ccom/c00.c line 120-122(2), 457-473(6)
- in /usr/src/lib/ccom/c02.c line 52, 63-65(2), 73-76(3), 102, 109-111(2), 120-123(2), 211, 222, 263, 275-276(2), 318, 355, 662-665(3), 724, 735, 804
- in /usr/src/lib/ccom/c03.c line 504-510(4)

plength defined in line 159; used 3 times

- in /usr/src/lib/ccom/c01.c line 336-337(2), 363

rcexpr defined in line 45; used 19 times

- in line 324, 343
- in /usr/src/lib/ccom/c02.c line 199, 205, 487, 551, 575, 597, 710
- in /usr/src/lib/ccom/c11.c line 599, 634, 700, 984-990(3), 1140, 1156, 1178, 1193

rlength defined in line 240; used 4 times

- in /usr/src/lib/ccom/c01.c line 948
- in /usr/src/lib/ccom/c02.c line 701
- in /usr/src/lib/ccom/c03.c line 488, 509

simplegoto defined in line 250; used 2 times

- in /usr/src/lib/ccom/c02.c line 333, 367

spnextchar defined in line 287; used 5 times

- in line 278
- in /usr/src/lib/ccom/c00.c line 287-290(2), 363, 438

treeout defined in line 64; used 8 times

- in line 38, 60, 106, 116, 122-130(4)

Last modified: 1993-07-04 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1331 |