Annotation of 43BSDReno/pgrm/pascal/src/cset.c, revision 1.1

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

unix.superglobalmegacorp.com

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