Annotation of 40BSD/cmd/pi/cset.c, revision 1.1

1.1     ! root        1: /* Copyright (c) 1979 Regents of the University of California */
        !             2: 
        !             3: static char sccsid[] = "@(#)cset.c 1.2 10/19/80";
        !             4: 
        !             5: #include "whoami.h"
        !             6: #include "0.h"
        !             7: #include "tree.h"
        !             8: #include "opcode.h"
        !             9: #include "objfmt.h"
        !            10: #include "pc.h"
        !            11: #include "pcops.h"
        !            12: 
        !            13: /*
        !            14:  *     rummage through a `constant' set (i.e. anything within [ ]'s) tree
        !            15:  *     and decide if this is a compile time constant set or a runtime set.
        !            16:  *     this information is returned in a structure passed from the caller.
        !            17:  *     while rummaging, this also reorders the tree so that all ranges
        !            18:  *     preceed all singletons.
        !            19:  */
        !            20: bool
        !            21: precset( r , settype , csetp )
        !            22:        int             *r;
        !            23:        struct nl       *settype;
        !            24:        struct csetstr  *csetp;
        !            25: {
        !            26:        register int            *e;
        !            27:        register struct nl      *t;
        !            28:        register struct nl      *exptype;
        !            29:        register int            *el;
        !            30:        register int            *pairp;
        !            31:        register int            *singp;
        !            32:        int                     *ip;
        !            33:        long                    lower;
        !            34:        long                    upper;
        !            35:        long                    rangeupper;
        !            36:        bool                    setofint;
        !            37: 
        !            38:        csetp -> csettype = NIL;
        !            39:        csetp -> paircnt = 0;
        !            40:        csetp -> singcnt = 0;
        !            41:        csetp -> comptime = TRUE;
        !            42:        setofint = FALSE;
        !            43:        if ( settype != NIL ) {
        !            44:            if ( settype -> class == SET ) {
        !            45:                    /*
        !            46:                     *  the easy case, we are told the type of the set.
        !            47:                     */
        !            48:                exptype = settype -> type;
        !            49:            } else {
        !            50:                    /*
        !            51:                     *  we are told the type, but it's not a set
        !            52:                     *  supposedly possible if someone tries
        !            53:                     *  e.g string context [1,2] = 'abc'
        !            54:                     */
        !            55:                error("Constant set involved in non set context");
        !            56:                return csetp -> comptime;
        !            57:            }
        !            58:        } else {
        !            59:                /*
        !            60:                 * So far we have no indication
        !            61:                 * of what the set type should be.
        !            62:                 * We "look ahead" and try to infer
        !            63:                 * The type of the constant set
        !            64:                 * by evaluating one of its members.
        !            65:                 */
        !            66:            e = r[2];
        !            67:            if (e == NIL) {
        !            68:                    /*
        !            69:                     *  tentative for [], return type of `intset'
        !            70:                     */
        !            71:                settype = lookup( intset );
        !            72:                if ( settype == NIL ) {
        !            73:                    panic( "empty set" );
        !            74:                }
        !            75:                settype = settype -> type;
        !            76:                if ( settype == NIL ) {
        !            77:                    return csetp -> comptime;
        !            78:                }
        !            79:                if ( isnta( settype , "t" ) ) {
        !            80:                    error("Set default type \"intset\" is not a set");
        !            81:                    return csetp -> comptime;
        !            82:                }
        !            83:                csetp -> csettype = settype;
        !            84:                return csetp -> comptime;
        !            85:            }
        !            86:            e = e[1];
        !            87:            if (e == NIL) {
        !            88:                return csetp -> comptime;
        !            89:            }
        !            90:            if (e[0] == T_RANG) {
        !            91:                    e = e[1];
        !            92:            }
        !            93:            codeoff();
        !            94:            t = rvalue(e, NIL , RREQ );
        !            95:            codeon();
        !            96:            if (t == NIL) {
        !            97:                return csetp -> comptime;
        !            98:            }
        !            99:                /*
        !           100:                 * The type of the set, settype, is
        !           101:                 * deemed to be a set of the base type
        !           102:                 * of t, which we call exptype.  If,
        !           103:                 * however, this would involve a
        !           104:                 * "set of integer", we cop out
        !           105:                 * and use "intset"'s current scoped
        !           106:                 * type instead.
        !           107:                 */
        !           108:            if (isa(t, "r")) {
        !           109:                    error("Sets may not have 'real' elements");
        !           110:                    return csetp -> comptime;
        !           111:            }
        !           112:            if (isnta(t, "bcsi")) {
        !           113:                    error("Set elements must be scalars, not %ss", nameof(t));
        !           114:                    return csetp -> comptime;
        !           115:            }
        !           116:            if (isa(t, "i")) {
        !           117:                    settype = lookup(intset);
        !           118:                    if (settype == NIL)
        !           119:                            panic("intset");
        !           120:                    settype = settype->type;
        !           121:                    if (settype == NIL)
        !           122:                            return csetp -> comptime;
        !           123:                    if (isnta(settype, "t")) {
        !           124:                            error("Set default type \"intset\" is not a set");
        !           125:                            return csetp -> comptime;
        !           126:                    }
        !           127:                    exptype = settype->type;
        !           128:                        /*
        !           129:                         *      say we are doing an intset
        !           130:                         *      but, if we get out of range errors for intset
        !           131:                         *      we punt constructing the set at compile time.
        !           132:                         */
        !           133:                    setofint = TRUE;
        !           134:            } else {
        !           135:                        exptype = t->type;
        !           136:                        if (exptype == NIL)
        !           137:                                return csetp -> comptime;
        !           138:                        if (exptype->class != RANGE)
        !           139:                                exptype = exptype->type;
        !           140:                        settype = defnl(0, SET, exptype, 0);
        !           141:            }
        !           142:        }
        !           143:        csetp -> csettype = settype;
        !           144:        setran( exptype );
        !           145:        lower = set.lwrb;
        !           146:        upper = set.lwrb + set.uprbp;
        !           147:        pairp = NIL;
        !           148:        singp = NIL;
        !           149:        codeoff();
        !           150:        while ( el = r[2] ) {
        !           151:                e = el[1];
        !           152:                if (e == NIL) {
        !           153:                            /*
        !           154:                             *  don't hang this one anywhere.
        !           155:                             */
        !           156:                        csetp -> csettype = NIL;
        !           157:                        r[2] = el[2];
        !           158:                        continue;
        !           159:                }
        !           160:                if (e[0] == T_RANG) {
        !           161:                        if ( csetp -> comptime && constval( e[2] ) ) {
        !           162:                            t = con.ctype;
        !           163:                            if ( ((long)con.crval) < lower || ((long)con.crval) > upper ) {
        !           164:                                if ( setofint ) {
        !           165:                                    csetp -> comptime = FALSE;
        !           166:                                } else {
        !           167:                                    error("Range upper bound of %d out of set bounds" , ((long)con.crval) );
        !           168:                                    csetp -> csettype = NIL;
        !           169:                                }
        !           170:                            }
        !           171:                            rangeupper = ((long)con.crval);
        !           172:                        } else {
        !           173:                            csetp -> comptime = FALSE;
        !           174:                            t = rvalue(e[2], NIL , RREQ );
        !           175:                            if (t == NIL) {
        !           176:                                    rvalue(e[1], NIL , RREQ );
        !           177:                                    goto pairhang;
        !           178:                            }
        !           179:                        }
        !           180:                        if (incompat(t, exptype, e[2])) {
        !           181:                                cerror("Upper bound of element type clashed with set type in constant set");
        !           182:                        }
        !           183:                        if ( csetp -> comptime && constval( e[1] ) ) {
        !           184:                            t = con.ctype;
        !           185:                            if ( ((long)con.crval) < lower || ((long)con.crval) > upper ) {
        !           186:                                if ( setofint ) {
        !           187:                                    csetp -> comptime = FALSE;
        !           188:                                } else {
        !           189:                                    error("Range lower bound of %d out of set bounds" , ((long)con.crval) );
        !           190:                                    csetp -> csettype = NIL;
        !           191:                                }
        !           192:                            }
        !           193:                        } else {
        !           194:                            csetp -> comptime = FALSE;
        !           195:                            t = rvalue(e[1], NIL , RREQ );
        !           196:                            if (t == NIL) {
        !           197:                                    goto pairhang;
        !           198:                            }
        !           199:                        }
        !           200:                        if (incompat(t, exptype, e[1])) {
        !           201:                                cerror("Lower bound of element type clashed with set type in constant set");
        !           202:                        }
        !           203: pairhang:
        !           204:                            /*
        !           205:                             *  remove this range from the tree list and 
        !           206:                             *  hang it on the pairs list.
        !           207:                             */
        !           208:                        ip = el[2];
        !           209:                        el[2] = pairp;
        !           210:                        pairp = r[2];
        !           211:                        r[2] = ip;
        !           212:                        csetp -> paircnt++;
        !           213:                } else {
        !           214:                        if ( csetp -> comptime && constval( e ) ) {
        !           215:                            t = con.ctype;
        !           216:                            if ( ((long)con.crval) < lower || ((long)con.crval) > upper ) {
        !           217:                                if ( setofint ) {
        !           218:                                    csetp -> comptime = FALSE;
        !           219:                                } else {
        !           220:                                    error("Value of %d out of set bounds" , ((long)con.crval) );
        !           221:                                    csetp -> csettype = NIL;
        !           222:                                }
        !           223:                            }
        !           224:                        } else {
        !           225:                            csetp -> comptime = FALSE;
        !           226:                            t = rvalue((int *) e, NLNIL , RREQ );
        !           227:                            if (t == NIL) {
        !           228:                                    goto singhang;
        !           229:                            }
        !           230:                        }
        !           231:                        if (incompat(t, exptype, e)) {
        !           232:                                cerror("Element type clashed with set type in constant set");
        !           233:                        }
        !           234: singhang:
        !           235:                            /*
        !           236:                             *  take this expression off the tree list and
        !           237:                             *  hang it on the list of singletons.
        !           238:                             */
        !           239:                        ip = el[2];
        !           240:                        el[2] = singp;
        !           241:                        singp = r[2];
        !           242:                        r[2] = ip;
        !           243:                        csetp -> singcnt++;
        !           244:                }
        !           245:        }
        !           246:        codeon();
        !           247: #      ifdef PC
        !           248:            if ( pairp != NIL ) {
        !           249:                for ( el = pairp ; el[2] != NIL ; el = el[2] ) /* void */;
        !           250:                el[2] = singp;
        !           251:                r[2] = pairp;
        !           252:            } else {
        !           253:                r[2] = singp;
        !           254:            }
        !           255: #      endif PC
        !           256: #      ifdef OBJ
        !           257:            if ( singp != NIL ) {
        !           258:                for ( el = singp ; el[2] != NIL ; el = el[2] ) /* void */;
        !           259:                el[2] = pairp;
        !           260:                r[2] = singp;
        !           261:            } else {
        !           262:                r[2] = pairp;
        !           263:            }
        !           264: #      endif OBJ
        !           265:        if ( csetp -> csettype == NIL ) {
        !           266:            csetp -> comptime = TRUE;
        !           267:        }
        !           268:        return csetp -> comptime;
        !           269: }
        !           270: 
        !           271: #define        BITSPERLONG     ( sizeof( long ) * BITSPERBYTE )
        !           272:     /*
        !           273:      * mask[i] has the low i bits turned off.
        !           274:      */
        !           275: long   mask[] = {      
        !           276:                    0xffffffff , 0xfffffffe , 0xfffffffc , 0xfffffff8 ,
        !           277:                    0xfffffff0 , 0xffffffe0 , 0xffffffc0 , 0xffffff80 ,
        !           278:                    0xffffff00 , 0xfffffe00 , 0xfffffc00 , 0xfffff800 ,
        !           279:                    0xfffff000 , 0xffffe000 , 0xffffc000 , 0xffff8000 ,
        !           280:                    0xffff0000 , 0xfffe0000 , 0xfffc0000 , 0xfff80000 ,
        !           281:                    0xfff00000 , 0xffe00000 , 0xffc00000 , 0xff800000 ,
        !           282:                    0xff000000 , 0xfe000000 , 0xfc000000 , 0xf8000000 ,
        !           283:                    0xf0000000 , 0xe0000000 , 0xc0000000 , 0x80000000 ,
        !           284:                    0x00000000
        !           285:                 };
        !           286:     /*
        !           287:      * given a csetstr, either
        !           288:      *     put out a compile time constant set and an lvalue to it.
        !           289:      * or
        !           290:      *     put out rvalues for the singletons and the pairs
        !           291:      *     and counts of each.
        !           292:      */
        !           293: postcset( r , csetp )
        !           294:     int                        *r;
        !           295:     struct csetstr     *csetp;
        !           296:     {
        !           297:        register int    *el;
        !           298:        register int    *e;
        !           299:        int             lower;
        !           300:        int             upper;
        !           301:        int             lowerdiv;
        !           302:        int             lowermod;
        !           303:        int             upperdiv;
        !           304:        int             uppermod;
        !           305:        int             label;
        !           306:        long            *lp;
        !           307:        long            *limit;
        !           308:        long            tempset[ ( MAXSET / BITSPERLONG ) + 1 ];
        !           309:        long            temp;
        !           310:        char            labelname[ BUFSIZ ];
        !           311: 
        !           312:        if ( csetp -> comptime ) {
        !           313:            setran( ( csetp -> csettype ) -> type );
        !           314:            limit = &tempset[ ( set.uprbp / BITSPERLONG ) + 1 ];
        !           315:            for ( lp = &tempset[0] ; lp < limit ; lp++ ) {
        !           316:                *lp = 0;
        !           317:            }
        !           318:            for ( el = r[2] ; el != NIL ; el = el[2] ) {
        !           319:                e = el[1];
        !           320:                if ( e[0] == T_RANG ) {
        !           321:                    constval( e[1] );
        !           322:                    lower = (long) con.crval;
        !           323:                    constval( e[2] );
        !           324:                    upper = (long) con.crval;
        !           325:                    if ( upper < lower ) {
        !           326:                        continue;
        !           327:                    }
        !           328:                    lowerdiv = ( lower - set.lwrb ) / BITSPERLONG;
        !           329:                    lowermod = ( lower - set.lwrb ) % BITSPERLONG;
        !           330:                    upperdiv = ( upper - set.lwrb ) / BITSPERLONG;
        !           331:                    uppermod = ( upper - set.lwrb ) % BITSPERLONG;
        !           332:                    temp = mask[ lowermod ];
        !           333:                    if ( lowerdiv == upperdiv ) {
        !           334:                        temp &= ~mask[ uppermod + 1 ];
        !           335:                    }
        !           336:                    tempset[ lowerdiv ] |= temp;
        !           337:                    limit = &tempset[ upperdiv-1 ];
        !           338:                    for ( lp = &tempset[ lowerdiv+1 ] ; lp <= limit ; lp++ ) {
        !           339:                        *lp |= ~0;
        !           340:                    }
        !           341:                    if ( lowerdiv != upperdiv ) {
        !           342:                        tempset[ upperdiv ] |= ~mask[ uppermod + 1 ];
        !           343:                    }
        !           344:                } else {
        !           345:                    constval( e );
        !           346:                    lowerdiv = ( ((long)con.crval) - set.lwrb ) / BITSPERLONG;
        !           347:                    lowermod = ( ((long)con.crval) - set.lwrb ) % BITSPERLONG;
        !           348:                    tempset[ lowerdiv ] |= ( 1 << lowermod );
        !           349:                }
        !           350:            }
        !           351:            if ( cgenflg )
        !           352:                return;
        !           353: #          ifdef PC
        !           354:                putprintf( "    .data" , 0 );
        !           355:                putprintf( "    .align 2" , 0 );
        !           356:                label = getlab();
        !           357:                putlab( label );
        !           358:                lp = &( tempset[0] );
        !           359:                limit = &tempset[ ( set.uprbp / BITSPERLONG ) + 1 ];
        !           360:                while ( lp < limit ) {
        !           361:                    putprintf( "        .long   0x%x" , 1 , *lp ++ );
        !           362:                    for ( temp = 2 ; ( temp <= 8 ) && lp < limit ; temp ++ ) {
        !           363:                        putprintf( ",0x%x" , 1 , *lp++ );
        !           364:                    }
        !           365:                    putprintf( "" , 0 );
        !           366:                }
        !           367:                putprintf( "    .text" , 0 );
        !           368:                sprintf( labelname , PREFIXFORMAT , LABELPREFIX , label );
        !           369:                putleaf( P2ICON , 0 , 0 , P2PTR | P2STRTY , labelname );
        !           370: #          endif PC
        !           371: #          ifdef OBJ
        !           372:                put( 2, O_CON, (set.uprbp / BITSPERLONG + 1) *
        !           373:                                 (BITSPERLONG / BITSPERBYTE));
        !           374:                lp = &( tempset[0] );
        !           375:                limit = &tempset[ ( set.uprbp / BITSPERLONG ) + 1 ];
        !           376:                while ( lp < limit ) {
        !           377:                    put( 2, O_CASE4, *lp ++);
        !           378:                }
        !           379: #          endif OBJ
        !           380:        } else {
        !           381: #          ifdef PC
        !           382:                putleaf( P2ICON , csetp -> paircnt , 0 , P2INT , 0 );
        !           383:                putop( P2LISTOP , P2INT );
        !           384:                putleaf( P2ICON , csetp -> singcnt , 0 , P2INT , 0 );
        !           385:                putop( P2LISTOP , P2INT );
        !           386:                for ( el = r[2] ; el != NIL ; el = el[2] ) {
        !           387:                    e = el[1];
        !           388:                    if ( e[0] == T_RANG ) {
        !           389:                        rvalue( e[2] , NIL , RREQ );
        !           390:                        putop( P2LISTOP , P2INT );
        !           391:                        rvalue( e[1] , NIL , RREQ );
        !           392:                        putop( P2LISTOP , P2INT );
        !           393:                    } else {
        !           394:                        rvalue( e , NIL , RREQ );
        !           395:                        putop( P2LISTOP , P2INT );
        !           396:                    }
        !           397:                }
        !           398: #          endif PC
        !           399: #          ifdef OBJ
        !           400:                for ( el = r[2] ; el != NIL ; el = el[2] ) {
        !           401:                    e = el[1];
        !           402:                    if ( e[0] == T_RANG ) {
        !           403:                        stkrval( e[2] , NIL , RREQ );
        !           404:                        stkrval( e[1] , NIL , RREQ );
        !           405:                    } else {
        !           406:                        stkrval( e , NIL , RREQ );
        !           407:                    }
        !           408:                }
        !           409:                put( 2 , O_CON24 , csetp -> singcnt );
        !           410:                put( 2 , O_CON24 , csetp -> paircnt );
        !           411: #          endif OBJ
        !           412:        }
        !           413: }

unix.superglobalmegacorp.com

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