Annotation of 41BSD/cmd/as/asexpr.c, revision 1.1

1.1     ! root        1: /* Copyright (c) 1980 Regents of the University of California */
        !             2: static char sccsid[] = "@(#)asexpr.c 4.2 8/15/80";
        !             3: #include <stdio.h>
        !             4: #include "as.h"
        !             5: #include "asexpr.h"
        !             6: 
        !             7: /*
        !             8:  * Tables for combination of operands.
        !             9:  */
        !            10: #define        XTXRN   5<<1            /* indexes last row/column when right shifted */
        !            11: 
        !            12: /*
        !            13:  *     table for +
        !            14:  */
        !            15: readonly char pltab[6][6] = {
        !            16: /*             UND     ABS     TXT     DAT     BSS     EXT */
        !            17: 
        !            18: /*UND*/                XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF,
        !            19: /*ABS*/                XUNDEF, XABS,   XTEXT,  XDATA,  XBSS,   XXTRN,
        !            20: /*TXT*/                XUNDEF, XTEXT,  ERR,    ERR,    ERR,    ERR,
        !            21: /*DAT*/                XUNDEF, XDATA,  ERR,    ERR,    ERR,    ERR,
        !            22: /*BSS*/                XUNDEF, XBSS,   ERR,    ERR,    ERR,    ERR,
        !            23: /*EXT*/                XUNDEF, XXTRN,  ERR,    ERR,    ERR,    ERR,
        !            24: };
        !            25: 
        !            26: /*
        !            27:  *     table for -
        !            28:  */
        !            29: readonly char mintab[6][6] = {
        !            30: /*             UND     ABS     TXT     DAT     BSS     EXT */
        !            31: 
        !            32: /*UND*/                XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF,
        !            33: /*ABS*/                XUNDEF, XABS,   ERR,    ERR,    ERR,    ERR,
        !            34: /*TXT*/                XUNDEF, XTEXT,  XABS,   ERR,    ERR,    ERR,
        !            35: /*DAT*/                XUNDEF, XDATA,  ERR,    XABS,   ERR,    ERR,
        !            36: /*BSS*/                XUNDEF, XBSS,   ERR,    ERR,    XABS,   ERR,
        !            37: /*EXT*/                XUNDEF, XXTRN,  ERR,    ERR,    ERR,    ERR,
        !            38: };
        !            39: 
        !            40: /* 
        !            41:  *     table for other operators
        !            42:  */
        !            43: readonly char othtab[6][6] = {
        !            44: /*             UND     ABS     TXT     DAT     BSS     EXT */
        !            45: 
        !            46: /*UND*/                XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF,
        !            47: /*ABS*/                XUNDEF, XABS,   ERR,    ERR,    ERR,    ERR,
        !            48: /*TXT*/                XUNDEF, ERR,    ERR,    ERR,    ERR,    ERR,
        !            49: /*DAT*/                XUNDEF, ERR,    ERR,    ERR,    ERR,    ERR,
        !            50: /*BSS*/                XUNDEF, ERR,    ERR,    ERR,    ERR,    ERR,
        !            51: /*EXT*/                XUNDEF, ERR,    ERR,    ERR,    ERR,    ERR,
        !            52: };
        !            53: 
        !            54: struct exp *
        !            55: combine(op, exp1, exp2)
        !            56:        register struct exp *exp1, *exp2;
        !            57: {
        !            58:        register        e1_type, e2_type;
        !            59:        register        back_type;
        !            60: 
        !            61:        lastnam=0;                      /* kludge for jxxx instructions */
        !            62: 
        !            63:        e1_type = exp1->e_xtype&XTYPE;
        !            64:        e2_type = exp2->e_xtype&XTYPE;
        !            65: 
        !            66:        if (exp1->e_xtype==XXTRN+XUNDEF)
        !            67:                e1_type = XTXRN;
        !            68:        if (exp2->e_xtype==XXTRN+XUNDEF)
        !            69:                e2_type = XTXRN;
        !            70:        if (passno==1)
        !            71:                if (exp1->e_xloc!=exp2->e_xloc && e1_type==e2_type)
        !            72:                        e1_type = e2_type = XTXRN;      /* error on != loc ctrs */
        !            73:        e1_type >>= 1;          /*dispose of the external (XXTRN) bit*/
        !            74:        e2_type >>= 1;
        !            75: 
        !            76:        switch (op) {
        !            77:        case PLUS:
        !            78:                exp1->e_xvalue += exp2->e_xvalue;
        !            79:                back_type = pltab[e1_type][e2_type];
        !            80:                break;
        !            81:        case MINUS:
        !            82:                exp1->e_xvalue -= exp2->e_xvalue;
        !            83:                back_type = mintab[e1_type][e2_type];
        !            84:                break;
        !            85:        case IOR:
        !            86:                exp1->e_xvalue |= exp2->e_xvalue;
        !            87:                goto comm;
        !            88:        case XOR:
        !            89:                exp1->e_xvalue ^= exp2->e_xvalue;
        !            90:                goto comm;
        !            91:        case AND:
        !            92:                exp1->e_xvalue &= exp2->e_xvalue;
        !            93:                goto comm;
        !            94:        case ORNOT:
        !            95:                exp1->e_xvalue |= ~exp2->e_xvalue;
        !            96:                goto comm;
        !            97:        case LSH:
        !            98:                exp1->e_xvalue <<= exp2->e_xvalue;
        !            99:                goto comm;
        !           100:        case RSH:
        !           101:                exp1->e_xvalue >>= exp2->e_xvalue;
        !           102:                goto comm;
        !           103:        case TILDE:
        !           104:                exp1->e_xvalue |= ~ exp2->e_xvalue;
        !           105:                goto comm;
        !           106:        case MUL:
        !           107:                exp1->e_xvalue *= exp2->e_xvalue;
        !           108:                goto comm;
        !           109:        case DIV:
        !           110:                if (exp2->e_xvalue == 0)
        !           111:                        yyerror("Divide check");
        !           112:                else
        !           113:                        exp1->e_xvalue /= exp2->e_xvalue;
        !           114:                goto comm;
        !           115:        case REGOP:
        !           116:                if (exp2->e_xvalue == 0)
        !           117:                        yyerror("Divide check (modulo)");
        !           118:                else
        !           119:                        exp1->e_xvalue %= exp2->e_xvalue;
        !           120:                goto comm;
        !           121:        
        !           122:        comm:
        !           123:                back_type = othtab[e1_type][e2_type];
        !           124:                break;
        !           125:        default:
        !           126:                yyerror("Internal error: unknown operator");
        !           127:        }
        !           128: 
        !           129:        if (e2_type==(XTXRN>>1))
        !           130:                exp1->e_xname = exp2->e_xname;
        !           131:        exp1->e_xtype = back_type | (
        !           132:                        (exp1->e_xtype|exp2->e_xtype) & (XFORW|XXTRN) );
        !           133:        if (back_type==ERR)
        !           134:                yyerror("Relocation error");
        !           135:        return(exp1);
        !           136: }
        !           137: 
        !           138: buildtokensets()
        !           139: {
        !           140: #define clobber(val, set) tokensets[(val)] |= (set)
        !           141: 
        !           142:        clobber(SEMI,   LINSTBEGIN);
        !           143:        clobber(NL,     LINSTBEGIN);
        !           144:        clobber(INT,    LINSTBEGIN);
        !           145: 
        !           146:        clobber(NAME,   YUKKYEXPRBEG + LINSTBEGIN);
        !           147:        clobber(INSTn,  YUKKYEXPRBEG);
        !           148:        clobber(INST0,  YUKKYEXPRBEG);
        !           149:        clobber(REG,    YUKKYEXPRBEG);
        !           150:        clobber(BFINT,  YUKKYEXPRBEG);
        !           151: 
        !           152:        clobber(INT,    SAFEEXPRBEG);
        !           153:        clobber(FLTNUM, SAFEEXPRBEG);
        !           154: 
        !           155:        clobber(PLUS,   ADDOPS);
        !           156:        clobber(MINUS,  ADDOPS + EBEGOPS);
        !           157: 
        !           158:        clobber(LP,     EBEGOPS);
        !           159: 
        !           160:        clobber(IOR,    BOOLOPS);
        !           161:        clobber(XOR,    BOOLOPS);
        !           162:        clobber(AND,    BOOLOPS);
        !           163:        clobber(ORNOT,  BOOLOPS);
        !           164: 
        !           165:        clobber(TILDE,  MULOPS + EBEGOPS);
        !           166:        clobber(LSH,    MULOPS);
        !           167:        clobber(RSH,    MULOPS);
        !           168:        clobber(MUL,    MULOPS);
        !           169:        clobber(DIV,    MULOPS);
        !           170:        clobber(REGOP,  MULOPS);        /* % */
        !           171: 
        !           172: }
        !           173: 
        !           174: /*
        !           175:  *     We keep the current token class in this global variable, so 
        !           176:  *     the recursive descent expression analyzers can talk amongst
        !           177:  *     themselves, and so that we may use the macros shift and shift over
        !           178:  */
        !           179: 
        !           180: extern int     yylval;         /*the value of the lexical value*/
        !           181: extern struct  exp     *xp;    /*the next free expression slot*/
        !           182: 
        !           183: static int     val;
        !           184: int exprparse(inval, backexpr) /*return the value the read head is sitting on*/
        !           185:        int     inval;
        !           186:        struct  exp **backexpr;
        !           187: {
        !           188:        register struct exp *lexpr;
        !           189:        int     op;
        !           190: 
        !           191:        val = inval;
        !           192:        lexpr = boolterm();
        !           193:        while (INTOKSET(val, ADDOPS)){
        !           194:                op = val;
        !           195:                shift;
        !           196:                lexpr = combine(op, lexpr, boolterm());
        !           197:        }
        !           198:        *backexpr = lexpr;
        !           199:        return(val);
        !           200: }
        !           201: 
        !           202: struct exp *boolterm()
        !           203: {
        !           204:        register        struct exp *lexpr;
        !           205:        int     op;
        !           206: 
        !           207:        lexpr = term();
        !           208:        while(INTOKSET(val, BOOLOPS)){
        !           209:                op = val;
        !           210:                shift;
        !           211:                lexpr = combine(op, lexpr, term());
        !           212:        }
        !           213:        return(lexpr);
        !           214: }
        !           215: 
        !           216: struct exp *term()
        !           217: {
        !           218:        register        struct  exp     *lexpr;
        !           219:        int             op;
        !           220: 
        !           221:        lexpr = factor();
        !           222:        while(INTOKSET(val, MULOPS)){
        !           223:                op = val;
        !           224:                shift;
        !           225:                lexpr = combine(op, lexpr, factor());
        !           226:        }
        !           227:        return(lexpr);
        !           228: }
        !           229: 
        !           230: struct exp *factor()
        !           231: {
        !           232:        struct  exp *lexpr;
        !           233:        int             op;
        !           234:        extern          int     droppedLP;      /*called exprparse after consuming an LP*/
        !           235: 
        !           236:        if (val == LP || droppedLP){
        !           237:                if (droppedLP)
        !           238:                        droppedLP = 0;
        !           239:                else
        !           240:                        shift;          /*the LP*/
        !           241:                val = exprparse(val, &lexpr);
        !           242:                if (val != RP)
        !           243:                        yyerror("right parenthesis expected");
        !           244:                else
        !           245:                        shift;
        !           246:        } else
        !           247:        if (INTOKSET(val, YUKKYEXPRBEG)){
        !           248:                lexpr = yukkyexpr(val, yylval);
        !           249:                shift;
        !           250:        }
        !           251:        else if (INTOKSET(val, SAFEEXPRBEG)){
        !           252:                lexpr = (struct exp *)yylval;
        !           253:                shift;
        !           254:        }
        !           255:        else if ( (val == TILDE) || (val == MINUS) ){
        !           256:                op = val;
        !           257:                shift;
        !           258:                lexpr = xp++;
        !           259:                lexpr->e_xtype = XABS;
        !           260:                lexpr->e_xvalue = 0;
        !           261:                lexpr = combine(op, lexpr, factor());
        !           262:        }
        !           263:        else {
        !           264:                yyerror("Bad expression syntax");
        !           265:                lexpr = xp++;
        !           266:                lexpr->e_xtype = XABS;
        !           267:                lexpr->e_xvalue = 0;
        !           268:        }
        !           269:        return(lexpr);
        !           270: }
        !           271: 
        !           272: struct exp *yukkyexpr(val, np)
        !           273:        int     val;
        !           274:        register        np;
        !           275: {
        !           276:        register        struct exp *locxp;
        !           277:        extern          int     exprisname;     /*last factor is a name*/
        !           278: 
        !           279:        exprisname = 0;
        !           280:        locxp = xp++;
        !           281:        if (val == NAME || val == BFINT){
        !           282:                if (val == BFINT) {
        !           283:                        int off = 0;
        !           284:                        yylval = ((struct exp *)np)->e_xvalue;
        !           285:                        if (yylval < 0) {
        !           286:                                yylval = -yylval;
        !           287:                                yylval--;
        !           288:                                off = -1;
        !           289:                                if (lgensym[yylval] == 1)
        !           290:                                        yyerror("Reference to undefined local label %db", yylval);
        !           291:                        } else {
        !           292:                                yylval--;
        !           293:                                genref[yylval] = 1;
        !           294:                        }
        !           295:                        sprintf(yytext, "L%d\001%d", yylval, lgensym[yylval] + off);
        !           296:                        yylval = np = (int)*lookup(passno == 1);
        !           297:                        lastnam = (struct symtab *)np;
        !           298:                }
        !           299:                exprisname++;
        !           300:                locxp->e_xtype = ((struct symtab *)np)->s_type;
        !           301:                if (( ((struct symtab *)np)->s_type&XTYPE)==XUNDEF) { /*forward*/
        !           302:                        locxp->e_xname = (struct symtab *)np;
        !           303:                        locxp->e_xvalue = 0;
        !           304:                        if (passno==1)
        !           305:                                ((struct symtab *)np)->s_type |= XFORW;
        !           306:                } else {        /*otherwise, just get the value*/
        !           307:                        locxp->e_xvalue = ((struct symtab *)np)->s_value;
        !           308:                        locxp->e_xname = NULL;
        !           309:                }
        !           310:        } else {        /*INSTn or INST0 or REG*/
        !           311:                locxp->e_xtype = XABS;
        !           312:                locxp->e_xvalue = ( (int)np) & 0xFF;
        !           313:                locxp->e_xloc = 0;
        !           314:                locxp->e_xname = NULL;
        !           315:        }
        !           316: 
        !           317:        return(locxp);
        !           318: }
        !           319: 
        !           320: 
        !           321: #ifdef DEBUG
        !           322: char   *tok_name[LASTTOKEN - FIRSTTOKEN + 1];
        !           323: struct Tok_Desc{
        !           324:        int             tok_which;
        !           325:        char            *tok_name;
        !           326: } tok_desc[] = {
        !           327:        FIRSTTOKEN,     "firsttoken",   /* 0 */
        !           328:        ISPACE,         "ispace",       /* 1 */
        !           329:        IBYTE,          "ibyte",        /* 2 */
        !           330:        IWORD,          "iword",        /* 3 */
        !           331:        IINT,           "iint",         /* 4 */
        !           332:        ILONG,          "ilong",        /* 5 */
        !           333:        IDATA,          "idata",        /* 6 */
        !           334:        IGLOBAL,        "iglobal",      /* 7 */
        !           335:        ISET,           "iset",         /* 8 */
        !           336:        ITEXT,          "itext",        /* 9 */
        !           337:        ICOMM,          "icomm",        /* 10 */
        !           338:        ILCOMM,         "ilcomm",       /* 11 */
        !           339:        IFLOAT,         "ifloat",       /* 12 */
        !           340:        IDOUBLE,        "idouble",      /* 13 */
        !           341:        IORG,           "iorg",         /* 14 */
        !           342:        IASCII,         "iascii",       /* 15 */
        !           343:        IASCIZ,         "iasciz",       /* 16 */
        !           344:        ILSYM,          "ilsym",        /* 17 */
        !           345:        IFILE,          "ifile",        /* 18 */
        !           346:        ILINENO,        "ilineno",      /* 19 */
        !           347:        IABORT,         "iabort",       /* 20 */
        !           348:        ISTAB,          "istab",        /* 23 */
        !           349:        ISTABSTR,       "istabstr",     /* 24 */
        !           350:        ISTABNONE,      "istabnone",    /* 25 */
        !           351:        ISTABDOT,       "istabdot",     /* 26 */
        !           352:        IJXXX,          "ijxxx",        /* 27 */
        !           353:        IALIGN,         "ialign",       /* 28 */
        !           354:        INST0,          "inst0",        /* 29 */
        !           355:        INSTn,          "instn",        /* 30 */
        !           356:        BFINT,          "bfint",        /* 31 */
        !           357:        PARSEEOF,       "parseeof",     /* 32 */
        !           358:        ILINESKIP,      "ilineskip",    /* 33 */
        !           359:        VOID,           "void",         /* 34 */
        !           360:        SKIP,           "skip",         /* 35 */
        !           361:        INT,            "int",          /* 36 */
        !           362:        FLTNUM,         "fltnum",       /* 37 */
        !           363:        NAME,           "name",         /* 38 */
        !           364:        STRING,         "string",       /* 39 */
        !           365:        QUAD,           "quad",         /* 40 */
        !           366:        SIZESPEC,       "sizespec",     /* 41 */
        !           367:        REG,            "reg",          /* 42 */
        !           368:        MUL,            "mul",          /* 43 */
        !           369:        LITOP,          "litop",        /* 44 */
        !           370:        LP,             "lp",           /* 45 */
        !           371:        MP,             "mp",           /* 46 */
        !           372:        NEEDSBUF,       "needsbuf",     /* 48 */        
        !           373:        REGOP,          "regop",        /* 49 */
        !           374:        NL,             "nl",           /* 50 */
        !           375:        SCANEOF,        "scaneof",      /* 51 */
        !           376:        BADCHAR,        "badchar",      /* 52 */
        !           377:        SP,             "sp",           /* 53 */
        !           378:        ALPH,           "alph",         /* 54 */
        !           379:        DIG,            "dig",          /* 55 */
        !           380:        SQ,             "sq",           /* 56 */
        !           381:        DQ,             "dq",           /* 57 */
        !           382:        SH,             "sh",           /* 58 */
        !           383:        LSH,            "lsh",          /* 59 */
        !           384:        RSH,            "rsh",          /* 60 */
        !           385:        MINUS,          "minus",        /* 61 */
        !           386:        SIZEQUOTE,      "sizequote",    /* 62 */
        !           387:        XOR,            "xor",          /* 64 */
        !           388:        DIV,            "div",          /* 65 */
        !           389:        SEMI,           "semi",         /* 66 */
        !           390:        COLON,          "colon",        /* 67 */
        !           391:        PLUS,           "plus",         /* 68 */
        !           392:        IOR,            "ior",          /* 69 */ 
        !           393:        AND,            "and",          /* 70 */
        !           394:        TILDE,          "tilde",        /* 71 */
        !           395:        ORNOT,          "ornot",        /* 72 */
        !           396:        CM,             "cm",           /* 73 */
        !           397:        LB,             "lb",           /* 74 */
        !           398:        RB,             "rb",           /* 75 */
        !           399:        RP,             "rp",           /* 76 */
        !           400:        LASTTOKEN,      "lasttoken"     /* 80 */
        !           401: };
        !           402: /*
        !           403:  *     turn a token type into a string
        !           404:  */
        !           405: static int     fixed = 0;
        !           406: char *tok_to_name(token)
        !           407: {
        !           408:        if (!fixed){
        !           409:                int     i;
        !           410:                for (i = FIRSTTOKEN; i <= LASTTOKEN; i++)
        !           411:                        tok_name[i] = "NOT ASSIGNED";
        !           412:                for (i = FIRSTTOKEN; i <= sizeof(tok_desc)/sizeof(struct Tok_Desc); i++){
        !           413:                        tok_name[tok_desc[i].tok_which] = tok_desc[i].tok_name;
        !           414:                }
        !           415:                fixed = 1;
        !           416:        }
        !           417:        if (FIRSTTOKEN <= token && token <= LASTTOKEN)
        !           418:                return(tok_name[token]);
        !           419:        else
        !           420:                panic("Unknown token number, %d\n", token);
        !           421:        /*NOTREACHED*/
        !           422: }
        !           423: #endif DEBUG

unix.superglobalmegacorp.com

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