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

unix.superglobalmegacorp.com

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