Annotation of 40BSD/cmd/pi/lval.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) 1979 Regents of the University of California */
                      2: 
                      3: static char sccsid[] = "@(#)lval.c 1.1 8/27/80";
                      4: 
                      5: #include "whoami.h"
                      6: #include "0.h"
                      7: #include "tree.h"
                      8: #include "opcode.h"
                      9: #include "objfmt.h"
                     10: #ifdef PC
                     11: #   include    "pc.h"
                     12: #   include    "pcops.h"
                     13: #endif PC
                     14: 
                     15: extern int flagwas;
                     16: /*
                     17:  * Lvalue computes the address
                     18:  * of a qualified name and
                     19:  * leaves it on the stack.
                     20:  * for pc, it can be asked for either an lvalue or an rvalue.
                     21:  * the semantics are the same, only the code is different.
                     22:  */
                     23: struct nl *
                     24: lvalue(r, modflag , required )
                     25:        int *r, modflag;
                     26:        int     required;
                     27: {
                     28:        register struct nl *p;
                     29:        struct nl *firstp, *lastp;
                     30:        register *c, *co;
                     31:        int f, o;
                     32:        /*
                     33:         * Note that the local optimizations
                     34:         * done here for offsets would more
                     35:         * appropriately be done in put.
                     36:         */
                     37:        int tr[2], trp[3];
                     38: 
                     39:        if (r == NIL) {
                     40:                return (NIL);
                     41:        }
                     42:        if (nowexp(r)) {
                     43:                return (NIL);
                     44:        }
                     45:        if (r[0] != T_VAR) {
                     46:                error("Variable required");     /* Pass mesgs down from pt of call ? */
                     47:                return (NIL);
                     48:        }
                     49: #      ifdef PC
                     50:                /*
                     51:                 *      pc requires a whole different control flow
                     52:                 */
                     53:            return pclvalue( r , modflag , required );
                     54: #      endif PC
                     55:        firstp = p = lookup(r[2]);
                     56:        if (p == NIL) {
                     57:                return (NIL);
                     58:        }
                     59:        c = r[3];
                     60:        if ((modflag & NOUSE) && !lptr(c)) {
                     61:                p->nl_flags = flagwas;
                     62:        }
                     63:        if (modflag & MOD) {
                     64:                p->nl_flags |= NMOD;
                     65:        }
                     66:        /*
                     67:         * Only possibilities for p->class here
                     68:         * are the named classes, i.e. CONST, TYPE
                     69:         * VAR, PROC, FUNC, REF, or a WITHPTR.
                     70:         */
                     71:        switch (p->class) {
                     72:                case WITHPTR:
                     73:                        /*
                     74:                         * Construct the tree implied by
                     75:                         * the with statement
                     76:                         */
                     77:                        trp[0] = T_LISTPP;
                     78:                        trp[1] = tr;
                     79:                        trp[2] = r[3];
                     80:                        tr[0] = T_FIELD;
                     81:                        tr[1] = r[2];
                     82:                        c = trp;
                     83: #                      ifdef PTREE
                     84:                            /*
                     85:                             * mung r[4] to say which field this T_VAR is
                     86:                             * for VarCopy
                     87:                             */
                     88:                            r[4] = reclook( p -> type , r[2] );
                     89: #                      endif
                     90:                        /* and fall through */
                     91:                case REF:
                     92:                        /*
                     93:                         * Obtain the indirect word
                     94:                         * of the WITHPTR or REF
                     95:                         * as the base of our lvalue
                     96:                         */
                     97:                        put(2, PTR_RV | bn << 8+INDX , p->value[0] );
                     98:                        f = 0;          /* have an lv on stack */
                     99:                        o = 0;
                    100:                        break;
                    101:                case VAR:
                    102:                        f = 1;          /* no lv on stack yet */
                    103:                        o = p->value[0];
                    104:                        break;
                    105:                default:
                    106:                        error("%s %s found where variable required", classes[p->class], p->symbol);
                    107:                        return (NIL);
                    108:        }
                    109:        /*
                    110:         * Loop and handle each
                    111:         * qualification on the name
                    112:         */
                    113:        if (c == NIL && (modflag&ASGN) && p->value[NL_FORV]) {
                    114:                error("Can't modify the for variable %s in the range of the loop", p->symbol);
                    115:                return (NIL);
                    116:        }
                    117:        for (; c != NIL; c = c[2]) {
                    118:                co = c[1];
                    119:                if (co == NIL) {
                    120:                        return (NIL);
                    121:                }
                    122:                lastp = p;
                    123:                p = p->type;
                    124:                if (p == NIL) {
                    125:                        return (NIL);
                    126:                }
                    127:                switch (co[0]) {
                    128:                        case T_PTR:
                    129:                                /*
                    130:                                 * Pointer qualification.
                    131:                                 */
                    132:                                lastp->nl_flags |= NUSED;
                    133:                                if (p->class != PTR && p->class != FILET) {
                    134:                                        error("^ allowed only on files and pointers, not on %ss", nameof(p));
                    135:                                        goto bad;
                    136:                                }
                    137:                                if (f) {
                    138:                                    put(2, PTR_RV | bn <<8+INDX , o );
                    139:                                } else {
                    140:                                        if (o) {
                    141:                                            put2(O_OFF, o);
                    142:                                        }
                    143:                                        put(1, PTR_IND);
                    144:                                }
                    145:                                /*
                    146:                                 * Pointer cannot be
                    147:                                 * nil and file cannot
                    148:                                 * be at end-of-file.
                    149:                                 */
                    150:                                put1(p->class == FILET ? O_FNIL : O_NIL);
                    151:                                f = o = 0;
                    152:                                continue;
                    153:                        case T_ARGL:
                    154:                                if (p->class != ARRAY) {
                    155:                                        if (lastp == firstp) {
                    156:                                                error("%s is a %s, not a function", r[2], classes[firstp->class]);
                    157:                                        } else {
                    158:                                                error("Illegal function qualificiation");
                    159:                                        }
                    160:                                        return (NIL);
                    161:                                }
                    162:                                recovered();
                    163:                                error("Pascal uses [] for subscripting, not ()");
                    164:                        case T_ARY:
                    165:                                if (p->class != ARRAY) {
                    166:                                        error("Subscripting allowed only on arrays, not on %ss", nameof(p));
                    167:                                        goto bad;
                    168:                                }
                    169:                                if (f) {
                    170:                                        put2(O_LV | bn<<8+INDX, o);
                    171:                                } else {
                    172:                                        if (o) {
                    173:                                            put2(O_OFF, o);
                    174:                                        }
                    175:                                }
                    176:                                switch (arycod(p, co[1])) {
                    177:                                        case 0:
                    178:                                                return (NIL);
                    179:                                        case -1:
                    180:                                                goto bad;
                    181:                                }
                    182:                                f = o = 0;
                    183:                                continue;
                    184:                        case T_FIELD:
                    185:                                /*
                    186:                                 * Field names are just
                    187:                                 * an offset with some 
                    188:                                 * semantic checking.
                    189:                                 */
                    190:                                if (p->class != RECORD) {
                    191:                                        error(". allowed only on records, not on %ss", nameof(p));
                    192:                                        goto bad;
                    193:                                }
                    194:                                if (co[1] == NIL) {
                    195:                                        return (NIL);
                    196:                                }
                    197:                                p = reclook(p, co[1]);
                    198:                                if (p == NIL) {
                    199:                                        error("%s is not a field in this record", co[1]);
                    200:                                        goto bad;
                    201:                                }
                    202: #                              ifdef PTREE
                    203:                                    /*
                    204:                                     * mung co[3] to indicate which field
                    205:                                     * this is for SelCopy
                    206:                                     */
                    207:                                    co[3] = p;
                    208: #                              endif
                    209:                                if (modflag & MOD) {
                    210:                                        p->nl_flags |= NMOD;
                    211:                                }
                    212:                                if ((modflag & NOUSE) == 0 || lptr(c[2])) {
                    213:                                        p->nl_flags |= NUSED;
                    214:                                }
                    215:                                o += p->value[0];
                    216:                                continue;
                    217:                        default:
                    218:                                panic("lval2");
                    219:                }
                    220:        }
                    221:        if (f) {
                    222:                put2(O_LV | bn<<8+INDX, o);
                    223:        } else {
                    224:                if (o) {
                    225:                    put2(O_OFF, o);
                    226:                }
                    227:        }
                    228:        return (p->type);
                    229: bad:
                    230:        cerror("Error occurred on qualification of %s", r[2]);
                    231:        return (NIL);
                    232: }
                    233: 
                    234: lptr(c)
                    235:        register int *c;
                    236: {
                    237:        register int *co;
                    238: 
                    239:        for (; c != NIL; c = c[2]) {
                    240:                co = c[1];
                    241:                if (co == NIL) {
                    242:                        return (NIL);
                    243:                }
                    244:                switch (co[0]) {
                    245: 
                    246:                case T_PTR:
                    247:                        return (1);
                    248:                case T_ARGL:
                    249:                        return (0);
                    250:                case T_ARY:
                    251:                case T_FIELD:
                    252:                        continue;
                    253:                default:
                    254:                        panic("lptr");
                    255:                }
                    256:        }
                    257:        return (0);
                    258: }
                    259: 
                    260: /*
                    261:  * Arycod does the
                    262:  * code generation
                    263:  * for subscripting.
                    264:  */
                    265: arycod(np, el)
                    266:        struct nl *np;
                    267:        int *el;
                    268: {
                    269:        register struct nl *p, *ap;
                    270:        int i, d, v, v1;
                    271:        int w;
                    272: 
                    273:        p = np;
                    274:        if (el == NIL) {
                    275:                return (0);
                    276:        }
                    277:        d = p->value[0];
                    278:        /*
                    279:         * Check each subscript
                    280:         */
                    281:        for (i = 1; i <= d; i++) {
                    282:                if (el == NIL) {
                    283:                        error("Too few subscripts (%d given, %d required)", i-1, d);
                    284:                        return (-1);
                    285:                }
                    286:                p = p->chain;
                    287: #              ifdef PC
                    288:                    precheck( p , "_SUBSC" , "_SUBSCZ" );
                    289: #              endif PC
                    290:                ap = rvalue(el[1], NLNIL , RREQ );
                    291:                if (ap == NIL) {
                    292:                        return (0);
                    293:                }
                    294: #              ifdef PC
                    295:                    postcheck( p );
                    296: #              endif PC
                    297:                if (incompat(ap, p->type, el[1])) {
                    298:                        cerror("Array index type incompatible with declared index type");
                    299:                        if (d != 1) {
                    300:                                cerror("Error occurred on index number %d", i);
                    301:                        }
                    302:                        return (-1);
                    303:                }
                    304:                w = aryconst(np, i);
                    305: #              ifdef OBJ
                    306:                    if (opt('t') == 0) {
                    307:                            switch (w) {
                    308:                            case 8:
                    309:                                    w = 6;
                    310:                            case 4:
                    311:                            case 2:
                    312:                            case 1:
                    313:                                    put2((width(ap) != 4 ? O_INX2P2 : O_INX4P2) | (w & ~1) << 7, ( short ) p->range[0]);
                    314:                                    el = el[2];
                    315:                                    continue;
                    316:                            }
                    317:                    }
                    318:                    put(4, width(ap) != 4 ? O_INX2 : O_INX4,w,( short ) p->range[0],
                    319:                           ( short ) ( p->range[1] - p->range[0] ) );
                    320: #              endif OBJ
                    321: #              ifdef PC
                    322:                        /*
                    323:                         *      subtract off the lower bound
                    324:                         */
                    325:                    if ( p -> range[ 0 ] != 0 ) {
                    326:                        putleaf( P2ICON , p -> range[0] , 0 , P2INT , 0 );
                    327:                        putop( P2MINUS , P2INT );
                    328:                    }
                    329:                        /*
                    330:                         *      multiply by the width of the elements
                    331:                         */
                    332:                    if ( w != 1 ) {
                    333:                        putleaf( P2ICON , w , 0 , P2INT , 0 );
                    334:                        putop( P2MUL , P2INT );
                    335:                    }
                    336:                        /*
                    337:                         *      and add it to the base address
                    338:                         */
                    339:                    putop( P2PLUS , ADDTYPE( p2type( np -> type ) , P2PTR ) );
                    340: #              endif PC
                    341:                el = el[2];
                    342:        }
                    343:        if (el != NIL) {
                    344:                do {
                    345:                        el = el[2];
                    346:                        i++;
                    347:                } while (el != NIL);
                    348:                error("Too many subscripts (%d given, %d required)", i-1, d);
                    349:                return (-1);
                    350:        }
                    351:        return (1);
                    352: }

unix.superglobalmegacorp.com

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