Annotation of 43BSD/ucb/pascal/src/var.c, revision 1.1.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[] = "@(#)var.c      5.2 (Berkeley) 7/26/85";
                      9: #endif not lint
                     10: 
                     11: #include "whoami.h"
                     12: #include "0.h"
                     13: #include "objfmt.h"
                     14: #include "align.h"
                     15: #include "iorec.h"
                     16: #ifdef PC
                     17: #   include    "pc.h"
                     18: #endif PC
                     19: #include "tmps.h"
                     20: #include "tree_ty.h"
                     21: 
                     22: /*
                     23:  * Declare variables of a var part.  DPOFF1 is
                     24:  * the local variable storage for all prog/proc/func
                     25:  * modules aside from the block mark.  The total size
                     26:  * of all the local variables is entered into the
                     27:  * size array.
                     28:  */
                     29: /*ARGSUSED*/
                     30: varbeg( lineofyvar , r )
                     31:     int        lineofyvar;
                     32: {
                     33:     static bool        var_order = FALSE;
                     34:     static bool        var_seen = FALSE;
                     35: 
                     36: /* this allows for multiple declaration
                     37:  * parts except when the "standard"
                     38:  * option has been specified.
                     39:  * If routine segment is being compiled,
                     40:  * do level one processing.
                     41:  */
                     42: 
                     43: #ifndef PI1
                     44:        if (!progseen)
                     45:                level1();
                     46:        line = lineofyvar;
                     47:        if ( parts[ cbn ] & RPRT ) {
                     48:            if ( opt( 's' ) ) {
                     49:                standard();
                     50:                error("Variable declarations should precede routine declarations");
                     51:            } else {
                     52:                if ( !var_order ) {
                     53:                    var_order = TRUE;
                     54:                    warning();
                     55:                    error("Variable declarations should precede routine declarations");
                     56:                }
                     57:            }
                     58:        }
                     59:        if ( parts[ cbn ] & VPRT ) {
                     60:            if ( opt( 's' ) ) {
                     61:                standard();
                     62:                error("All variables should be declared in one var part");
                     63:            } else {
                     64:                if ( !var_seen ) {
                     65:                    var_seen = TRUE;
                     66:                    warning();
                     67:                    error("All variables should be declared in one var part");
                     68:                }
                     69:            }
                     70:        }
                     71:        parts[ cbn ] |= VPRT;
                     72: #endif
                     73:     /*
                     74:      *  #ifndef PI0
                     75:      *      sizes[cbn].om_max = sizes[cbn].curtmps.om_off = -DPOFF1;
                     76:      *  #endif
                     77:      */
                     78:        forechain = NIL;
                     79: #ifdef PI0
                     80:        send(REVVBEG);
                     81: #endif
                     82: }
                     83: 
                     84: var(vline, vidl, vtype)
                     85: #ifdef PI0
                     86:        int vline;
                     87:        struct tnode *vidl, *vtype;
                     88: {
                     89:        register struct nl *np;
                     90:        register struct tnode *vl;
                     91: 
                     92:        np = gtype(vtype);
                     93:        line = vline;
                     94:        /* why is this here? */
                     95:        for (vl = vidl; vl != TR_NIL; vl = vl->list_node.next) {
                     96:                }
                     97:        }
                     98:        send(REVVAR, vline, vidl, vtype);
                     99: }
                    100: #else
                    101:        int vline;
                    102:        register struct tnode *vidl;
                    103:        struct tnode *vtype;
                    104: {
                    105:        register struct nl *np;
                    106:        register struct om *op;
                    107:        long w;
                    108:        int o2;
                    109: #ifdef PC
                    110:        struct nl       *vp;
                    111: #endif
                    112: 
                    113:        np = gtype(vtype);
                    114:        line = vline;
                    115:        w = lwidth(np);
                    116:        op = &sizes[cbn];
                    117:        for (; vidl != TR_NIL; vidl = vidl->list_node.next) {
                    118: #              ifdef OBJ
                    119:                    op->curtmps.om_off =
                    120:                        roundup((int)(op->curtmps.om_off-w), (long)align(np));
                    121:                    o2 = op -> curtmps.om_off;
                    122: #              endif OBJ
                    123: #              ifdef PC
                    124:                    if ( cbn == 1 ) {
                    125:                                /*
                    126:                                 * global variables are not accessed off the fp
                    127:                                 * but rather by their names.
                    128:                                 */
                    129:                            o2 = 0;
                    130:                    } else {
                    131:                                /*
                    132:                                 * locals are aligned, too.
                    133:                                 */
                    134:                            op->curtmps.om_off =
                    135:                                roundup((int)(op->curtmps.om_off - w),
                    136:                                (long)align(np));
                    137:                            o2 = op -> curtmps.om_off;
                    138:                    }
                    139: #              endif PC
                    140: #              ifdef PC
                    141:                vp = enter(defnl((char *) vidl->list_node.list, VAR, np, o2));
                    142: #              else
                    143:                (void) enter(defnl((char *) vidl->list_node.list, VAR, np, o2));
                    144: #              endif
                    145:                if ( np != NLNIL && (np -> nl_flags & NFILES) ) {
                    146:                    dfiles[ cbn ] = TRUE;
                    147:                }
                    148: #              ifdef PC
                    149:                    if ( cbn == 1 ) {
                    150:                        putprintf( "    .data" , 0 );
                    151:                        aligndot(align(np));
                    152:                        putprintf( "    .comm   " , 1 );
                    153:                        putprintf( EXTFORMAT , 1 , (int) vidl->list_node.list );
                    154:                        putprintf( ",%d" , 0 , (int) w );
                    155:                        putprintf( "    .text" , 0 );
                    156:                        stabgvar( vp , w , line );
                    157:                        vp -> extra_flags |= NGLOBAL;
                    158:                    } else {
                    159:                        vp -> extra_flags |= NLOCAL;
                    160:                    }
                    161: #              endif PC
                    162:        }
                    163: #      ifdef PTREE
                    164:            {
                    165:                pPointer        *Vars;
                    166:                pPointer        Var = VarDecl( ovidl , vtype );
                    167: 
                    168:                pSeize( PorFHeader[ nesting ] );
                    169:                Vars = &( pDEF( PorFHeader[ nesting ] ).PorFVars );
                    170:                *Vars = ListAppend( *Vars , Var );
                    171:                pRelease( PorFHeader[ nesting ] );
                    172:            }
                    173: #      endif
                    174: }
                    175: #endif
                    176: 
                    177: varend()
                    178: {
                    179: 
                    180:        foredecl();
                    181: #ifndef PI0
                    182:        sizes[cbn].om_max = sizes[cbn].curtmps.om_off;
                    183: #else
                    184:        send(REVVEND);
                    185: #endif
                    186: }
                    187: 
                    188: /*
                    189:  * Evening
                    190:  */
                    191: long
                    192: leven(w)
                    193:        register long w;
                    194: {
                    195:        if (w < 0)
                    196:                return (w & 0xfffffffe);
                    197:        return ((w+1) & 0xfffffffe);
                    198: }
                    199: 
                    200: #ifndef PC
                    201: int
                    202: even(w)
                    203:        register int w;
                    204: {
                    205:        return leven((long)w);
                    206: }
                    207: #endif
                    208: 
                    209: /*
                    210:  * Find the width of a type in bytes.
                    211:  */
                    212: width(np)
                    213:        struct nl *np;
                    214: {
                    215: 
                    216:        return (lwidth(np));
                    217: }
                    218: 
                    219: long
                    220: lwidth(np)
                    221:        struct nl *np;
                    222: {
                    223:        register struct nl *p;
                    224: 
                    225:        p = np;
                    226:        if (p == NIL)
                    227:                return (0);
                    228: loop:
                    229:        switch (p->class) {
                    230:                default:
                    231:                        panic("wclass");
                    232:                case TYPE:
                    233:                        switch (nloff(p)) {
                    234:                                case TNIL:
                    235:                                        return (2);
                    236:                                case TSTR:
                    237:                                case TSET:
                    238:                                        panic("width");
                    239:                                default:
                    240:                                        p = p->type;
                    241:                                        goto loop;
                    242:                        }
                    243:                case ARRAY:
                    244:                        return (aryconst(p, 0));
                    245:                case PTR:
                    246:                        return ( sizeof ( int * ) );
                    247:                case FILET:
                    248:                        return ( sizeof(struct iorec) + lwidth( p -> type ) );
                    249:                case CRANGE:
                    250:                        p = p->type;
                    251:                        goto loop;
                    252:                case RANGE:
                    253:                        if (p->type == nl+TDOUBLE)
                    254: #ifdef DEBUG
                    255:                                return (hp21mx ? 4 : 8);
                    256: #else
                    257:                                return (8);
                    258: #endif
                    259:                case SCAL:
                    260:                        return (bytes(p->range[0], p->range[1]));
                    261:                case SET:
                    262:                        setran(p->type);
                    263:                        /*
                    264:                         * Sets are some multiple of longs
                    265:                         */
                    266:                        return roundup((int)((set.uprbp >> 3) + 1),
                    267:                                (long)(sizeof(long)));
                    268:                case STR:
                    269:                case RECORD:
                    270:                        return ( p->value[NL_OFFS] );
                    271:        }
                    272: }
                    273: 
                    274:     /*
                    275:      * round up x to a multiple of y
                    276:      * for computing offsets of aligned things.
                    277:      * y had better be positive.
                    278:      * rounding is in the direction of x.
                    279:      */
                    280: long
                    281: roundup( x , y )
                    282:     int                        x;
                    283:     register long      y;
                    284:     {
                    285:        
                    286:        if ( y == 0 ) {
                    287:            return x;
                    288:        }
                    289:        if ( x >= 0 ) {
                    290:                return ( ( ( x + ( y - 1 ) ) / y ) * y );
                    291:        } else {
                    292:                return ( ( ( x - ( y - 1 ) ) / y ) * y );
                    293:        }
                    294:     }
                    295: 
                    296:     /*
                    297:      * alignment of an object using the c alignment scheme
                    298:      */
                    299: int
                    300: align( np )
                    301:     struct nl  *np;
                    302:     {
                    303:        register struct nl *p;
                    304:        long elementalign;
                    305: 
                    306:        p = np;
                    307:        if ( p == NIL ) {
                    308:            return 0;
                    309:        }
                    310: alignit:
                    311:        switch ( p -> class ) {
                    312:            default:
                    313:                    panic( "align" );
                    314:            case TYPE:
                    315:                    switch ( nloff( p ) ) {
                    316:                        case TNIL:
                    317:                                return A_POINT;
                    318:                        case TSTR:
                    319:                                return A_STRUCT;
                    320:                        case TSET:
                    321:                                return A_SET;
                    322:                        default:
                    323:                                p = p -> type;
                    324:                                goto alignit;
                    325:                    }
                    326:            case ARRAY:
                    327:                        /*
                    328:                         * arrays are structures, since they can get
                    329:                         * assigned form/to as structure assignments.
                    330:                         * preserve internal alignment if it is greater.
                    331:                         */
                    332:                    elementalign = align(p -> type);
                    333:                    return elementalign > A_STRUCT ? elementalign : A_STRUCT;
                    334:            case PTR:
                    335:                    return A_POINT;
                    336:            case FILET:
                    337:                    return A_FILET;
                    338:            case CRANGE:
                    339:            case RANGE:
                    340:                    if ( p -> type == nl+TDOUBLE ) {
                    341:                        return A_DOUBLE;
                    342:                    }
                    343:                    /* else, fall through */
                    344:            case SCAL:
                    345:                    switch ( bytes( p -> range[0] , p -> range[1] ) ) {
                    346:                        case 4:
                    347:                            return A_LONG;
                    348:                        case 2:
                    349:                            return A_SHORT;
                    350:                        case 1:
                    351:                            return A_CHAR;
                    352:                        default:
                    353:                            panic( "align: scal" );
                    354:                    }
                    355:            case SET:
                    356:                    return A_SET;
                    357:            case STR:
                    358:                        /*
                    359:                         * arrays of chars are structs
                    360:                         */
                    361:                    return A_STRUCT;
                    362:            case RECORD:
                    363:                        /*
                    364:                         * the alignment of a record is in its align_info field
                    365:                         * why don't we use this for the rest of the namelist?
                    366:                         */
                    367:                    return p -> align_info;
                    368:        }
                    369:     }
                    370: 
                    371: #ifdef PC
                    372:     /*
                    373:      * output an alignment pseudo-op.
                    374:      */
                    375: aligndot(alignment)
                    376:     int        alignment;
                    377: #ifdef vax
                    378: {
                    379:     switch (alignment) {
                    380:        case 1:
                    381:            return;
                    382:        case 2:
                    383:            putprintf(" .align 1", 0);
                    384:            return;
                    385:        default:
                    386:        case 4:
                    387:            putprintf(" .align 2", 0);
                    388:            return;
                    389:     }
                    390: }
                    391: #endif vax
                    392: #ifdef mc68000
                    393: {
                    394:     switch (alignment) {
                    395:        case 1:
                    396:            return;
                    397:        default:
                    398:            putprintf(" .even", 0);
                    399:            return;
                    400:     }
                    401: }
                    402: #endif mc68000
                    403: #endif PC
                    404:     
                    405: /*
                    406:  * Return the width of an element
                    407:  * of a n time subscripted np.
                    408:  */
                    409: long aryconst(np, n)
                    410:        struct nl *np;
                    411:        int n;
                    412: {
                    413:        register struct nl *p;
                    414:        long s, d;
                    415: 
                    416:        if ((p = np) == NIL)
                    417:                return (NIL);
                    418:        if (p->class != ARRAY)
                    419:                panic("ary");
                    420:        /*
                    421:         * If it is a conformant array, we cannot find the width from
                    422:         * the type.
                    423:         */
                    424:        if (p->chain->class == CRANGE)
                    425:                return (NIL);
                    426:        s = lwidth(p->type);
                    427:        /*
                    428:         * Arrays of anything but characters are word aligned.
                    429:         */
                    430:        if (s & 1)
                    431:                if (s != 1)
                    432:                        s++;
                    433:        /*
                    434:         * Skip the first n subscripts
                    435:         */
                    436:        while (n >= 0) {
                    437:                p = p->chain;
                    438:                n--;
                    439:        }
                    440:        /*
                    441:         * Sum across remaining subscripts.
                    442:         */
                    443:        while (p != NIL) {
                    444:                if (p->class != RANGE && p->class != SCAL)
                    445:                        panic("aryran");
                    446:                d = p->range[1] - p->range[0] + 1;
                    447:                s *= d;
                    448:                p = p->chain;
                    449:        }
                    450:        return (s);
                    451: }
                    452: 
                    453: /*
                    454:  * Find the lower bound of a set, and also its size in bits.
                    455:  */
                    456: setran(q)
                    457:        struct nl *q;
                    458: {
                    459:        register lb, ub;
                    460:        register struct nl *p;
                    461: 
                    462:        p = q;
                    463:        if (p == NIL)
                    464:                return;
                    465:        lb = p->range[0];
                    466:        ub = p->range[1];
                    467:        if (p->class != RANGE && p->class != SCAL)
                    468:                panic("setran");
                    469:        set.lwrb = lb;
                    470:        /* set.(upperbound prime) = number of bits - 1; */
                    471:        set.uprbp = ub-lb;
                    472: }
                    473: 
                    474: /*
                    475:  * Return the number of bytes required to hold an arithmetic quantity
                    476:  */
                    477: bytes(lb, ub)
                    478:        long lb, ub;
                    479: {
                    480: 
                    481: #ifndef DEBUG
                    482:        if (lb < -32768 || ub > 32767)
                    483:                return (4);
                    484:        else if (lb < -128 || ub > 127)
                    485:                return (2);
                    486: #else
                    487:        if (!hp21mx && (lb < -32768 || ub > 32767))
                    488:                return (4);
                    489:        if (lb < -128 || ub > 127)
                    490:                return (2);
                    491: #endif
                    492:        else
                    493:                return (1);
                    494: }

unix.superglobalmegacorp.com

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