Annotation of 3BSD/cmd/as/asexpr.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) 1979 Regents of the University of California */
                      2: #include <stdio.h>
                      3: #include "as.h"
                      4: #include "asexpr.h"
                      5: 
                      6: /*
                      7:  * Tables for combination of operands.
                      8:  */
                      9: 
                     10: /*
                     11:  *     table for +
                     12:  */
                     13: readonly char pltab[6][6] = {
                     14: /*             UND     ABS     TXT     DAT     BSS     EXT */
                     15: 
                     16: /*UND*/                XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF,
                     17: /*ABS*/                XUNDEF, XABS,   XTEXT,  XDATA,  XBSS,   XXTRN,
                     18: /*TXT*/                XUNDEF, XTEXT,  ERR,    ERR,    ERR,    ERR,
                     19: /*DAT*/                XUNDEF, XDATA,  ERR,    ERR,    ERR,    ERR,
                     20: /*BSS*/                XUNDEF, XBSS,   ERR,    ERR,    ERR,    ERR,
                     21: /*EXT*/                XUNDEF, XXTRN,  ERR,    ERR,    ERR,    ERR,
                     22: };
                     23: 
                     24: /*
                     25:  *     table for -
                     26:  */
                     27: readonly char mintab[6][6] = {
                     28: /*             UND     ABS     TXT     DAT     BSS     EXT */
                     29: 
                     30: /*UND*/                XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF,
                     31: /*ABS*/                XUNDEF, XABS,   ERR,    ERR,    ERR,    ERR,
                     32: /*TXT*/                XUNDEF, XTEXT,  XABS,   ERR,    ERR,    ERR,
                     33: /*DAT*/                XUNDEF, XDATA,  ERR,    XABS,   ERR,    ERR,
                     34: /*BSS*/                XUNDEF, XBSS,   ERR,    ERR,    XABS,   ERR,
                     35: /*EXT*/                XUNDEF, XXTRN,  ERR,    ERR,    ERR,    ERR,
                     36: };
                     37: 
                     38: /* 
                     39:  *     table for other operators
                     40:  */
                     41: readonly char othtab[6][6] = {
                     42: /*             UND     ABS     TXT     DAT     BSS     EXT */
                     43: 
                     44: /*UND*/                XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF,
                     45: /*ABS*/                XUNDEF, XABS,   ERR,    ERR,    ERR,    ERR,
                     46: /*TXT*/                XUNDEF, ERR,    ERR,    ERR,    ERR,    ERR,
                     47: /*DAT*/                XUNDEF, ERR,    ERR,    ERR,    ERR,    ERR,
                     48: /*BSS*/                XUNDEF, ERR,    ERR,    ERR,    ERR,    ERR,
                     49: /*EXT*/                XUNDEF, ERR,    ERR,    ERR,    ERR,    ERR,
                     50: };
                     51: 
                     52: struct exp *
                     53: combine(op, exp1, exp2)
                     54:        register struct exp *exp1, *exp2;
                     55: {
                     56:        register        e1_type, e2_type;
                     57:        register        type;
                     58: 
                     59:        lastnam=0;                      /* kludge for jxxx instructions */
                     60: 
                     61:        e1_type = exp1->xtype&XTYPE;
                     62:        e2_type = exp2->xtype&XTYPE;
                     63: 
                     64:        if (exp1->xtype==XXTRN+XUNDEF)
                     65:                e1_type = XTXRN;
                     66:        if (exp2->xtype==XXTRN+XUNDEF)
                     67:                e2_type = XTXRN;
                     68:        if (passno==1)
                     69:                if (exp1->xloc!=exp2->xloc && e1_type==e2_type)
                     70:                        e1_type = e2_type = XTXRN;      /* error on != loc ctrs */
                     71:        e1_type >>= 1;          /*dispost of the external (XXTRN) bit*/
                     72:        e2_type >>= 1;
                     73: 
                     74:        switch (op) {
                     75:        case PLUS:
                     76:                exp1->xvalue += exp2->xvalue;
                     77:                type = pltab[e1_type][e2_type];
                     78:                break;
                     79:        case MINUS:
                     80:                exp1->xvalue -= exp2->xvalue;
                     81:                type = mintab[e1_type][e2_type];
                     82:                break;
                     83:        case IOR:
                     84:                exp1->xvalue |= exp2->xvalue;
                     85:                goto comm;
                     86:        case XOR:
                     87:                exp1->xvalue ^= exp2->xvalue;
                     88:                goto comm;
                     89:        case AND:
                     90:                exp1->xvalue &= exp2->xvalue;
                     91:                goto comm;
                     92:        case ORNOT:
                     93:                exp1->xvalue |= ~exp2->xvalue;
                     94:                goto comm;
                     95:        case LSH:
                     96:                exp1->xvalue <<= exp2->xvalue;
                     97:                goto comm;
                     98:        case RSH:
                     99:                exp1->xvalue >>= exp2->xvalue;
                    100:                goto comm;
                    101:        case TILDE:
                    102:                exp1->xvalue |= ~ exp2->xvalue;
                    103:                goto comm;
                    104:        case MUL:
                    105:                exp1->xvalue *= exp2->xvalue;
                    106:                goto comm;
                    107:        case DIV:
                    108:                if (exp2->xvalue == 0)
                    109:                        yyerror("Divide check");
                    110:                else
                    111:                        exp1->xvalue /= exp2->xvalue;
                    112:                goto comm;
                    113:        case REGOP:
                    114:                if (exp2->xvalue == 0)
                    115:                        yyerror("Divide check (modulo)");
                    116:                else
                    117:                        exp1->xvalue %= exp2->xvalue;
                    118:                goto comm;
                    119:        
                    120:        comm:
                    121:                type = othtab[e1_type][e2_type];
                    122:                break;
                    123:        default:
                    124:                yyerror("Internal error: unknown operator");
                    125:        }
                    126: 
                    127:        if (e2_type==(XTXRN>>1))
                    128:                exp1->xname = exp2->xname;
                    129:        exp1->xtype = type | (
                    130:                        (exp1->xtype|exp2->xtype) & (XFORW|XXTRN) );
                    131:        if (type==ERR)
                    132:                yyerror("Relocation error");
                    133:        return(exp1);
                    134: }
                    135: 
                    136: buildtokensets()
                    137: {
                    138: #define clobber(val, set) tokensets[(val)] |= (set)
                    139: 
                    140:        clobber(SEMI,   LINSTBEGIN);
                    141:        clobber(NL,     LINSTBEGIN);
                    142: 
                    143:        clobber(NAME,   YUKKYEXPRBEG + LINSTBEGIN);
                    144:        clobber(INSTn,  YUKKYEXPRBEG);
                    145:        clobber(INST0,  YUKKYEXPRBEG);
                    146:        clobber(REG,    YUKKYEXPRBEG);
                    147: 
                    148:        clobber(INT,    SAFEEXPRBEG);
                    149:        clobber(FLTNUM, SAFEEXPRBEG);
                    150: 
                    151:        clobber(PLUS,   ADDOPS);
                    152:        clobber(MINUS,  ADDOPS + EBEGOPS);
                    153: 
                    154:        clobber(LP,     EBEGOPS);
                    155: 
                    156:        clobber(IOR,    BOOLOPS);
                    157:        clobber(XOR,    BOOLOPS);
                    158:        clobber(AND,    BOOLOPS);
                    159:        clobber(ORNOT,  BOOLOPS);
                    160: 
                    161:        clobber(TILDE,  MULOPS + EBEGOPS);
                    162:        clobber(LSH,    MULOPS);
                    163:        clobber(RSH,    MULOPS);
                    164:        clobber(MUL,    MULOPS);
                    165:        clobber(DIV,    MULOPS);
                    166:        clobber(REGOP,  MULOPS);        /* % */
                    167: }
                    168: 
                    169: /*
                    170:  *     We keep the current token class in this global variable, so 
                    171:  *     the recursive descent expression analyzers can talk amongst
                    172:  *     themselves, and so that we may use the macros shift and shift over
                    173:  */
                    174: 
                    175: extern int     yylval;         /*the value of the lexical value*/
                    176: extern struct  exp     *xp;    /*the next free expression slot*/
                    177: 
                    178: static int     val;
                    179: int exprparse(inval, backexpr) /*return the value the read head is sitting on*/
                    180:        int     inval;
                    181:        struct  exp **backexpr;
                    182: {
                    183:        register struct exp *lexpr;
                    184:        int     op;
                    185: 
                    186:        val = inval;
                    187:        lexpr = boolterm();
                    188:        while (INTOKSET(val, ADDOPS)){
                    189:                op = val;
                    190:                shift;
                    191:                lexpr = combine(op, lexpr, boolterm());
                    192:        }
                    193:        *backexpr = lexpr;
                    194:        return(val);
                    195: }
                    196: 
                    197: struct exp *boolterm()
                    198: {
                    199:        register        struct exp *lexpr;
                    200:        int     op;
                    201: 
                    202:        lexpr = term();
                    203:        while(INTOKSET(val, BOOLOPS)){
                    204:                op = val;
                    205:                shift;
                    206:                lexpr = combine(op, lexpr, term());
                    207:        }
                    208:        return(lexpr);
                    209: }
                    210: 
                    211: struct exp *term()
                    212: {
                    213:        register        struct  exp     *lexpr;
                    214:        int             op;
                    215: 
                    216:        lexpr = factor();
                    217:        while(INTOKSET(val, MULOPS)){
                    218:                op = val;
                    219:                shift;
                    220:                lexpr = combine(op, lexpr, factor());
                    221:        }
                    222:        return(lexpr);
                    223: }
                    224: 
                    225: struct exp *factor()
                    226: {
                    227:        struct  exp *lexpr;
                    228:        int             op;
                    229:        extern          int     droppedLP;      /*called exprparse after consuming an LP*/
                    230: 
                    231:        if (val == LP || droppedLP){
                    232:                if (droppedLP)
                    233:                        droppedLP = 0;
                    234:                else
                    235:                        shift;          /*the LP*/
                    236:                val = exprparse(val, &lexpr);
                    237:                if (val != RP)
                    238:                        yyerror("right parenthesis expected");
                    239:                else
                    240:                        shift;
                    241:        } else
                    242:        if (INTOKSET(val, YUKKYEXPRBEG)){
                    243:                lexpr = yukkyexpr(val, yylval);
                    244:                shift;
                    245:        }
                    246:        else if (INTOKSET(val, SAFEEXPRBEG)){
                    247:                lexpr = (struct exp *)yylval;
                    248:                shift;
                    249:        }
                    250:        else if ( (val == TILDE) || (val == MINUS) ){
                    251:                op = val;
                    252:                shift;
                    253:                lexpr = xp++;
                    254:                lexpr->xtype = XABS;
                    255:                lexpr->xvalue = 0;
                    256:                lexpr = combine(op, lexpr, factor());
                    257:        }
                    258:        else {
                    259:                yyerror("Bad expression syntax");
                    260:                lexpr = xp++;
                    261:                lexpr->xtype = XABS;
                    262:                lexpr->xvalue = 0;
                    263:        }
                    264:        return(lexpr);
                    265: }
                    266: 
                    267: struct exp *yukkyexpr(val, np)
                    268:        int     val;
                    269:        register        np;
                    270: {
                    271:        register        struct exp *locxp;
                    272:        extern          int     exprisname;     /*last factor is a name*/
                    273: 
                    274:        exprisname = 0;
                    275:        locxp = xp++;
                    276:        if (val == NAME){
                    277:                exprisname++;
                    278:                locxp->xtype = ((struct symtab *)np)->type;
                    279:                if (( ((struct symtab *)np)->type&XTYPE)==XUNDEF) { /*forward*/
                    280:                        locxp->xname = (struct symtab *)np;
                    281:                        locxp->xvalue = 0;
                    282:                        if (passno==1)
                    283:                                ((struct symtab *)np)->type |= XFORW;
                    284:                } else {        /*otherwise, just get the value*/
                    285:                        locxp->xvalue = ((struct symtab *)np)->value;
                    286:                        locxp->xname = NULL;
                    287:                }
                    288:        } else {        /*INSTn or INST0 or REG*/
                    289:                locxp->xtype = XABS;
                    290:                locxp->xvalue = ( (int)np) & 0xFF;
                    291:                locxp->xloc = 0;
                    292:                locxp->xname = NULL;
                    293:        }
                    294: 
                    295:        return(locxp);
                    296: }

unix.superglobalmegacorp.com

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