1: #
   2: /*
   3:  * C compiler
   4:  *
   5:  *
   6:  */
   7: 
   8: #include "c0h.c"
   9: 
  10: /*
  11:  * Reduce the degree-of-reference by one.
  12:  * e.g. turn "ptr-to-int" into "int".
  13:  */
  14: decref(at)
  15: {
  16:     register t;
  17: 
  18:     t = at;
  19:     if ((t & ~TYPE) == 0) {
  20:         error("Illegal indirection");
  21:         return(t);
  22:     }
  23:     return((t>>TYLEN) & ~TYPE | t&TYPE);
  24: }
  25: 
  26: /*
  27:  * Increase the degree of reference by
  28:  * one; e.g. turn "int" to "ptr-to-int".
  29:  */
  30: incref(t)
  31: {
  32:     return(((t&~TYPE)<<TYLEN) | (t&TYPE) | PTR);
  33: }
  34: 
  35: /*
  36:  * Make a tree that causes a branch to lbl
  37:  * if the tree's value is non-zero together with the cond.
  38:  */
  39: cbranch(tree, lbl, cond)
  40: struct tnode *tree;
  41: {
  42:     rcexpr(block(1,CBRANCH,tree,lbl,cond));
  43: }
  44: 
  45: /*
  46:  * Write out a tree.
  47:  */
  48: rcexpr(tree)
  49: struct tnode *tree;
  50: {
  51: 
  52:     treeout(tree);
  53:     outcode("BN", EXPR, line);
  54: }
  55: 
  56: treeout(atree)
  57: struct tnode *atree;
  58: {
  59:     register struct tnode *tree;
  60: 
  61:     if ((tree = atree) == 0)
  62:         return;
  63:     switch(tree->op) {
  64: 
  65:     case 0:
  66:         outcode("B", NULL);
  67:         return;
  68: 
  69:     case NAME:
  70:         outcode("BNN", NAME, tree->class, tree->type);
  71:         if (tree->class==EXTERN)
  72:             outcode("S", tree->nname);
  73:         else
  74:             outcode("N", tree->nloc);
  75:         return;
  76: 
  77:     case CON:
  78:     case FCON:
  79:     case SFCON:
  80:         outcode("BNN", tree->op, tree->type, tree->value);
  81:         return;
  82: 
  83:     case FSEL:
  84:         treeout(tree->tr1);
  85:         outcode("BNN", tree->op, tree->type, tree->tr2);
  86:         return;
  87: 
  88:     case CBRANCH:
  89:         treeout(tree->btree);
  90:         outcode("BNN", tree->op, tree->lbl, tree->cond);
  91:         return;
  92: 
  93:     default:
  94:         treeout(tree->tr1);
  95:         if (opdope[tree->op]&BINARY)
  96:             treeout(tree->tr2);
  97:         outcode("BN", tree->op, tree->type);
  98:         return;
  99:     }
 100: }
 101: 
 102: /*
 103:  * Generate a branch
 104:  */
 105: branch(lab) {
 106:     outcode("BN", BRANCH, lab);
 107: }
 108: 
 109: /*
 110:  * Generate a label
 111:  */
 112: label(l) {
 113:     outcode("BN", LABEL, l);
 114: }
 115: 
 116: /*
 117:  * ap is a tree node whose type
 118:  * is some kind of pointer; return the size of the object
 119:  * to which the pointer points.
 120:  */
 121: plength(ap)
 122: struct tname *ap;
 123: {
 124:     register t, l;
 125:     register struct tname *p;
 126: 
 127:     p = ap;
 128:     if (p==0 || ((t=p->type)&~TYPE) == 0)       /* not a reference */
 129:         return(1);
 130:     p->type = decref(t);
 131:     l = length(p);
 132:     p->type = t;
 133:     return(l);
 134: }
 135: 
 136: /*
 137:  * return the number of bytes in the object
 138:  * whose tree node is acs.
 139:  */
 140: length(acs)
 141: struct tnode *acs;
 142: {
 143:     register t, n;
 144:     register struct tnode *cs;
 145: 
 146:     cs = acs;
 147:     t = cs->type;
 148:     n = 1;
 149:     while ((t&XTYPE) == ARRAY) {
 150:         t = decref(t);
 151:         n = dimtab[cs->ssp&0377];
 152:     }
 153:     if ((t&~TYPE)==FUNC)
 154:         return(0);
 155:     if (t>=PTR)
 156:         return(2*n);
 157:     switch(t&TYPE) {
 158: 
 159:     case INT:
 160:         return(2*n);
 161: 
 162:     case CHAR:
 163:         return(n);
 164: 
 165:     case FLOAT:
 166:     case LONG:
 167:         return(4*n);
 168: 
 169:     case DOUBLE:
 170:         return(8*n);
 171: 
 172:     case STRUCT:
 173:         return(n * dimtab[cs->lenp&0377]);
 174: 
 175:     case RSTRUCT:
 176:         error("Bad structure");
 177:         return(0);
 178:     }
 179:     error("Compiler error (length)");
 180: }
 181: 
 182: /*
 183:  * The number of bytes in an object, rounded up to a word.
 184:  */
 185: rlength(cs)
 186: struct tnode *cs;
 187: {
 188:     return((length(cs)+ALIGN) & ~ALIGN);
 189: }
 190: 
 191: /*
 192:  * After an "if (...) goto", look to see if the transfer
 193:  * is to a simple label.
 194:  */
 195: simplegoto()
 196: {
 197:     register struct hshtab *csp;
 198: 
 199:     if ((peeksym=symbol())==NAME && nextchar()==';') {
 200:         csp = csym;
 201:         if (csp->hclass==0 && csp->htype==0) {
 202:             csp->htype = ARRAY;
 203:             if (csp->hoffset==0)
 204:                 csp->hoffset = isn++;
 205:         }
 206:         if ((csp->hclass==0||csp->hclass==STATIC)
 207:          &&  csp->htype==ARRAY) {
 208:             peeksym = -1;
 209:             return(csp->hoffset);
 210:         }
 211:     }
 212:     return(0);
 213: }
 214: 
 215: /*
 216:  * Return the next non-white-space character
 217:  */
 218: nextchar()
 219: {
 220:     while (spnextchar()==' ')
 221:         peekc = 0;
 222:     return(peekc);
 223: }
 224: 
 225: /*
 226:  * Return the next character, translating all white space
 227:  * to blank and handling line-ends.
 228:  */
 229: spnextchar()
 230: {
 231:     register c;
 232: 
 233:     if ((c = peekc)==0)
 234:         c = getchar();
 235:     if (c=='\t')
 236:         c = ' ';
 237:     else if (c=='\n') {
 238:         c = ' ';
 239:         if (inhdr==0)
 240:             line++;
 241:         inhdr = 0;
 242:     } else if (c=='\001') { /* SOH, insert marker */
 243:         inhdr++;
 244:         c = ' ';
 245:     }
 246:     peekc = c;
 247:     return(c);
 248: }
 249: 
 250: /*
 251:  * is a break or continue legal?
 252:  */
 253: chconbrk(l)
 254: {
 255:     if (l==0)
 256:         error("Break/continue error");
 257: }
 258: 
 259: /*
 260:  * The goto statement.
 261:  */
 262: dogoto()
 263: {
 264:     register struct tnode *np;
 265: 
 266:     *cp++ = tree();
 267:     build(STAR);
 268:     chkw(np = *--cp, -1);
 269:     rcexpr(block(1,JUMP,0,0,np));
 270: }
 271: 
 272: /*
 273:  * The return statement, which has to convert
 274:  * the returned object to the function's type.
 275:  */
 276: doret()
 277: {
 278:     register struct tnode *t;
 279: 
 280:     if (nextchar() != ';') {
 281:         t = tree();
 282:         *cp++ = &funcblk;
 283:         *cp++ = t;
 284:         build(ASSIGN);
 285:         cp[-1] = cp[-1]->tr2;
 286:         build(RFORCE);
 287:         rcexpr(*--cp);
 288:     }
 289:     branch(retlab);
 290: }
 291: 
 292: /*
 293:  * write out a character to the usual output
 294:  * or to the string file
 295:  */
 296: putchar(c)
 297: {
 298:     write(1, &c, 1);
 299: }
 300: 
 301: outcode(s, a)
 302: char *s;
 303: {
 304:     register char *sp;
 305:     register *ap, *bufp;
 306:     int n;
 307:     char *np;
 308: 
 309:     bufp = obuf;
 310:     if (strflg)
 311:         bufp = sbuf;
 312:     ap = &a;
 313:     for (;;) switch(*s++) {
 314:     case 'B':
 315:         putw(*ap++ | (0376<<8), bufp);
 316:         continue;
 317: 
 318:     case 'N':
 319:         putw(*ap++, bufp);
 320:         continue;
 321: 
 322:     case 'S':
 323:         np = *ap++;
 324:         n = ncps;
 325:         while (n-- && *np) {
 326:             putc(*np++, bufp);
 327:         }
 328:         putc(0, bufp);
 329:         continue;
 330: 
 331:     case '1':
 332:         putw(1, bufp);
 333:         continue;
 334: 
 335:     case '0':
 336:         putw(0, bufp);
 337:         continue;
 338: 
 339:     case '\0':
 340:         return;
 341:     }
 342:     error("Botch in outcode");
 343: }

Defined functions

branch defined in line 105; used 12 times
cbranch defined in line 39; used 9 times
chconbrk defined in line 253; used 3 times
decref defined in line 14; used 2 times
dogoto defined in line 262; used 2 times
doret defined in line 276; used 2 times
incref defined in line 30; used 4 times
label defined in line 112; used 22 times
length defined in line 140; used 5 times
nextchar defined in line 218; used 5 times
outcode defined in line 301; used 39 times
plength defined in line 121; used 3 times
putchar defined in line 296; used 12 times
rcexpr defined in line 48; used 13 times
rlength defined in line 185; used 3 times
simplegoto defined in line 195; used 2 times
spnextchar defined in line 229; used 5 times
treeout defined in line 56; used 5 times
Last modified: 1975-07-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1044
Valid CSS Valid XHTML 1.0 Strict