Annotation of coherent/b/bin/as/lex.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * This is the controlling loop in the assembler.
        !             3:  *
        !             4:  */
        !             5: #include <utype.h>
        !             6: #include <asm.h>
        !             7: #include <asflags.h>
        !             8: #include <y_tab.h>
        !             9: #include <symtab.h>
        !            10: 
        !            11: /* states */
        !            12: #define INITIAL        0
        !            13: #define INSYM   1
        !            14: #define INCHAR 2       /* in char constant */
        !            15: #define LTS    3
        !            16: #define GTS    4
        !            17: #define BSLP   5       /* back slash while reading parms */
        !            18: #define WHITE  6       /* in white space */
        !            19: #define ENDLINE 7
        !            20: #define CSTATE 8       /* Pick up parms in macro expansion */
        !            21: #define INTOKEN 9
        !            22: 
        !            23: #define OPONLY1        10      /* search for operator only */
        !            24: #define OPONLY2 11
        !            25: #define OPONLY3        12
        !            26: #define OPONLY4        13
        !            27: 
        !            28: #define INSTR  14      /* string detected */
        !            29: #define BSL    15      /* back slash */
        !            30: #define BSLDIG  16     /* digit after back slash */
        !            31: 
        !            32: #define CMSTATE 17     /* pick up names in macro definition */
        !            33: #define INNAME 18
        !            34: 
        !            35: #define LZERO  19      /* lead zero */
        !            36: #define XNUM   20      /* hex number */
        !            37: #define DNUM   21      /* decimal number */
        !            38: #define ONUM   22      /* octal number */
        !            39: #define BNUM   23      /* binary number */
        !            40: 
        !            41: #define BANGS   24     /* ! seen */
        !            42: #define EQUS    25     /* = seen */
        !            43: 
        !            44: #define DSTATE  26     /* eat whole line for S_EQUS */
        !            45: 
        !            46: /* positions */
        !            47: #define LABEL  0
        !            48: #define OPCODE 1
        !            49: #define OPERAND        2
        !            50: #define COMMENT 3
        !            51: 
        !            52: /* comparisons */
        !            53: #define LT 1
        !            54: #define GT 2
        !            55: #define EQ 4
        !            56: 
        !            57: #define RET(toYacc) return(lastToken = (toYacc))
        !            58: #define RSTATE(toYacc, newstate) { state = newstate; RET(toYacc); }
        !            59: #define NEWS(newstate) { state = newstate; continue; }
        !            60: 
        !            61: static unsigned short state = INITIAL;
        !            62: static unsigned short pstate;  /* previous state when \ detected */
        !            63: static unsigned short pos = LABEL;
        !            64: 
        !            65: static unsigned short ctype;   /* current logic type */
        !            66: 
        !            67: static char buf[1024], *bp = buf;
        !            68: static char *backOff;  /* start of decimal number */
        !            69: static char fromMac = ' ';             /* ' ' or '+' */
        !            70: static short opIx;     /* index of current opcode */
        !            71: static psw = 0;
        !            72: static long number = 0;
        !            73: static char token[1024], *tp;
        !            74: 
        !            75: static int lastChar;   /* last Character in */
        !            76: static short vctr, scnt, dcnt;
        !            77: static symt *stype;
        !            78: static short ytype;
        !            79: 
        !            80: /*
        !            81:  * Invalid character message.
        !            82:  */
        !            83: static void
        !            84: invChar(c, s)
        !            85: register short c;
        !            86: char *s;
        !            87: {
        !            88:        unsigned short p;
        !            89: 
        !            90:        p = bp - lastL;
        !            91:        if (isprint(c))
        !            92:                yyerror("Invalid character '%c' %s at position %d", c, s, p);
        !            93:                /**/
        !            94:        else
        !            95:                yyerror("Invalid character 0x%02x %s at position %d",
        !            96:                        c & 255, s, p); /**/
        !            97: }
        !            98: 
        !            99: /*
        !           100:  * Expand parms in macro line.
        !           101:  * # as first char of line foils replacment.
        !           102:  */
        !           103: static char *
        !           104: expand(s, recurs)
        !           105: register char *s;
        !           106: {
        !           107:        register char c;
        !           108:        char *tp, *rep, *newl, *start;
        !           109:        macro *mac;
        !           110:        short sav, pb;
        !           111:        unsigned short point;
        !           112: 
        !           113:        start = s;
        !           114:        pb = 0;
        !           115:        for(state = WHITE; ; ) {
        !           116:                switch(state) {
        !           117:                case WHITE:
        !           118:                        if (isalpha(c = *s++)) {
        !           119:                                state = INSYM;
        !           120:                                tp = token;
        !           121:                                *tp++ = c;
        !           122:                                break;
        !           123:                        }
        !           124:                        pb = 0;
        !           125:                        break;
        !           126:                case INSYM:
        !           127:                        if (isalnum(c = *s++)) {
        !           128:                                *tp++ = c;
        !           129:                                break;
        !           130:                        }
        !           131:                        mac = NULL;
        !           132:                        *tp = '\0';
        !           133:                        if ((!recurs && (NULL != trueMac) &&
        !           134:                            (NULL != (rep = lookList(token)))) ||
        !           135:                           (NULL != (mac = macLookUp(token, MACSTR)))) {
        !           136:                                tp = --s - (strlen(token) + pb);
        !           137:                                sav = *tp;      /* stomp parm name */
        !           138:                                *tp = '\0';
        !           139:                                if (NULL == mac)        /* parm match */
        !           140:                                        rep = expand(rep, 1);
        !           141:                                else {  /* equs match */
        !           142:                                        rep = mac->names->str;
        !           143:                                        mac->type = MACSCAN;
        !           144:                                        rep = expand(rep, 1);
        !           145:                                        mac->type = MACSTR;
        !           146:                                }
        !           147:                                point = strlen(start) + strlen(rep);
        !           148:                                newl = galloc(point + strlen(s) + 1);
        !           149:                                sprintf(newl, "%s%s%s", start, rep, s);
        !           150:                                *tp = sav;      /* Un stomp parm name */
        !           151:                                start = newl;
        !           152:                                s = start + point; /* don't rescan */
        !           153:                        }
        !           154:                        pb = (c == '\\');
        !           155:                        state = WHITE;
        !           156:                }
        !           157:                if (!c)
        !           158:                        break;
        !           159:        }
        !           160:        return(start);
        !           161: }
        !           162: 
        !           163: /*
        !           164:  * Get next line from macro or while.
        !           165:  */
        !           166: static char *
        !           167: nextMac()
        !           168: {
        !           169:        macctl *tmp;
        !           170:        macline *l;
        !           171:        extern char *strcpy();
        !           172: 
        !           173:        for(;;) {
        !           174:                if (NULL == macExp) {   /* not in a macro */
        !           175:                        fromMac = ' ';
        !           176:                        return(NULL);
        !           177:                }
        !           178:                if (NULL != (l = macExp->curr)) {
        !           179:                        fromMac = '+';
        !           180:                        macExp->curr =  l->next;
        !           181:                        return(strcpy(buf, l->line));
        !           182:                }
        !           183: 
        !           184:                if ((tmp = macExp) == trueMac) { /* popping macro */
        !           185:                        freeList(macExp->parms);
        !           186: 
        !           187:                        while(logic->expno == trueMac->expno) {
        !           188:                                if ((logic->type == INWDEF) ||
        !           189:                                   (logic->type == INPWDEF))
        !           190:                                        yyerror("End of macro building .while");
        !           191:                                /* A \fB.macro\fR ended while reading in a
        !           192:                                 * \fB.while\fR loop. */
        !           193:                                freeLevel();
        !           194:                        }
        !           195: 
        !           196:                        do {
        !           197:                                trueMac = trueMac->prev;
        !           198:                        } while((NULL != trueMac) &&
        !           199:                                (trueMac->type != MACTYPE));
        !           200:                }
        !           201: 
        !           202:                macExp = macExp->prev;          /* pop a level */
        !           203:                free((char *)tmp);
        !           204:        }
        !           205: }
        !           206: 
        !           207: /*
        !           208:  * Save a line in a macro.
        !           209:  */
        !           210: saveLine()
        !           211: {
        !           212:        macline *newl;
        !           213: 
        !           214:        newl = (macline *)alloc((unsigned)(sizeof(*newl) + strlen(lastL)));
        !           215:        strcpy(newl->line, lastL);
        !           216:        if (NULL == inMacDef->first)
        !           217:                lastDef = inMacDef->first = newl;
        !           218:        else {
        !           219:                lastDef->next = newl;
        !           220:                lastDef = newl;
        !           221:        }
        !           222: }
        !           223: 
        !           224: /*
        !           225:  * Get a line off a file.
        !           226:  */
        !           227: static char *
        !           228: getLine()
        !           229: {
        !           230:        register char *line;
        !           231: 
        !           232:        ++statement;            /* increment statement number */
        !           233:        if (NULL != (line = nextMac()))
        !           234:                return(line);
        !           235: 
        !           236:        while(NULL == (fgets(line = buf, sizeof(buf), inpc->fp))) {
        !           237:                if (NULL != inpc->prev) {
        !           238:                        inpctl *tmp;
        !           239: 
        !           240:                        fclose(inpc->fp);
        !           241:                        inpc = (tmp = inpc)->prev;
        !           242:                        free((char *)tmp);
        !           243:                }
        !           244:                else {  /* end of pass */
        !           245:                        for(;NORMAL != logic->type; freeLevel()) {
        !           246:                                switch(logic->type) {
        !           247:                                case INMACDEF:
        !           248:                                case PMACDEF:
        !           249:                                        yyerror("Missing .endm");
        !           250:                                 /* Input ended leaving \fB.macro\fR open. */
        !           251:                                        break;
        !           252:                                case INIF0:
        !           253:                                case INIF1:
        !           254:                                case INIFX:
        !           255:                                        yyerror("Missing .endi");
        !           256:                                 /* Input ended leaving \fB.if\fR open. */
        !           257:                                        break;
        !           258:                                case INWDEF:
        !           259:                                case INPWDEF:
        !           260:                                        yyerror("Missing .endw");
        !           261:                                 /* Input ended leaving \fB.while\fR open. */
        !           262:                                }
        !           263:                        }
        !           264:                        if (2 == pass) {
        !           265:                                cleanUp();
        !           266: 
        !           267:                                switch (errCt) {
        !           268:                                case 0:
        !           269:                                        exit(0);
        !           270:                                case 1:
        !           271:                                        fprintf(errdev, "1 Error\n");
        !           272:                                        break;
        !           273:                                default:
        !           274:                                        fprintf(errdev, "%d Errors\n", errCt);
        !           275:                                }
        !           276:                                unlink(outName);
        !           277:                                exit(1);
        !           278:                        }
        !           279:                        else {  /* avoid close & open */
        !           280:                                rewind(inpc->fp);
        !           281:                                inpc->lineNo = 0;
        !           282:                                statement = 1;
        !           283: 
        !           284:                                newPass(outName);
        !           285: 
        !           286:                                /* reset compiler switches to initial state */
        !           287:                                alignon = alignonX;
        !           288:                                lswitch = lswitchX;
        !           289:                                nswitch = nswitchX;
        !           290:                                wswitch = wswitchX;
        !           291:                                fswitch = fswitchX;
        !           292:                                bswitch = bswitchX;
        !           293: 
        !           294:                                dodefs();
        !           295:                                outLine((char *)NULL, 0);
        !           296:                                continue;
        !           297:                        }
        !           298:                }
        !           299:        }
        !           300:        inpc->lineNo++;
        !           301:        return(line);
        !           302: }
        !           303: 
        !           304: /*
        !           305:  * In OPONLY3 we found an op process it.
        !           306:  * separated to keep from crashing Coherent compiler in cc2.
        !           307:  */
        !           308: static unsigned short
        !           309: procOp()
        !           310: {
        !           311:        register opc *op;
        !           312: 
        !           313:        *tp = '\0';
        !           314:        bp--;
        !           315:        if (-1 == (opIx = opLookUp(token)))
        !           316:                return(OPONLY4);
        !           317: 
        !           318:        if (INIF1 <= ctype)
        !           319:                fatal("Logic error in macro def '%s' %d", token, ctype); /* TECH */
        !           320: 
        !           321:        op = prefTab + opIx;
        !           322:        switch(op->kind) {      /* switch on function type */   
        !           323:        case S_MACRO:
        !           324:                if (ctype < INIF0)
        !           325:                        newLevel(PMACDEF);
        !           326:                break;
        !           327:        case S_ENDM:
        !           328:                switch(ctype) {
        !           329:                case INMACDEF:
        !           330:                        inMacDef = (macro *)NULL;
        !           331:                        lastDef = (macline *)NULL;
        !           332:                        freeLevel();
        !           333:                        return(INITIAL);
        !           334:                case PMACDEF:
        !           335:                        freeLevel();
        !           336:                }
        !           337:                break;
        !           338:        case S_WHILE:
        !           339:                switch(ctype) {
        !           340:                case INWDEF:
        !           341:                case INPWDEF:
        !           342:                        newLevel(INPWDEF);
        !           343:                }
        !           344:                break;
        !           345:        case S_ENDW:
        !           346:                switch(ctype) {
        !           347:                case INWDEF: {
        !           348:                        macctl *tmp;
        !           349:                                saveLine();
        !           350:                        logic = (tmp = logic)->prev;
        !           351:                        tmp->type  = WHILETYPE;
        !           352:                        tmp->curr = tmp->first = inMacDef->first;
        !           353:                        tmp->parms = tmp->names = NULL;
        !           354:                        tmp->prev = macExp;
        !           355:                        macExp = tmp;
        !           356:                        free((char *)inMacDef);
        !           357:                        lastDef  = (macline *)NULL;
        !           358:                        inMacDef = (macro *)NULL;
        !           359:                        return(INITIAL);
        !           360:                }
        !           361:                case INPWDEF:
        !           362:                        freeLevel();
        !           363:                        break;
        !           364:                }
        !           365:                break;
        !           366:        case S_IF:
        !           367:                switch(ctype) {
        !           368:                case INIF0:
        !           369:                case INIFX:
        !           370:                        newLevel(INIFX);
        !           371:                }
        !           372:                break;
        !           373:        case S_ELSE:
        !           374:                switch(ctype) {
        !           375:                case INIF0:
        !           376:                        logic->type = INIF1;
        !           377:                        return(INITIAL);
        !           378:                }
        !           379:                break;
        !           380:        case S_ENDI:
        !           381:                switch(ctype) {
        !           382:                case INIF0:
        !           383:                case INIFX:
        !           384:                        freeLevel();
        !           385:                }
        !           386:                break;
        !           387:        }
        !           388:        return(OPONLY4);
        !           389: }
        !           390: 
        !           391: /*
        !           392:  * Read line and start processing.
        !           393:  * separated from yylex() to keep from crashing compiler in cc2.
        !           394:  */
        !           395: static unsigned short
        !           396: startLine()
        !           397: {
        !           398:        register short c;
        !           399: 
        !           400:        do {    /* GNU outputs # line numbers */
        !           401:                if (';' != lastChar) {
        !           402:                        outLine(lastL, fromMac);
        !           403:                        bp = lastL = getLine();
        !           404:                }
        !           405:                if (COMMA != lastToken)
        !           406:                        freel();        /* trash free space from last line */
        !           407:        } while ('#' == *bp);
        !           408: 
        !           409:        ctype = logic->type;
        !           410: 
        !           411:        if (('#' != *bp) &&
        !           412:           (';' != lastChar) &&
        !           413:           (defCt || (NULL != trueMac)) &&
        !           414:           ((ctype > INPWDEF) || (ctype < INWDEF))) {
        !           415:                bp = lastL = expand(bp, 0);
        !           416: 
        !           417:                if ((lastL != buf) && (fromMac != '+')) {
        !           418:                        outLine(buf, fromMac);
        !           419:                        fromMac = '@';
        !           420:                }
        !           421:        }
        !           422: 
        !           423:        if ('#' == *bp) /* don't lex noexpand */
        !           424:                bp++;
        !           425: 
        !           426:        if (COMMA == lastToken) /* continuation line ? */
        !           427:                return(psw);
        !           428: 
        !           429:        lastChar = c = *bp;     /* get a char */
        !           430:        if (ctype < INIF1) {
        !           431:                if ((' ' == c) || ('\t' == c))
        !           432:                        return(OPONLY1);
        !           433:                else if (isalpha(c))
        !           434:                        return(OPONLY2);
        !           435:                else
        !           436:                        return(OPONLY4);
        !           437:        }
        !           438:        if ((' ' == c) || ('\t' == c)) {
        !           439:                pos = OPCODE;
        !           440:                return(WHITE);
        !           441:        }
        !           442:        if (isalpha(c)) {
        !           443:                pos = LABEL;
        !           444:                tp = token;
        !           445:                *tp++ = c;
        !           446:                return(INSYM);
        !           447:        }
        !           448:        switch(c) {
        !           449:        case '/': case '\n': case 0: case ';':
        !           450:                break;
        !           451:        default:
        !           452:                invChar(c, "");
        !           453:        }
        !           454:        return(INITIAL);
        !           455: }
        !           456: 
        !           457: /*
        !           458:  * Got an opcode, set it up.
        !           459:  */
        !           460: static
        !           461: doOp(opIx)
        !           462: {
        !           463:        register opc *op;
        !           464: 
        !           465:        lflags = 0;
        !           466:        stype = typTab + (kind = (op = prefTab + opIx)->kind);
        !           467:        yylval.o = op;
        !           468:        pos = OPERAND;
        !           469:        /* op code determines operand syntax */
        !           470:        switch(ytype = stype->type) {
        !           471:        case NCMD:
        !           472:                RSTATE(ytype, ENDLINE)
        !           473:        case OP:
        !           474:                if (stype->bldr & REP_INSTR)
        !           475:                        pos = OPCODE;
        !           476:        case ICMD:
        !           477:        case DATA:
        !           478:                RSTATE(ytype, WHITE)
        !           479:        case ECMD:
        !           480:        case ECMDX:
        !           481:        case CMD:
        !           482:                if (S_EQUS == kind) {
        !           483:                        tp = token;
        !           484:                        scnt = dcnt = 0;
        !           485:                        RSTATE(ytype, DSTATE)
        !           486:                }
        !           487:                RSTATE(ytype, CSTATE)
        !           488:        case DCMD:
        !           489:                RSTATE(ytype, CMSTATE)
        !           490:        default:
        !           491:                fatal("Optype %d in lex", ytype); /* TECH */
        !           492:        }
        !           493: }
        !           494: 
        !           495: /*
        !           496:  * get tokens
        !           497:  */
        !           498: yylex()
        !           499: {
        !           500:     register short c;
        !           501: 
        !           502:     for(;;) {
        !           503:        /*
        !           504:         * Allow Japaneese comments and strings, catch other non ascii
        !           505:         * and abort the line.
        !           506:         */
        !           507:        if ((state != INITIAL) &&
        !           508:           !isascii(lastChar = c = *bp++) &&
        !           509:           (state != INSTR) &&
        !           510:           (state != INCHAR)) {
        !           511:                invChar(c, "");
        !           512:                RSTATE(NL, INITIAL)
        !           513:        }
        !           514: 
        !           515:        switch(state) {
        !           516:        case INITIAL:           /* start of line */
        !           517:                bcnt = pcnt = 0;
        !           518:                psw = startLine();
        !           519:                lastChar = c = *bp++;
        !           520:                if (!isascii(c)) {
        !           521:                        invChar(c, "");
        !           522:                        RSTATE(NL, INITIAL)
        !           523:                }
        !           524:                NEWS(psw);
        !           525:                
        !           526:        case OPONLY1:   /* find start of opcode */
        !           527:                switch(c) {
        !           528:                case ' ':
        !           529:                case '\t':
        !           530:                        continue;
        !           531:                default:
        !           532:                        if (!islower(c))
        !           533:                                NEWS(OPONLY4)
        !           534:                        tp = token;
        !           535:                        *tp++ = c;
        !           536:                        NEWS(OPONLY3)
        !           537:                }
        !           538: 
        !           539:        case OPONLY2:                   /* bypass label */
        !           540:                if (isalnum(c))
        !           541:                        continue;
        !           542:                --bp;
        !           543:                if ((' ' == c) || ('\t' == c))
        !           544:                        NEWS(OPONLY1)
        !           545:                NEWS(OPONLY4)
        !           546:                
        !           547:        case OPONLY3:
        !           548:                if (isalnum(c)) {       /* accumulate opcode */
        !           549:                        *tp++ = c;
        !           550:                        continue;
        !           551:                }
        !           552:                NEWS(procOp());
        !           553: 
        !           554:        case OPONLY4:   /* default processing */
        !           555:                if (logic->type < INIF0)
        !           556:                        saveLine();
        !           557:                NEWS(INITIAL)
        !           558: 
        !           559:        case INSYM:
        !           560:                if (isalnum(c)) {
        !           561:                        *tp++ = c;
        !           562:                        continue;
        !           563:                }
        !           564:                *tp = '\0';
        !           565:                --bp;
        !           566:                if (pos == OPERAND) {
        !           567:                        sym *sp;
        !           568: 
        !           569:                        sp = symLookUp(token, S_UNDEF, 0L, 0);
        !           570:                        switch(sp->type) {
        !           571:                        case IDENTIFIER:
        !           572:                        case REG:
        !           573:                        case LEN:
        !           574:                                yylval.s = sp;
        !           575:                                break;
        !           576:                        case NUMBER:
        !           577:                                yylval.val = sp->loc;
        !           578:                        }
        !           579:                        RSTATE(sp->type, WHITE)
        !           580:                }
        !           581: 
        !           582:                /* pos != OPERAND may be opcode or label */
        !           583:                if (':' != c) {
        !           584:                        if (-1 != (opIx = opLookUp(token)))
        !           585:                                return(doOp(opIx));
        !           586: 
        !           587:                        if (NULL != (macFound = macLookUp(token, MACTYPE))) {
        !           588:                                static opc smac = { /* fake opcode */
        !           589:                                        0, S_MAC
        !           590:                                };
        !           591: 
        !           592:                                yylval.o = &smac; /* macro expansion */
        !           593:                                RSTATE(CMD, CSTATE)
        !           594:                        }
        !           595: 
        !           596:                        if (!strcmp(token, ".")) {
        !           597:                                yylval.t = token;
        !           598:                                pos = OPCODE;
        !           599:                                RSTATE(TOKEN, WHITE)
        !           600:                        }
        !           601:                }
        !           602: 
        !           603:                if ((pos == LABEL) || (':' == c)) {
        !           604:                        yylval.t = token;
        !           605:                        pos = OPCODE;
        !           606:                        RSTATE(TOKEN, WHITE)
        !           607:                }
        !           608: 
        !           609:                yyerror("Invalid opcode: '%s'", token);
        !           610:                /* The string in the opcode position is
        !           611:                 * not one of our opcodes or one of
        !           612:                 * your macros. */
        !           613:                RSTATE(NL, INITIAL)
        !           614: 
        !           615:        case DSTATE:    /* eat whole line for define */
        !           616:                switch(c) {
        !           617:                case '"':
        !           618:                        if (dcnt)
        !           619:                                dcnt = 0;
        !           620:                        else if (!scnt)
        !           621:                                dcnt = 1;
        !           622:                        break;
        !           623:                case '\'':
        !           624:                        if (scnt)
        !           625:                                scnt = 0;
        !           626:                        else if (!dcnt)
        !           627:                                scnt = 1;
        !           628:                        break;
        !           629:                case '\\':
        !           630:                        *tp++ = c;
        !           631:                        psw = state;
        !           632:                        NEWS(BSLP)
        !           633:                case '/':
        !           634:                        if (scnt | dcnt)
        !           635:                                break;
        !           636:                case 0:         /* let # define take semicolon */
        !           637:                case '\n':
        !           638:                        *tp = '\0';
        !           639:                        yylval.t = trim(token);
        !           640:                        RSTATE(TOKEN, ENDLINE)
        !           641:                }
        !           642:                *tp++ = c;
        !           643:                continue;
        !           644: 
        !           645:        case CSTATE: /* pick up parms on macro expansion */
        !           646:                state = psw = INTOKEN;
        !           647:                *(tp = token) = '\0';
        !           648:                scnt = dcnt = pcnt = bcnt = 0;
        !           649:                vctr = 1;
        !           650:                switch(c) {
        !           651:                case 0:
        !           652:                case ';':
        !           653:                case '\n':
        !           654:                case '/':
        !           655:                        if (COMMA == lastToken)
        !           656:                                NEWS(INITIAL)
        !           657:                        RSTATE(NL, INITIAL)
        !           658:                case ',':
        !           659:                        switch(lastToken) {
        !           660:                        case CMD:
        !           661:                        case COMMA:
        !           662:                                bp--;
        !           663:                                yylval.t = token;
        !           664:                                RSTATE(TOKEN, CSTATE)
        !           665:                        }
        !           666:                        RSTATE(COMMA, CSTATE)
        !           667:                }
        !           668: 
        !           669:        case INTOKEN:   /* pick up parms on macro expansion */
        !           670:                switch(c) {
        !           671:                case '(':
        !           672:                        pcnt += vctr; break;
        !           673:                case ')':
        !           674:                        if (pcnt)
        !           675:                                pcnt -= vctr;
        !           676:                        break;
        !           677:                case '[':
        !           678:                        bcnt += vctr; break;
        !           679:                case ']':
        !           680:                        if (bcnt)
        !           681:                                bcnt -= vctr;
        !           682:                        break;
        !           683:                case '"':
        !           684:                        if (dcnt)
        !           685:                                dcnt = 0;
        !           686:                        else if (!scnt)
        !           687:                                dcnt = 1;
        !           688:                        vctr = (dcnt | scnt) ^ 1;
        !           689:                        break;
        !           690:                case '\'':
        !           691:                        if (scnt)
        !           692:                                scnt = 0;
        !           693:                        else if (!dcnt)
        !           694:                                scnt = 1;
        !           695:                        vctr = (dcnt | scnt) ^ 1;
        !           696:                        break;
        !           697:                case '\\':
        !           698:                        *tp++ = c;
        !           699:                        psw = state;
        !           700:                        NEWS(BSLP)
        !           701: 
        !           702:                case ';':
        !           703:                case '/':
        !           704:                        if (!vctr)
        !           705:                                break;
        !           706:                case 0:
        !           707:                case '\n':
        !           708:                        if (pcnt | bcnt | scnt | dcnt) {
        !           709:                                yyerror("Unmatched bracket in parmeter");
        !           710:                /* Line ended leaving an open bracket or parenthesis. */
        !           711:                                RSTATE(NL, INITIAL)
        !           712:                        }
        !           713:                        --bp;
        !           714:                        *tp = '\0';
        !           715:                        if (*(yylval.t = trim(token)))
        !           716:                                RSTATE(TOKEN, CSTATE)
        !           717:                        NEWS(CSTATE)
        !           718:                case ',':
        !           719:                        if (pcnt | bcnt | scnt | dcnt)
        !           720:                                break;
        !           721:                        --bp;
        !           722:                        *tp = '\0';
        !           723:                        yylval.t = trim(token);
        !           724:                        switch(ytype) {
        !           725:                        case ECMD:
        !           726:                        case ECMDX:
        !           727:                                RSTATE(TOKEN, WHITE)
        !           728:                        }
        !           729:                        RSTATE(TOKEN, CSTATE)
        !           730:                }
        !           731:                *tp++ = c;
        !           732:                continue;
        !           733: 
        !           734:        case BSLP:      /* back slash while reading parm */
        !           735:                switch(c) {
        !           736:                case 0:
        !           737:                case '\n':
        !           738:                        --bp;
        !           739:                        yyerror("End of line after backslash reading parm");
        !           740:                /* Macro parmeters may not be broken up with backslash. */
        !           741:                        break;
        !           742:                }
        !           743:                *tp++ = c;
        !           744:                NEWS(psw)
        !           745: 
        !           746:        case CMSTATE: /* pick up names on macro definition */
        !           747:                psw = state = INNAME;
        !           748:                tp = token;
        !           749:                switch(c) {
        !           750:                case ',':
        !           751:                        RET(COMMA);
        !           752:                case 0:
        !           753:                case ';':
        !           754:                case '\n':
        !           755:                case '/':
        !           756:                        if (COMMA == lastToken)
        !           757:                                NEWS(INITIAL)
        !           758:                        RSTATE(NL, INITIAL)
        !           759:                }
        !           760:        case INNAME:    /* pick up parms on macro definition */
        !           761:                switch(c) {
        !           762:                case 0:
        !           763:                case ';':
        !           764:                case '\n':
        !           765:                case '/':
        !           766:                case ',':
        !           767:                        --bp;
        !           768:                        *tp = '\0';
        !           769:                        if (*(yylval.t = trim(token)))
        !           770:                                RSTATE(TOKEN, CMSTATE)
        !           771:                        NEWS(CMSTATE)
        !           772:                default:
        !           773:                        if (ispunct(c)) {
        !           774:                                invChar(c, "in macro name");
        !           775:                                RSTATE(NL, INITIAL)
        !           776:                        }
        !           777:                }
        !           778:                *tp++ = c;
        !           779:                continue;
        !           780: 
        !           781: 
        !           782:        case WHITE:
        !           783:                /*
        !           784:                 * This piece of code is heavily trafficked.
        !           785:                 * Force the fastest form of switch statement
        !           786:                 * by covering many cases.
        !           787:                 */
        !           788:                switch(c) {
        !           789:                case '1':       case '2':       case '3':       case '4':
        !           790:                case '5':       case '6':       case '7':       case '8':
        !           791:                case '9':       case '0':
        !           792:                        backOff = bp - 1;
        !           793:                        if (number = c - '0')
        !           794:                                NEWS(DNUM)
        !           795:                        NEWS(LZERO);
        !           796: 
        !           797:                /* % allowed as first char only */
        !           798:                case 'a':       case 'b':       case 'c':       case 'd':
        !           799:                case 'e':       case 'f':       case 'g':       case 'h':
        !           800:                case 'i':       case 'j':       case 'k':       case 'l':
        !           801:                case 'm':       case 'n':       case 'o':       case 'p':
        !           802:                case 'q':       case 'r':       case 's':       case 't':
        !           803:                case 'u':       case 'v':       case 'w':       case 'x':
        !           804:                case 'y':       case 'z':
        !           805:                case 'A':       case 'B':       case 'C':       case 'D':
        !           806:                case 'E':       case 'F':       case 'G':       case 'H':
        !           807:                case 'I':       case 'J':       case 'K':       case 'L':
        !           808:                case 'M':       case 'N':       case 'O':       case 'P':
        !           809:                case 'Q':       case 'R':       case 'S':       case 'T':
        !           810:                case 'U':       case 'V':       case 'W':       case 'X':
        !           811:                case 'Y':       case 'Z':       case '?':       case '_':
        !           812:                case '%':       case '.':
        !           813:                        tp = token;
        !           814:                        *tp++ = c;
        !           815:                        NEWS(INSYM)
        !           816: 
        !           817:                case ' ':
        !           818:                case '\t':
        !           819:                        continue;
        !           820:                case 0:
        !           821:                case ';':
        !           822:                case '\n':
        !           823:                case '/':
        !           824:                        if (COMMA == lastToken)
        !           825:                                NEWS(INITIAL)
        !           826:                        RSTATE(NL, INITIAL)
        !           827:                case '<':
        !           828:                        NEWS(LTS)
        !           829:                case '>':
        !           830:                        NEWS(GTS)
        !           831:                case '!':
        !           832:                        NEWS(BANGS)
        !           833:                case '=':
        !           834:                        NEWS(EQUS)
        !           835:                case '+':
        !           836:                        RET(PLUS);
        !           837:                case '-':
        !           838:                        RET(MINUS);
        !           839:                case '*':
        !           840:                        RET(TIMES);
        !           841:                case ':':
        !           842:                        if (OPERAND == pos)
        !           843:                                RET(COLON);
        !           844:                        pos = OPCODE;
        !           845:                        RSTATE(NL, WHITE)
        !           846:        
        !           847:                case '&':
        !           848:                        RET(AND);
        !           849:                case '|':
        !           850:                        RET(OR);
        !           851:                case '^':
        !           852:                        RET(XOR);
        !           853:                case '#':
        !           854:                        RET(P_SIGN);
        !           855:                case '$':
        !           856:                        RET(D_SIGN);
        !           857:                case '~':
        !           858:                        RET(NOT);
        !           859:                case ',':
        !           860:                        psw = WHITE;
        !           861:                        RET(COMMA);
        !           862:                /*
        !           863:                 * This assembler may reverse the normal usage of
        !           864:                 * brackets and parentheses. That is expressions
        !           865:                 * are put in []. 5(%eax) is 5 past %eax.
        !           866:                 * bswitch flips this back. Keeps counts to improve
        !           867:                 * the syntax error message.
        !           868:                 */
        !           869:                case '[':
        !           870:                        bcnt++;
        !           871:                        RET(bswitch ? LBRACK : LPAREN);
        !           872:                case ']':
        !           873:                        bcnt--;
        !           874:                        RET(bswitch ? RBRACK : RPAREN);
        !           875:                case '(':
        !           876:                        pcnt++;
        !           877:                        RET(bswitch ? LPAREN : LBRACK);
        !           878:                case ')':
        !           879:                        pcnt--;
        !           880:                        RET(bswitch ? RPAREN : RBRACK);
        !           881:                case '@':
        !           882:                        RET(AT);
        !           883:                case '"':
        !           884:                        psw = WHITE;
        !           885:                        tp = token;
        !           886:                        NEWS(INSTR)
        !           887:                case '\'':
        !           888:                        psw = WHITE;
        !           889:                        tp = token;
        !           890:                        NEWS(INCHAR)
        !           891:                default:
        !           892:                        invChar(c, "as token start");
        !           893:                        RSTATE(NL, INITIAL)
        !           894:                }
        !           895: 
        !           896:        case ONUM:
        !           897:                if (isdigit(c)) {
        !           898:                        if (c > '7')
        !           899:                                yyerror("Error in octal number"); /**/
        !           900:                        number *= 8;
        !           901:                        number += c - '0';
        !           902:                        continue;
        !           903:                }
        !           904:                bp--;
        !           905:                yylval.val = number;
        !           906:                RSTATE(NUMBER, WHITE)
        !           907: 
        !           908:        case BNUM:
        !           909:                if (isdigit(c)) {
        !           910:                        if (c > '1')
        !           911:                                yyerror("Error in binary number"); /**/
        !           912:                        number *= 2;
        !           913:                        number += c - '0';
        !           914:                        continue;
        !           915:                }
        !           916:                bp--;
        !           917:                yylval.val = number;
        !           918:                RSTATE(NUMBER, WHITE)
        !           919: 
        !           920:        case XNUM:
        !           921:                if (isxdigit(c)) {
        !           922:                        number *= 16;
        !           923:                        if (isdigit(c))
        !           924:                                number += c - '0';
        !           925:                        else if (islower(c))
        !           926:                                number += c - ('a' - 10);
        !           927:                        else
        !           928:                                number += c - ('A' - 10);
        !           929:                        continue;
        !           930:                }
        !           931:                bp--;
        !           932:                yylval.val = number;
        !           933:                RSTATE(NUMBER, WHITE)
        !           934:                
        !           935:        case DNUM:
        !           936:                if (isdigit(c)) {
        !           937:                        number *= 10;
        !           938:                        number += c - '0';
        !           939:                        continue;
        !           940:                }
        !           941:                if (('.' == c) || ('e' == c) || ('E' == c)) {
        !           942:                        yylval.dbl = strtod(backOff, &bp);
        !           943:                        RSTATE(FNUM, WHITE)
        !           944:                }
        !           945:                bp--;
        !           946:                yylval.val = number;
        !           947:                RSTATE(NUMBER, WHITE)
        !           948: 
        !           949:        case LZERO:
        !           950:                switch(c) {
        !           951:                case '.':
        !           952:                        yylval.dbl = strtod(backOff, &bp);
        !           953:                        RSTATE(FNUM, WHITE)
        !           954:                case 'x':
        !           955:                case 'X':
        !           956:                        NEWS(XNUM)
        !           957:                case 'b':
        !           958:                case 'B':
        !           959:                        NEWS(BNUM)
        !           960:                default:
        !           961:                        bp--;
        !           962:                        if (isdigit(c))
        !           963:                                NEWS(ONUM)
        !           964:                        yylval.val = number;
        !           965:                        RSTATE(NUMBER, WHITE)
        !           966:                }
        !           967: 
        !           968:        case LTS:       /* < seen */
        !           969:                switch(c) {
        !           970:                case '<':
        !           971:                        RSTATE(LSHIFT, WHITE)
        !           972:                case '=':
        !           973:                        yylval.val = (LT|EQ);
        !           974:                        break;
        !           975:                default:
        !           976:                        --bp;
        !           977:                        yylval.val = LT;
        !           978:                }
        !           979:                RSTATE(COMPARISON, WHITE)               
        !           980: 
        !           981:        case GTS:       /* > seen */
        !           982:                switch(c) {
        !           983:                case '=':
        !           984:                        yylval.val = (GT|EQ);
        !           985:                        break;
        !           986:                case '>':
        !           987:                        RSTATE(RSHIFT, WHITE)
        !           988:                default:
        !           989:                        --bp;
        !           990:                        yylval.val = GT;
        !           991:                }
        !           992:                RSTATE(COMPARISON, WHITE)
        !           993: 
        !           994:        case EQUS:      /* = seen take = or == */
        !           995:                if (OPCODE == pos) {
        !           996:                        --bp;
        !           997:                        opIx = opLookUp(".equ");
        !           998:                        return(doOp(opIx));
        !           999:                }
        !          1000:                if ('=' != c)   
        !          1001:                        --bp;
        !          1002:                yylval.val = EQ;
        !          1003:                RSTATE(COMPARISON, WHITE)
        !          1004: 
        !          1005:        case BANGS:     /* ! seen */
        !          1006:                if ('=' == c) {
        !          1007:                        yylval.val = (GT|LT);
        !          1008:                        RSTATE(COMPARISON, WHITE)
        !          1009:                }
        !          1010:                --bp;
        !          1011:                RSTATE(BANG, WHITE)
        !          1012: 
        !          1013:        case INSTR:
        !          1014:        case INCHAR:
        !          1015:                switch(c) {
        !          1016:                case 0:
        !          1017:                case '\n':
        !          1018:                        --bp;
        !          1019:                        if (state == INSTR) {
        !          1020:                                yyerror("End of line detected in string"); /**/
        !          1021:                                *tp = '\0';
        !          1022:                                yylval.t = token;
        !          1023:                                RSTATE(TOKEN, psw)
        !          1024:                        }
        !          1025:                        yyerror("End of line detected in character constant");
        !          1026:                        /**/
        !          1027:                case '\'':
        !          1028:                        if (state != INCHAR)
        !          1029:                                break;
        !          1030:                        *tp = '\0';
        !          1031:                        if (strlen(token) != 1)
        !          1032:                                yyerror("Character constant %d long",
        !          1033:                                        strlen(token));
        !          1034:                                /* Character constants must be one byte long. */
        !          1035:                        yylval.val = token[0];
        !          1036:                        RSTATE(NUMBER, psw)
        !          1037:                case '"':
        !          1038:                        if (state != INSTR)
        !          1039:                                break;
        !          1040:                        *tp = '\0';
        !          1041:                        yylval.t = token;
        !          1042:                        RSTATE(TOKEN, psw)
        !          1043:                case '\\':
        !          1044:                        pstate = state;
        !          1045:                        NEWS(BSL)
        !          1046:                }
        !          1047:                *tp++ = c;
        !          1048:                continue;
        !          1049: 
        !          1050:        case BSL:       /* back slash */
        !          1051:                switch(c) {
        !          1052:                case 0:
        !          1053:                case '\n':
        !          1054:                        --bp;
        !          1055:                        yyerror("End of line after backslash");
        !          1056:                        /**/
        !          1057:                        break;
        !          1058:                case 'n':
        !          1059:                        *tp++ = '\n'; break;
        !          1060:                case 'r':
        !          1061:                        *tp++ = '\r'; break;
        !          1062:                case 't':
        !          1063:                        *tp++ = '\t'; break;
        !          1064:                case 'b':
        !          1065:                        *tp++ = '\b'; break;
        !          1066:                case 'f':
        !          1067:                        *tp++ = '\f'; break;
        !          1068:                default:
        !          1069:                        if ((c >= '0') && (c <= '7')) {
        !          1070:                                number = 0;
        !          1071:                                bp--;
        !          1072:                                NEWS(BSLDIG)
        !          1073:                        }
        !          1074:                        *tp++ = c;
        !          1075:                }
        !          1076:                NEWS(pstate)
        !          1077: 
        !          1078:        case BSLDIG:    /* accumulate octal number */
        !          1079:                if ((c >= '0') && (c <= '7')) {
        !          1080:                        number *= 8;
        !          1081:                        number += c - '0';
        !          1082:                        continue;
        !          1083:                }
        !          1084:                if (number > 255) {
        !          1085:                        yyerror("Octal number %ld truncated to char", number);
        !          1086:                        /* An octal number in a string was too big. */
        !          1087:                        number &= 255;
        !          1088:                }
        !          1089:                if (!number) {
        !          1090:                        yyerror("Cannot insert \\0 in string");
        !          1091:                        /* NUL (\e0) terminates strings.
        !          1092:                         * Instead of
        !          1093:                         * .DM
        !          1094:                         *      .byte   "hello\en\e0"
        !          1095:                         * .DE
        !          1096:                         * use:
        !          1097:                         * .DM
        !          1098:                         *      .byte   "hello\en", 0
        !          1099:                         * .DE */
        !          1100:                }
        !          1101:                *tp++ = number;
        !          1102:                bp--;
        !          1103:                NEWS(pstate)
        !          1104: 
        !          1105:        case ENDLINE:
        !          1106:                RSTATE(NL, INITIAL)
        !          1107:        }
        !          1108:     }
        !          1109: }

unix.superglobalmegacorp.com

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