Annotation of 3BSD/cmd/pi/rec.c, revision 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 Novmeber 1978
        !             8:  */
        !             9: 
        !            10: #include "whoami"
        !            11: #include "0.h"
        !            12: #include "tree.h"
        !            13: #include "opcode.h"
        !            14: 
        !            15: /*
        !            16:  * Build a record namelist entry.
        !            17:  * Some of the processing here is somewhat involved.
        !            18:  * The basic structure we are building is as follows.
        !            19:  *
        !            20:  * Each record has a main RECORD entry, with an attached
        !            21:  * chain of fields as ->chain;  these include all the fields in all
        !            22:  * the variants of this record.
        !            23:  *
        !            24:  * Attached to NL_VARNT is a chain of VARNT structures
        !            25:  * describing each of the variants.  These are further linked
        !            26:  * through ->chain.  Each VARNT has, in ->range[0] the value of
        !            27:  * the associated constant, and each points at a RECORD describing
        !            28:  * the subrecord through NL_VTOREC.  These pointers are not unique,
        !            29:  * more than one VARNT may reference the same RECORD.
        !            30:  *
        !            31:  * The involved processing here is in computing the NL_OFFS entry
        !            32:  * by maxing over the variants.  This works as follows.
        !            33:  *
        !            34:  * Each RECORD has two size counters.  NL_OFFS is the maximum size
        !            35:  * so far of any variant of this record;  NL_FLDSZ gives the size
        !            36:  * of just the FIELDs to this point as a base for further variants.
        !            37:  *
        !            38:  * As we process each variant record, we start its size with the
        !            39:  * NL_FLDSZ we have so far.  After processing it, if its NL_OFFS
        !            40:  * is the largest so far, we update the NL_OFFS of this subrecord.
        !            41:  * This will eventually propagate back and update the NL_OFFS of the
        !            42:  * entire record.
        !            43:  */
        !            44: 
        !            45: /*
        !            46:  * P0 points to the outermost RECORD for name searches.
        !            47:  */
        !            48: struct nl *P0;
        !            49: 
        !            50: tyrec(r, off)
        !            51:        int *r, off;
        !            52: {
        !            53: 
        !            54:            return tyrec1(r, off, 1);
        !            55: }
        !            56: 
        !            57: /*
        !            58:  * Define a record namelist entry.
        !            59:  * R is the tree for the record to be built.
        !            60:  * Off is the offset for the first item in this (sub)record.
        !            61:  */
        !            62: struct nl *
        !            63: tyrec1(r, off, first)
        !            64:        register int *r;
        !            65:        int off;
        !            66:        char first;
        !            67: {
        !            68:        register struct nl *p, *P0was;
        !            69: 
        !            70:        p = defnl(0, RECORD, 0, 0);
        !            71:        P0was = P0;
        !            72:        if (first)
        !            73:                P0 = p;
        !            74: #ifndef PI0
        !            75:        p->value[NL_FLDSZ] = p->value[NL_OFFS] = off;
        !            76: #endif
        !            77:        if (r != NIL) {
        !            78:                fields(p, r[2]);
        !            79:                variants(p, r[3]);
        !            80:        }
        !            81:        P0 = P0was;
        !            82:        return (p);
        !            83: }
        !            84: 
        !            85: /*
        !            86:  * Define the fixed part fields for p.
        !            87:  */
        !            88: struct nl *
        !            89: fields(p, r)
        !            90:        struct nl *p;
        !            91:        int *r;
        !            92: {
        !            93:        register int *fp, *tp, *ip;
        !            94:        struct nl *jp;
        !            95: 
        !            96:        for (fp = r; fp != NIL; fp = fp[2]) {
        !            97:                tp = fp[1];
        !            98:                if (tp == NIL)
        !            99:                        continue;
        !           100:                jp = gtype(tp[3]);
        !           101:                line = tp[1];
        !           102:                for (ip = tp[2]; ip != NIL; ip = ip[2])
        !           103:                        deffld(p, ip[1], jp);
        !           104:        }
        !           105: }
        !           106: 
        !           107: /*
        !           108:  * Define the variants for RECORD p.
        !           109:  */
        !           110: struct nl *
        !           111: variants(p, r)
        !           112:        struct nl *p;
        !           113:        register int *r;
        !           114: {
        !           115:        register int *vc, *v;
        !           116:        int *vr;
        !           117:        struct nl *ct;
        !           118: 
        !           119:        if (r == NIL)
        !           120:                return;
        !           121:        ct = gtype(r[3]);
        !           122:        line = r[1];
        !           123:        /*
        !           124:         * Want it even if r[2] is NIL so
        !           125:         * we check its type in "new" and "dispose"
        !           126:         * calls -- link it to NL_TAG.
        !           127:         */
        !           128:        p->ptr[NL_TAG] = deffld(p, r[2], ct);
        !           129:        for (vc = r[4]; vc != NIL; vc = vc[2]) {
        !           130:                v = vc[1];
        !           131:                if (v == NIL)
        !           132:                        continue;
        !           133:                vr = tyrec1(v[3], p->value[NL_FLDSZ], 0);
        !           134: #ifndef PI0
        !           135:                if (vr->value[NL_OFFS] > p->value[NL_OFFS])
        !           136:                        p->value[NL_OFFS] = vr->value[NL_OFFS];
        !           137: #endif
        !           138:                line = v[1];
        !           139:                for (v = v[2]; v != NIL; v = v[2])
        !           140:                        defvnt(p, v[1], vr, ct);
        !           141:        }
        !           142: }
        !           143: 
        !           144: /*
        !           145:  * Define a field in subrecord p of record P0
        !           146:  * with name s and type t.
        !           147:  */
        !           148: struct nl *
        !           149: deffld(p, s, t)
        !           150:        struct nl *p;
        !           151:        register char *s;
        !           152:        register struct nl *t;
        !           153: {
        !           154:        register struct nl *fp;
        !           155: 
        !           156:        if (reclook(P0, s) != NIL) {
        !           157: #ifndef PI1
        !           158:                error("%s is a duplicate field name in this record", s);
        !           159: #endif
        !           160:                s = NIL;
        !           161:        }
        !           162: #ifndef PI0
        !           163:        fp = enter(defnl(s, FIELD, t, p->value[NL_OFFS]));
        !           164: #else
        !           165:        fp = enter(defnl(s, FIELD, t, 0));
        !           166: #endif
        !           167:        if (s != NIL) {
        !           168:                fp->chain = P0->chain;
        !           169:                P0->chain = fp;
        !           170: #ifndef PI0
        !           171:                p->value[NL_FLDSZ] = p->value[NL_OFFS] += even(width(t));
        !           172: #endif
        !           173:                if (t != NIL) {
        !           174:                        P0->nl_flags |= t->nl_flags & NFILES;
        !           175:                        p->nl_flags |= t->nl_flags & NFILES;
        !           176:                }
        !           177:        }
        !           178:        return (fp);
        !           179: }
        !           180: 
        !           181: /*
        !           182:  * Define a variant from the constant tree of t
        !           183:  * in subrecord p of record P0 where the casetype
        !           184:  * is ct and the variant record to be associated is vr.
        !           185:  */
        !           186: struct nl *
        !           187: defvnt(p, t, vr, ct)
        !           188:        struct nl *p, *vr;
        !           189:        int *t;
        !           190:        register struct nl *ct;
        !           191: {
        !           192:        register struct nl *av;
        !           193: 
        !           194:        gconst(t);
        !           195:        if (ct != NIL && incompat(con.ctype, ct)) {
        !           196: #ifndef PI1
        !           197:                cerror("Variant label type incompatible with selector type");
        !           198: #endif
        !           199:                ct = NIL;
        !           200:        }
        !           201:        av = defnl(0, VARNT, ct, 0);
        !           202: #ifndef PI1
        !           203:        if (ct != NIL)
        !           204:                uniqv(p);
        !           205: #endif
        !           206:        av->chain = p->ptr[NL_VARNT];
        !           207:        p->ptr[NL_VARNT] = av;
        !           208:        av->ptr[NL_VTOREC] = vr;
        !           209:        av->range[0] = con.crval;
        !           210:        return (av);
        !           211: }
        !           212: 
        !           213: #ifndef PI1
        !           214: /*
        !           215:  * Check that the constant label value
        !           216:  * is unique among the labels in this variant.
        !           217:  */
        !           218: uniqv(p)
        !           219:        struct nl *p;
        !           220: {
        !           221:        register struct nl *vt;
        !           222: 
        !           223:        for (vt = p->ptr[NL_VARNT]; vt != NIL; vt = vt->chain)
        !           224:                if (vt->range[0] == con.crval) {
        !           225:                        error("Duplicate variant case label in record");
        !           226:                        return;
        !           227:                }
        !           228: }
        !           229: #endif
        !           230: 
        !           231: /*
        !           232:  * See if the field name s is defined
        !           233:  * in the record p, returning a pointer
        !           234:  * to it namelist entry if it is.
        !           235:  */
        !           236: struct nl *
        !           237: reclook(p, s)
        !           238:        register struct nl *p;
        !           239:        char *s;
        !           240: {
        !           241: 
        !           242:        if (p == NIL || s == NIL)
        !           243:                return (NIL);
        !           244:        for (p = p->chain; p != NIL; p = p->chain)
        !           245:                if (p->symbol == s)
        !           246:                        return (p);
        !           247:        return (NIL);
        !           248: }

unix.superglobalmegacorp.com

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