Annotation of 42BSD/bin/as/asexpr.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *     Copyright (c) 1982 Regents of the University of California
        !             3:  */
        !             4: #ifndef lint
        !             5: static char sccsid[] = "@(#)asexpr.c 4.5 6/30/83";
        !             6: 
        !             7: #endif not lint
        !             8: #include <stdio.h>
        !             9: #include "as.h"
        !            10: #include "asscan.h"
        !            11: #include "asexpr.h"
        !            12: 
        !            13: /*
        !            14:  * Tables for combination of operands.
        !            15:  */
        !            16: #define        XTXRN   5<<1            /* indexes last row/column when right shifted */
        !            17: 
        !            18: /*
        !            19:  *     table for +
        !            20:  */
        !            21: readonly char pltab[6][6] = {
        !            22: /*             UND     ABS     TXT     DAT     BSS     EXT */
        !            23: 
        !            24: /*UND*/                XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF,
        !            25: /*ABS*/                XUNDEF, XABS,   XTEXT,  XDATA,  XBSS,   XXTRN,
        !            26: /*TXT*/                XUNDEF, XTEXT,  ERR,    ERR,    ERR,    ERR,
        !            27: /*DAT*/                XUNDEF, XDATA,  ERR,    ERR,    ERR,    ERR,
        !            28: /*BSS*/                XUNDEF, XBSS,   ERR,    ERR,    ERR,    ERR,
        !            29: /*EXT*/                XUNDEF, XXTRN,  ERR,    ERR,    ERR,    ERR,
        !            30: };
        !            31: 
        !            32: /*
        !            33:  *     table for -
        !            34:  */
        !            35: readonly char mintab[6][6] = {
        !            36: /*             UND     ABS     TXT     DAT     BSS     EXT */
        !            37: 
        !            38: /*UND*/                XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF,
        !            39: /*ABS*/                XUNDEF, XABS,   ERR,    ERR,    ERR,    ERR,
        !            40: /*TXT*/                XUNDEF, XTEXT,  XABS,   ERR,    ERR,    ERR,
        !            41: /*DAT*/                XUNDEF, XDATA,  ERR,    XABS,   ERR,    ERR,
        !            42: /*BSS*/                XUNDEF, XBSS,   ERR,    ERR,    XABS,   ERR,
        !            43: /*EXT*/                XUNDEF, XXTRN,  ERR,    ERR,    ERR,    ERR,
        !            44: };
        !            45: 
        !            46: /* 
        !            47:  *     table for other operators
        !            48:  */
        !            49: readonly char othtab[6][6] = {
        !            50: /*             UND     ABS     TXT     DAT     BSS     EXT */
        !            51: 
        !            52: /*UND*/                XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF,
        !            53: /*ABS*/                XUNDEF, XABS,   ERR,    ERR,    ERR,    ERR,
        !            54: /*TXT*/                XUNDEF, ERR,    ERR,    ERR,    ERR,    ERR,
        !            55: /*DAT*/                XUNDEF, ERR,    ERR,    ERR,    ERR,    ERR,
        !            56: /*BSS*/                XUNDEF, ERR,    ERR,    ERR,    ERR,    ERR,
        !            57: /*EXT*/                XUNDEF, ERR,    ERR,    ERR,    ERR,    ERR,
        !            58: };
        !            59: 
        !            60: struct exp *combine(op, exp1, exp2)
        !            61:        reg struct exp *exp1, *exp2;
        !            62: {
        !            63:        reg     e1_type, e2_type;
        !            64:        reg     back_type;
        !            65:        char    *btype = "The assembler can only do arithmetic on 1,2, or 4 byte integers";
        !            66: 
        !            67:        lastnam=0;                      /* kludge for jxxx instructions */
        !            68: 
        !            69:        e1_type = exp1->e_xtype&XTYPE;
        !            70:        e2_type = exp2->e_xtype&XTYPE;
        !            71: 
        !            72:        if (exp1->e_xtype==XXTRN+XUNDEF)
        !            73:                e1_type = XTXRN;
        !            74:        if (exp2->e_xtype==XXTRN+XUNDEF)
        !            75:                e2_type = XTXRN;
        !            76:        if (passno==1)
        !            77:                if (exp1->e_xloc!=exp2->e_xloc && e1_type==e2_type)
        !            78:                        e1_type = e2_type = XTXRN;      /* error on != loc ctrs */
        !            79:        e1_type >>= 1;          /*dispose of the external (XXTRN) bit*/
        !            80:        e2_type >>= 1;
        !            81: 
        !            82:        switch(exp1->e_number.num_tag){
        !            83:        case TYPB:
        !            84:        case TYPW:
        !            85:        case TYPL:
        !            86:                break;
        !            87:        default:
        !            88:                yyerror(btype);
        !            89:                return(exp1);
        !            90:        }
        !            91:        switch(exp2->e_number.num_tag){
        !            92:        case TYPB:
        !            93:        case TYPW:
        !            94:        case TYPL:
        !            95:                break;
        !            96:        default:
        !            97:                yyerror(btype);
        !            98:                return(exp1);
        !            99:        }
        !           100:        switch (op){
        !           101:        case PLUS:
        !           102:                exp1->e_xvalue += exp2->e_xvalue;
        !           103:                back_type = pltab[e1_type][e2_type];
        !           104:                break;
        !           105:        case MINUS:
        !           106:                exp1->e_xvalue -= exp2->e_xvalue;
        !           107:                back_type = mintab[e1_type][e2_type];
        !           108:                break;
        !           109:        case IOR:
        !           110:                exp1->e_xvalue |= exp2->e_xvalue;
        !           111:                goto comm;
        !           112:        case XOR:
        !           113:                exp1->e_xvalue ^= exp2->e_xvalue;
        !           114:                goto comm;
        !           115:        case AND:
        !           116:                exp1->e_xvalue &= exp2->e_xvalue;
        !           117:                goto comm;
        !           118:        case ORNOT:
        !           119:                exp1->e_xvalue |= ~exp2->e_xvalue;
        !           120:                goto comm;
        !           121:        case LSH:
        !           122:                exp1->e_xvalue <<= exp2->e_xvalue;
        !           123:                goto comm;
        !           124:        case RSH:
        !           125:                exp1->e_xvalue >>= exp2->e_xvalue;
        !           126:                goto comm;
        !           127:        case TILDE:
        !           128:                exp1->e_xvalue |= ~ exp2->e_xvalue;
        !           129:                goto comm;
        !           130:        case MUL:
        !           131:                exp1->e_xvalue *= exp2->e_xvalue;
        !           132:                goto comm;
        !           133:        case DIV:
        !           134:                if (exp2->e_xvalue == 0)
        !           135:                        yyerror("Divide check");
        !           136:                else
        !           137:                        exp1->e_xvalue /= exp2->e_xvalue;
        !           138:                goto comm;
        !           139:        case REGOP:
        !           140:                if (exp2->e_xvalue == 0)
        !           141:                        yyerror("Divide check (modulo)");
        !           142:                else
        !           143:                        exp1->e_xvalue %= exp2->e_xvalue;
        !           144:                goto comm;
        !           145:        
        !           146:        comm:
        !           147:                back_type = othtab[e1_type][e2_type];
        !           148:                break;
        !           149:        default:
        !           150:                yyerror("Internal error: unknown operator");
        !           151:        }
        !           152: 
        !           153:        if (e2_type==(XTXRN>>1))
        !           154:                exp1->e_xname = exp2->e_xname;
        !           155:        exp1->e_xtype = back_type | (
        !           156:                        (exp1->e_xtype|exp2->e_xtype) & (XFORW|XXTRN) );
        !           157:        if (back_type==ERR)
        !           158:                yyerror("Relocation error");
        !           159:        return(exp1);
        !           160: }
        !           161: 
        !           162: buildtokensets()
        !           163: {
        !           164: #define clobber(val, set) tokensets[(val)] |= (set)
        !           165: 
        !           166:        clobber(SEMI,   LINSTBEGIN);
        !           167:        clobber(NL,     LINSTBEGIN);
        !           168:        clobber(INT,    LINSTBEGIN);
        !           169: 
        !           170:        clobber(NAME,   YUKKYEXPRBEG + LINSTBEGIN);
        !           171:        clobber(INSTn,  YUKKYEXPRBEG);
        !           172:        clobber(INST0,  YUKKYEXPRBEG);
        !           173:        clobber(REG,    YUKKYEXPRBEG);
        !           174:        clobber(BFINT,  YUKKYEXPRBEG);
        !           175: 
        !           176:        clobber(INT,    SAFEEXPRBEG);
        !           177:        clobber(BIGNUM, SAFEEXPRBEG);
        !           178: 
        !           179:        clobber(PLUS,   ADDOPS);
        !           180:        clobber(MINUS,  ADDOPS + EBEGOPS);
        !           181: 
        !           182:        clobber(LP,     EBEGOPS);
        !           183: 
        !           184:        clobber(IOR,    BOOLOPS);
        !           185:        clobber(XOR,    BOOLOPS);
        !           186:        clobber(AND,    BOOLOPS);
        !           187:        clobber(ORNOT,  BOOLOPS);
        !           188: 
        !           189:        clobber(TILDE,  MULOPS + EBEGOPS);
        !           190:        clobber(LSH,    MULOPS);
        !           191:        clobber(RSH,    MULOPS);
        !           192:        clobber(MUL,    MULOPS);
        !           193:        clobber(DIV,    MULOPS);
        !           194:        clobber(REGOP,  MULOPS);        /* % */
        !           195: 
        !           196: }
        !           197: 
        !           198: /*
        !           199:  *     We keep the current token class in this global variable, so 
        !           200:  *     the recursive descent expression analyzers can talk amongst
        !           201:  *     themselves, and so that we may use the macros shift and shift over
        !           202:  */
        !           203: 
        !           204: extern int     yylval;         /*the value of the lexical value*/
        !           205: extern struct  exp     *xp;    /*the next free expression slot*/
        !           206: 
        !           207: static inttoktype      val;
        !           208: 
        !           209: /*
        !           210:  *     return the value the read head is sitting on
        !           211:  */
        !           212: inttoktype exprparse(inval, backexpr)
        !           213:        inttoktype      inval;
        !           214:        struct  exp **backexpr;
        !           215: {
        !           216:        reg     struct exp *lexpr;
        !           217:        inttoktype      op;
        !           218: 
        !           219:        val = inval;
        !           220:        lexpr = boolterm();
        !           221:        while (INTOKSET(val, ADDOPS)){
        !           222:                op = val;
        !           223:                shift;
        !           224:                lexpr = combine(op, lexpr, boolterm());
        !           225:        }
        !           226:        *backexpr = lexpr;
        !           227:        return(val);
        !           228: }
        !           229: 
        !           230: struct exp *boolterm()
        !           231: {
        !           232:        reg     struct exp *lexpr;
        !           233:        inttoktype      op;
        !           234: 
        !           235:        lexpr = term();
        !           236:        while(INTOKSET(val, BOOLOPS)){
        !           237:                op = val;
        !           238:                shift;
        !           239:                lexpr = combine(op, lexpr, term());
        !           240:        }
        !           241:        return(lexpr);
        !           242: }
        !           243: 
        !           244: struct exp *term()
        !           245: {
        !           246:        reg     struct  exp     *lexpr;
        !           247:        inttoktype      op;
        !           248: 
        !           249:        lexpr = factor();
        !           250:        while(INTOKSET(val, MULOPS)){
        !           251:                op = val;
        !           252:                shift;
        !           253:                lexpr = combine(op, lexpr, factor());
        !           254:        }
        !           255:        return(lexpr);
        !           256: }
        !           257: 
        !           258: struct exp *factor()
        !           259: {
        !           260:        struct  exp *lexpr;
        !           261:        inttoktype      op;
        !           262:        extern          int     droppedLP;      /*called exprparse after consuming an LP*/
        !           263: 
        !           264:        if (val == LP || droppedLP){
        !           265:                if (droppedLP)
        !           266:                        droppedLP = 0;
        !           267:                else
        !           268:                        shift;          /*the LP*/
        !           269:                val = exprparse(val, &lexpr);
        !           270:                if (val != RP)
        !           271:                        yyerror("right parenthesis expected");
        !           272:                else
        !           273:                        shift;
        !           274:        } else
        !           275:        if (INTOKSET(val, YUKKYEXPRBEG)){
        !           276:                lexpr = yukkyexpr(val, yylval);
        !           277:                shift;
        !           278:        }
        !           279:        else if (INTOKSET(val, SAFEEXPRBEG)){
        !           280:                lexpr = (struct exp *)yylval;
        !           281:                shift;
        !           282:        }
        !           283:        else if ( (val == TILDE) || (val == MINUS) ){
        !           284:                op = val;
        !           285:                shift;
        !           286:                lexpr = xp++;
        !           287:                lexpr->e_xtype = XABS;
        !           288:                lexpr->e_number = Znumber;
        !           289:                lexpr->e_number.num_tag = TYPL;
        !           290:                lexpr = combine(op, lexpr, factor());
        !           291:        } else {
        !           292:                yyerror("Bad expression syntax");
        !           293:                lexpr = xp++;
        !           294:                lexpr->e_xtype = XABS;
        !           295:                lexpr->e_number = Znumber;
        !           296:                lexpr->e_number.num_tag = TYPL;
        !           297:        }
        !           298:        return(lexpr);
        !           299: }
        !           300: 
        !           301: struct exp *yukkyexpr(val, np)
        !           302:        int     val;
        !           303:        reg     np;
        !           304: {
        !           305:        reg     struct exp *locxp;
        !           306:        extern  int     exprisname;     /*last factor is a name*/
        !           307:                int     off = 0;
        !           308: 
        !           309:        exprisname = 0;
        !           310:        locxp = xp++;
        !           311:        locxp->e_number = Znumber;
        !           312:        locxp->e_number.num_tag = TYPL;
        !           313: 
        !           314:        switch(val){
        !           315:        case BFINT:
        !           316:                yylval = ((struct exp *)np)->e_xvalue;
        !           317:                if (yylval < 0) {
        !           318:                        yylval = -yylval;
        !           319:                        yylval--;
        !           320:                        off = -1;
        !           321:                        if (lgensym[yylval] == 1)
        !           322:                                yyerror("Reference to undefined local label %db", yylval);
        !           323:                } else {
        !           324:                        yylval--;
        !           325:                        genref[yylval] = 1;
        !           326:                }
        !           327:                (void)sprintf(yytext, "L%d\001%d", yylval, lgensym[yylval] + off);
        !           328:                yylval = np = (int)*lookup(passno == 1);
        !           329:                lastnam = (struct symtab *)np;
        !           330:                /* FALLTHROUGH */
        !           331:        case NAME:
        !           332:                exprisname++;
        !           333:                locxp->e_xtype = ((struct symtab *)np)->s_type;
        !           334:                if (( ((struct symtab *)np)->s_type&XTYPE)==XUNDEF) { /*forward*/
        !           335:                        locxp->e_xname = (struct symtab *)np;
        !           336:                        locxp->e_xvalue = 0;
        !           337:                        if (passno==1)
        !           338:                                ((struct symtab *)np)->s_type |= XFORW;
        !           339:                } else {        /*otherwise, just get the value*/
        !           340:                        locxp->e_xvalue = ((struct symtab *)np)->s_value;
        !           341:                        locxp->e_xname = NULL;
        !           342:                }
        !           343:                break;
        !           344:        default:
        !           345:                yyerror("Internal Error in yukkyexpr");
        !           346:                /* FALLTHROUGH */
        !           347: 
        !           348:        case INSTn:
        !           349:        case INST0:
        !           350:        case REG:
        !           351:                locxp->e_xtype = XABS;
        !           352:                locxp->e_xvalue = ( (int)np) & 0xFF;
        !           353:                locxp->e_xloc = 0;
        !           354:                locxp->e_xname = NULL;
        !           355:                break;
        !           356:        }
        !           357: 
        !           358:        return(locxp);
        !           359: }
        !           360: 
        !           361: /*
        !           362:  *     Print definitions for token kinds
        !           363:  */
        !           364: static char pdirect[]  = "directive";
        !           365: static char pinstr[]   = "instruction";
        !           366: static char phunk[]    = "lexeme";
        !           367: static char psmall[]   = "small symbol";
        !           368: static char pcntrl[]   = "control token";
        !           369: 
        !           370: #define        DIRECT  pdirect
        !           371: #define        INSTR   pinstr
        !           372: #define        HUNK    phunk
        !           373: #define        SMALL   psmall
        !           374: #define        CNTRL   pcntrl
        !           375: 
        !           376: struct Tok_Desc{
        !           377:        int             tok_which;
        !           378:        char            *tok_kind;
        !           379:        char            *tok_name;
        !           380: };
        !           381: struct Tok_Desc *tok_name[LASTTOKEN - FIRSTTOKEN + 1];
        !           382: 
        !           383: struct Tok_Desc tok_desc[] = {
        !           384:        FIRSTTOKEN,     DIRECT, "first token",
        !           385: 
        !           386:        IBYTE,          DIRECT, ".byte",
        !           387:        IWORD,          DIRECT, ".word",
        !           388:        IINT,           DIRECT, ".int",
        !           389:        ILONG,          DIRECT, ".long",
        !           390:        IQUAD,          DIRECT, ".quad",
        !           391:        IOCTA,          DIRECT, ".octa",
        !           392:        IFFLOAT,        DIRECT, ".ffloat",
        !           393:        IDFLOAT,        DIRECT, ".dfloat",
        !           394:        IGFLOAT,        DIRECT, ".gfloat",
        !           395:        IHFLOAT,        DIRECT, ".hfloat",
        !           396:        IASCII,         DIRECT, ".ascii",
        !           397:        IASCIZ,         DIRECT, ".asciz",
        !           398:        IFILL,          DIRECT, ".fill",
        !           399:        ISPACE,         DIRECT, ".space",
        !           400: 
        !           401:        IDATA,          DIRECT, ".data",
        !           402:        ITEXT,          DIRECT, ".text",
        !           403:        IGLOBAL,        DIRECT, ".global",
        !           404:        IALIGN,         DIRECT, ".align",
        !           405: 
        !           406:        ISET,           DIRECT, ".set",
        !           407:        ICOMM,          DIRECT, ".comm",
        !           408:        ILCOMM,         DIRECT, ".lcomm",
        !           409:        IORG,           DIRECT, ".org",
        !           410:        ILSYM,          DIRECT, ".lsym",
        !           411: 
        !           412:        ISTAB,          DIRECT, ".stab",
        !           413:        ISTABSTR,       DIRECT, ".stabstr",
        !           414:        ISTABNONE,      DIRECT, ".stabnone",
        !           415:        ISTABDOT,       DIRECT, ".stabdot",
        !           416: 
        !           417:        IFILE,          DIRECT, ".file",
        !           418:        ILINENO,        DIRECT, ".lineno",
        !           419:        IABORT,         DIRECT, ".abort",
        !           420: 
        !           421:        IJXXX,          INSTR,  "jump pseudo",
        !           422:        INST0,          INSTR,  "0 argument inst",
        !           423:        INSTn,          INSTR,  "n argument inst",
        !           424: 
        !           425:        PARSEEOF,       CNTRL,  "parse end of file",
        !           426:        ILINESKIP,      CNTRL,  "skip lines",
        !           427:        VOID,           CNTRL,  "void",
        !           428:        SKIP,           CNTRL,  "skip",
        !           429:        NL,             CNTRL,  "new line",
        !           430:        SCANEOF,        CNTRL,  "scanner end of file",
        !           431:        BADCHAR,        CNTRL,  "bad character",
        !           432:        SH,             CNTRL,  "comment, #",
        !           433: 
        !           434:        INT,            HUNK,   "int",
        !           435:        BFINT,          HUNK,   "local label",
        !           436:        BIGNUM,         HUNK,   "big number",
        !           437:        NAME,           HUNK,   "name",
        !           438:        STRING,         HUNK,   "string",
        !           439:        REG,            HUNK,   "register specifier",
        !           440: 
        !           441:        SIZESPEC,       SMALL,  "size specifier, [BWLbwl]",
        !           442:        SIZEQUOTE,      SMALL,  "sizequote, [^']",
        !           443:        LITOP,          SMALL,  "litop",
        !           444: 
        !           445:        MP,             SMALL,  "minus parenthesis, -(",
        !           446:        REGOP,          SMALL,  "register operator, %",
        !           447: 
        !           448:        SP,             SMALL,  "space",
        !           449:        ALPH,           SMALL,  "alphabetic character, [A-Za-z_]",
        !           450:        DIG,            SMALL,  "digit character, [A-Fa-f0-9]",
        !           451: 
        !           452:        SQ,             SMALL,  "single quote, '",
        !           453:        DQ,             SMALL,  "double quote, \"",
        !           454: 
        !           455:        LSH,            SMALL,  "arithmetic left shift, <",
        !           456:        RSH,            SMALL,  "arithmetic right shift, >",
        !           457:        XOR,            SMALL,  "exclusive or, ^",
        !           458: 
        !           459:        PLUS,           SMALL,  "plus, +",
        !           460:        MINUS,          SMALL,  "minus, -",
        !           461:        MUL,            SMALL,  "multiply, *",
        !           462:        DIV,            SMALL,  "divide, /",
        !           463:        SEMI,           SMALL,  "semi colon, ;",
        !           464:        COLON,          SMALL,  "colon, :",
        !           465:        IOR,            SMALL,  "inclusive or, |",
        !           466:        AND,            SMALL,  "and, &",
        !           467: 
        !           468:        TILDE,          SMALL,  "one's complement, ~",
        !           469:        ORNOT,          SMALL,  "ornot, !",
        !           470:        CM,             SMALL,  "comma",
        !           471: 
        !           472:        LB,             SMALL,  "left bracket, [",
        !           473:        RB,             SMALL,  "right bracket, ]",
        !           474:        LP,             SMALL,  "left parenthesis, (",
        !           475:        RP,             SMALL,  "right parentheis, )",
        !           476: 
        !           477:        LASTTOKEN,      SMALL,  "last token",
        !           478: };
        !           479: /*
        !           480:  *     turn a token type into a string
        !           481:  */
        !           482: char *tok_to_name(token)
        !           483: {
        !           484:        static  int     fixed = 0;
        !           485:        static  char    buf[64];
        !           486:        static  struct  Tok_Desc        NA = {0, (char *)0, "NOT ASSIGNED"};
        !           487:                int     i;
        !           488:                char    *cp;
        !           489: 
        !           490:        if (!fixed){
        !           491:                for (i = FIRSTTOKEN; i <= LASTTOKEN; i++)
        !           492:                        tok_name[i] = &NA;
        !           493:                for (i = 0; i <= sizeof(tok_desc)/sizeof(struct Tok_Desc); i++){
        !           494:                        tok_name[tok_desc[i].tok_which] = &tok_desc[i];
        !           495:                }
        !           496:                fixed = 1;
        !           497:        }
        !           498:        if (FIRSTTOKEN <= token && token <= LASTTOKEN){
        !           499:                sprintf(buf, "%s %s", tok_name[token]->tok_kind,
        !           500:                        tok_name[token]->tok_name);
        !           501:                return(buf);
        !           502:        } else {
        !           503:                panic("Unknown token number, %d\n", token);
        !           504:                /*NOTREACHED*/
        !           505:        }
        !           506: }

unix.superglobalmegacorp.com

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