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

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

unix.superglobalmegacorp.com

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