Annotation of 41BSD/cmd/pi/cset.c, revision 1.1.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.