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

Defined functions

branch defined in line 146; used 14 times
cbranch defined in line 39; used 9 times
chconbrk defined in line 316; used 3 times
decref defined in line 14; used 2 times
dogoto defined in line 325; used 2 times
doret defined in line 339; used 2 times
incref defined in line 30; used 5 times
label defined in line 154; used 24 times
length defined in line 183; used 9 times
nextchar defined in line 281; used 6 times
outcode defined in line 368; used 54 times
plength defined in line 164; used 3 times
rcexpr defined in line 49; used 18 times
rlength defined in line 245; used 3 times
simplegoto defined in line 255; used 2 times
spnextchar defined in line 292; used 8 times
treeout defined in line 70; used 8 times
Last modified: 1979-05-07
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1002
Valid CSS Valid XHTML 1.0 Strict