Annotation of researchv10no/cmd/PDP11/11c/c04.c, revision 1.1.1.1

1.1       root        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 LONG:
                    215:                elsz = SZLONG;
                    216:                break;
                    217: 
                    218:        case DOUBLE:
                    219:                elsz = SZDOUB;
                    220:                break;
                    221: 
                    222:        case STRUCT:
                    223:                if ((elsz = cs->t.strp->S.ssize) == 0)
                    224:                        error("Undefined structure");
                    225:                break;
                    226:        default:
                    227:                error("Compiler error (length)");
                    228:                return(0);
                    229:        }
                    230:        n *= elsz;
                    231:        if (n >= (unsigned)50000) {
                    232:                error("Warning: very large data structure");
                    233:                nerror--;
                    234:        }
                    235:        return(n);
                    236: }
                    237: 
                    238: /*
                    239:  * The number of bytes in an object, rounded up to a word.
                    240:  */
                    241: rlength(cs)
                    242: union tree *cs;
                    243: {
                    244:        return((length(cs)+ALIGN) & ~ALIGN);
                    245: }
                    246: 
                    247: /*
                    248:  * After an "if (...) goto", look to see if the transfer
                    249:  * is to a simple label.
                    250:  */
                    251: simplegoto()
                    252: {
                    253:        register struct nmlist *csp;
                    254: 
                    255:        if ((peeksym=symbol())==NAME && nextchar()==';') {
                    256:                csp = csym;
                    257:                if (csp->hblklev == 0)
                    258:                        csp = pushdecl(csp);
                    259:                if (csp->hclass==0 && csp->htype==0) {
                    260:                        csp->htype = ARRAY;
                    261:                        csp->hflag |= FLABL;
                    262:                        if (csp->hoffset==0)
                    263:                                csp->hoffset = isn++;
                    264:                }
                    265:                if ((csp->hclass==0||csp->hclass==STATIC)
                    266:                 &&  csp->htype==ARRAY) {
                    267:                        peeksym = -1;
                    268:                        return(csp->hoffset);
                    269:                }
                    270:        }
                    271:        return(0);
                    272: }
                    273: 
                    274: /*
                    275:  * Return the next non-white-space character
                    276:  */
                    277: nextchar()
                    278: {
                    279:        while (spnextchar()==' ')
                    280:                peekc = 0;
                    281:        return(peekc);
                    282: }
                    283: 
                    284: /*
                    285:  * Return the next character, translating all white space
                    286:  * to blank and handling line-ends.
                    287:  */
                    288: spnextchar()
                    289: {
                    290:        register c;
                    291: 
                    292:        if ((c = peekc)==0)
                    293:                c = getchar();
                    294:        if (c=='\t' || c=='\014')       /* FF */
                    295:                c = ' ';
                    296:        else if (c=='\n') {
                    297:                c = ' ';
                    298:                line++;
                    299:        }
                    300:        peekc = c;
                    301:        return(c);
                    302: }
                    303: 
                    304: /*
                    305:  * is a break or continue legal?
                    306:  */
                    307: chconbrk(l)
                    308: {
                    309:        if (l==0)
                    310:                error("Break/continue error");
                    311: }
                    312: 
                    313: /*
                    314:  * The goto statement.
                    315:  */
                    316: dogoto()
                    317: {
                    318:        register union tree *np;
                    319:        register char *st;
                    320: 
                    321:        st = starttree();
                    322:        *cp++ = tree(0);
                    323:        build(STAR);
                    324:        chkw(np = *--cp, -1);
                    325:        rcexpr(block(JUMP, 0, (int *)NULL, (union str *)NULL, np, TNULL));
                    326:        endtree(st);
                    327: }
                    328: 
                    329: /*
                    330:  * The return statement, which has to convert
                    331:  * the returned object to the function's type.
                    332:  */
                    333: doret()
                    334: {
                    335:        register union tree *t;
                    336: 
                    337:        if (nextchar() != ';') {
                    338:                register char *st;
                    339: 
                    340:                st = starttree();
                    341:                *cp++ = (union tree *)&funcblk;
                    342:                *cp++ = tree(0);
                    343:                build(ASSIGN);
                    344:                cp[-1] = cp[-1]->t.tr2;
                    345:                build(RFORCE);
                    346:                rcexpr(*--cp);
                    347:                endtree(st);
                    348:        }
                    349:        branch(retlab);
                    350: }
                    351: 
                    352: /*
                    353:  * Write a character on the error output.
                    354:  */
                    355: /*
                    356:  * Coded output:
                    357:  *   B: beginning of line; an operator
                    358:  *   N: a number
                    359:  *   S: a symbol (external)
                    360:  *   1: number 1
                    361:  *   0: number 0
                    362:  */
                    363: /* VARARGS1 */
                    364: outcode(s, a)
                    365: char *s;
                    366: {
                    367:        register *ap;
                    368:        register FILE *bufp;
                    369:        int n;
                    370:        register char *np;
                    371: 
                    372:        bufp = stdout;
                    373:        if (strflg)
                    374:                bufp = sbufp;
                    375:        ap = &a;
                    376:        for (;;) switch(*s++) {
                    377:        case 'B':
                    378:                putc(*ap++, bufp);
                    379:                putc(0376, bufp);
                    380:                continue;
                    381: 
                    382:        case 'N':
                    383:                putc(*ap, bufp);
                    384:                putc(*ap++>>8, bufp);
                    385:                continue;
                    386: 
                    387:        case 'F':
                    388:                n = 1000;
                    389:                np = (char *)*ap++;
                    390:                goto str;
                    391: 
                    392:        case 'S':
                    393:                n = NCPS;
                    394:                np = (char *)*ap++;
                    395:                if (*np)
                    396:                        putc('_', bufp);
                    397:        str:
                    398:                while (n-- && *np) {
                    399:                        putc(*np++&0177, bufp);
                    400:                }
                    401:                putc(0, bufp);
                    402:                continue;
                    403: 
                    404:        case '1':
                    405:                putc(1, bufp);
                    406:                putc(0, bufp);
                    407:                continue;
                    408: 
                    409:        case '0':
                    410:                putc(0, bufp);
                    411:                putc(0, bufp);
                    412:                continue;
                    413: 
                    414:        case '\0':
                    415:                if (ferror(bufp)) {
                    416:                        error("Write error on temp");
                    417:                        exit(1);
                    418:                }
                    419:                return;
                    420: 
                    421:        default:
                    422:                error("Botch in outcode");
                    423:        }
                    424: }
                    425: 
                    426: unsigned
                    427: hash(sp)
                    428: register char *sp;
                    429: {
                    430:        register unsigned h;
                    431:        register c;
                    432: 
                    433:        h = 0;
                    434:        c = 7;
                    435:        do {
                    436:                if (*sp == 0)
                    437:                        break;
                    438:                h += h;
                    439:                h += *sp++;
                    440:        } while (--c != 0);
                    441:        return(h%HSHSIZ);
                    442: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.