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

Defined functions

branch defined in line 147; used 14 times
cbranch defined in line 40; used 9 times
chconbrk defined in line 317; used 3 times
decref defined in line 15; used 2 times
dogoto defined in line 326; used 2 times
doret defined in line 340; used 2 times
incref defined in line 31; used 5 times
label defined in line 155; used 24 times
length defined in line 184; used 9 times
nextchar defined in line 282; used 6 times
outcode defined in line 369; used 54 times
plength defined in line 165; used 3 times
rcexpr defined in line 50; used 18 times
rlength defined in line 246; used 3 times
simplegoto defined in line 256; used 2 times
spnextchar defined in line 293; used 8 times
treeout defined in line 71; used 8 times
Last modified: 1981-07-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1131
Valid CSS Valid XHTML 1.0 Strict