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

1.1       root        1: /* Copyright (c) 1979 Regents of the University of California */
                      2: #include <stdio.h>
                      3: #include "as.h"
                      4: #include "asscan.h"
                      5: 
                      6: extern int     d124;
                      7: extern         struct  exp     *xp;
                      8: 
                      9: struct tokbufdesc *bufstart;           /*where the buffer list begins*/
                     10: struct tokbufdesc *buftail;            /*last one on the list*/
                     11: struct tokbufdesc *emptybuf;           /*the one being filled*/
                     12: 
                     13: #define TOKDALLOP      8
                     14: 
                     15: int    useVM;                          /*keep `tmp' file in virtual memory*/
                     16: int    bufno;                          /*which buffer number: 0,1 for tmp file*/
                     17: struct         tokbufdesc tokbuf[2];           /*our initial increment of buffers*/
                     18:        
                     19: inittmpfile()
                     20: {
                     21:        if (passno == 1){
                     22:                if (useVM){
                     23:                        bufstart = &tokbuf[0];
                     24:                        buftail = &tokbuf[1];
                     25:                        bufstart->tok_next = buftail;
                     26:                        buftail->tok_next = 0;
                     27:                }
                     28:                tokbuf[0].tok_count = -1;
                     29:                tokbuf[1].tok_count = -1;
                     30:        }
                     31:        bufno = 0;
                     32:        emptybuf = &tokbuf[bufno];
                     33:        tokptr = 0;
                     34:        tokub = 0;
                     35: }
                     36: 
                     37: closetmpfile()
                     38: {
                     39:        if (passno == 1){
                     40:                if (useVM){
                     41:                        emptybuf->toks[emptybuf->tok_count++] = PARSEEOF;
                     42:                } else {
                     43:                        /*
                     44:                         *      Clean up the buffers that haven't been
                     45:                         *      written out yet
                     46:                         */
                     47:                        if (tokbuf[bufno ^ 1].tok_count >= 0){
                     48:                                if (fwrite(&tokbuf[bufno ^ 1], sizeof *emptybuf, 1, tmpfil) != 1){
                     49:                                  badwrite:
                     50:                                        yyerror("Unexpected end of file writing the interpass tmp file");
                     51:                                exit(2);
                     52:                                }
                     53:                        }
                     54:                        /*
                     55:                         *      Ensure that we will read an End of file,
                     56:                         *      if there are more than one file names
                     57:                         *      in the argument list
                     58:                         */
                     59:                        tokbuf[bufno].toks[tokbuf[bufno].tok_count++] = PARSEEOF;
                     60:                        if (fwrite(&tokbuf[bufno], sizeof *emptybuf, 1, tmpfil)
                     61:                                        != 1) goto      badwrite;
                     62:                }
                     63:        }       /*end of being pass 1*/
                     64: }
                     65: 
                     66: #define bstrlg(from, length) \
                     67:        *(lgtype *)from = length; \
                     68:        (char *)from += sizeof(lgtype) + length 
                     69: 
                     70: #define bstrfromto(from,to) \
                     71:        *(lgtype *)from = (char *)to - (char *)from - sizeof(lgtype); \
                     72:        (char *)from += sizeof(lgtype) + (char *)to - (char *)from
                     73: 
                     74: #define eatstrlg(from) \
                     75:        (char *)from +=  sizeof(lgtype) + *(lgtype *)from
                     76: 
                     77: #define bskiplg(from, length) \
                     78:        *(lgtype *)from = length; \
                     79:        (char *)from += sizeof(lgtype) + length
                     80: 
                     81: #define bskipfromto(from, to) \
                     82:        *(lgtype *)from = (toktype *)to - (toktype *)from - sizeof(lgtype); \
                     83:        (char *)from += sizeof (lgtype) + (toktype *)to - (toktype *)from
                     84: 
                     85: #define eatskiplg(from) \
                     86:        (toktype *)from += sizeof(lgtype) + *(lgtype *)from
                     87: 
                     88: #ifdef DEBUG
                     89:        ptrall  firsttoken;
                     90: #endif
                     91: 
                     92: extern int             yylval;         /*global communication with parser*/
                     93: 
                     94: toktype yylex()
                     95: {
                     96:        register        ptrall  bufptr; 
                     97:        register        toktype         val;    
                     98:        register        struct  exp     *locxp;
                     99: 
                    100:        bufptr = tokptr;                /*copy in the global value*/
                    101:    top:
                    102:        if (bufptr < tokub){
                    103:                gtoken(val, bufptr);
                    104:                switch(yylval = val){
                    105:                        case    PARSEEOF :
                    106:                                        yylval = val = PARSEEOF;
                    107:                                        break;
                    108:                        case    INT:
                    109:                                        locxp = xp++;
                    110:                                        glong(locxp->xvalue, bufptr);
                    111:                                  makevalue:
                    112:                                        locxp->xtype = XABS;
                    113:                                        locxp->xloc = 0;
                    114:                                        locxp->xname = NULL;
                    115:                                        yylval = (int)locxp;
                    116:                                        break;
                    117:                        case    FLTNUM: /*case patched on 3-Jan-80*/
                    118:                                        locxp = xp++;
                    119:                                        gdouble(locxp->doubval.dvalue, bufptr);
                    120:                                        /*
                    121:                                         *      We make sure that locxp->xvalue
                    122:                                         *      is not in the range suitable for
                    123:                                         *      a short literal.  The field
                    124:                                         *      xvalue is only used for
                    125:                                         *      integers, not doubles, but when
                    126:                                         *      we test for short literals
                    127:                                         *      in ascode.c, we look
                    128:                                         *      at the field xvalue when
                    129:                                         *      it encounters an in line
                    130:                                         *      floating number. Ergo,
                    131:                                         *      give it a bad value.
                    132:                                         */
                    133:                                        locxp->xvalue = -1;
                    134:                                        goto makevalue;
                    135:                        case    NAME:
                    136:                                        gptr(yylval, bufptr);
                    137:                                        lastnam = (struct symtab *)yylval;
                    138:                                        break;
                    139:                        case    SIZESPEC:
                    140:                        case    REG:
                    141:                        case    INSTn:
                    142:                        case    INST0:
                    143:                                        gchar(yylval, bufptr);
                    144:                                        break;
                    145:                        case    IJXXX:
                    146:                                        gchar(yylval, bufptr);
                    147:                                        gptr(lastjxxx, bufptr);
                    148:                                        break;
                    149:                        case    ILINESKIP:
                    150:                                        gint(yylval, bufptr);
                    151:                                        lineno += yylval;
                    152:                                        goto top;
                    153:                        case    SKIP:   
                    154:                                        eatskiplg(bufptr);
                    155:                                        goto top;
                    156:                        case    VOID:   
                    157:                                        goto top;
                    158:                        case    STRING:
                    159:                                        strptr = &strbuf[strno ^= 1];
                    160:                                        strptr->str_lg = *((lgtype *)bufptr);
                    161:                                        movestr(&strptr->str[0],
                    162:                                                (char *)bufptr + sizeof(lgtype),
                    163:                                                strptr->str_lg);
                    164:                                        eatstrlg(bufptr);
                    165:                                        yylval = (int)strptr;
                    166:                                        break;
                    167:                        case    ISTAB:
                    168:                        case    ISTABSTR:
                    169:                        case    ISTABNONE:
                    170:                        case    ISTABDOT:
                    171:                        case    IALIGN:
                    172:                                        gptr(yylval, bufptr);
                    173:                                        break;
                    174:                } /*end of the switch*/
                    175: 
                    176: #ifdef DEBUG
                    177: 
                    178:                if (toktrace)
                    179:                switch(val){
                    180:                        case    INT:    printf("Class integer val %d\n",
                    181:                                                ((struct exp *)yylval)->xvalue);
                    182:                                        break;
                    183:                        case    FLTNUM: printf("Class floating point num value %4.3f\n",
                    184:                                        ((struct exp *)yylval) -> doubval.dvalue);
                    185:                                        break;
                    186:                        case    NAME:   printf("Class name, \"%.8s\"\n",
                    187:                                                ((struct symtab *)yylval)->name);
                    188:                                        break;
                    189:                        case    REG:    printf("Class register, number %d\n",
                    190:                                                yylval);
                    191:                                        break;
                    192:                        case    INSTn:  printf("Class INSTn, %.8s\n",
                    193:                                                itab[0xFF &yylval]->name);
                    194:                                        break;
                    195:                        case    IJXXX:  printf("Class IJXXX, %.8s\n",
                    196:                                                itab[0xFF &yylval]->name);
                    197:                                        break;
                    198:                        case    INST0:  printf("Class INST0, %.8s\n",
                    199:                                                itab[0xFF &yylval]->name);
                    200:                                        break;
                    201:                        case    STRING: printf("Class string, length %d\n",
                    202:                                                ((struct strdesc *)yylval)->str_lg);
                    203:                                        break;
                    204:                        default:        printf("Pass: %d Tok: %d Other class: %d, 0%o, '%c'\n",
                    205:                                                passno,
                    206:                                                bufptr -  firsttoken,
                    207:                                                val,val, val);
                    208:                                        break;
                    209:                }               /*end of the debug switch*/
                    210: #endif
                    211: 
                    212:        }       /*end of this buffer*/
                    213:        else {
                    214:                if (useVM){
                    215:                        bufno += 1;
                    216:                        emptybuf = emptybuf->tok_next;
                    217:                        if (emptybuf == 0){
                    218:                                struct  tokbufdesc *newdallop;
                    219:                                int     i;
                    220:                                if (passno == 2)
                    221:                                        goto badread;
                    222:                                emptybuf = newdallop = 
                    223:                                  (struct tokbufdesc *)sbrk(
                    224:                                        TOKDALLOP*sizeof (struct tokbufdesc));
                    225:                                if (emptybuf == (struct tokbufdesc *)-1)
                    226:                                        goto badwrite;
                    227:                                for (i=0; i < TOKDALLOP; i++){
                    228:                                        buftail->tok_next = newdallop;
                    229:                                        buftail = newdallop;
                    230:                                        newdallop += 1;
                    231:                                }
                    232:                                buftail->tok_next = 0;
                    233:                        }       /*end of need to get more buffers*/
                    234:                        (toktype *)bufptr = &(emptybuf->toks[0]);
                    235:                        if (passno == 1)
                    236:                                scan_dot_s(emptybuf);
                    237:                } else {        /*don't use VM*/
                    238:                        bufno ^= 1;
                    239:                        emptybuf = &tokbuf[bufno];
                    240:                        ((toktype *)bufptr) = &(emptybuf->toks[0]);
                    241:                        if (passno == 1){
                    242:                                /*
                    243:                                 *      First check if there are things to write
                    244:                                 *      out at all
                    245:                                 */
                    246:                                if (emptybuf->tok_count >= 0){
                    247:                                        if (fwrite(emptybuf, sizeof *emptybuf, 1, tmpfil) != 1){
                    248:                                          badwrite:
                    249:                                                yyerror("Unexpected end of file writing the interpass tmp file");
                    250:                                                exit(2);
                    251:                                        }
                    252:                                }
                    253:                                scan_dot_s(emptybuf);
                    254:                        } else {        /*pass 2*/
                    255:                                if (fread(emptybuf, sizeof *emptybuf, 1, tmpfil) != 1){
                    256:                                  badread:
                    257:                                        yyerror("Unexpected end of file while reading the interpass tmp file");
                    258:                                        exit(1);
                    259:                                }
                    260:                        }       /*end of pass2*/
                    261:                }       /*end of using a real live file*/
                    262:                (char *)tokub = (char *)bufptr + emptybuf->tok_count;
                    263: #ifdef DEBUG
                    264:                firsttoken = bufptr;
                    265:                if (debug)
                    266:                        printf("created buffernumber %d with %d tokens\n",
                    267:                                bufno, emptybuf->tok_count);
                    268: #endif
                    269:                        goto top;
                    270:        }       /*end of reading/creating a new buffer*/
                    271:        tokptr = bufptr;                /*copy back the global value*/
                    272:        return(val);
                    273: }      /*end of yylex*/
                    274: 
                    275: 
                    276: buildskip(from, to)
                    277:        register        ptrall  from, to;
                    278: {
                    279:        int     diff;
                    280:        register        int     frombufno;
                    281:        register        struct  tokbufdesc *middlebuf;
                    282:        /*
                    283:         *      check if from and to are in the same buffer
                    284:         *      from and to DIFFER BY AT MOST 1 buffer and to is
                    285:         *      always ahead of from, with to being in the buffer emptybuf
                    286:         *      points to.
                    287:         *      The hard part here is accounting for the case where the
                    288:         *      skip is to cross a buffer boundary; we must construct
                    289:         *      two skips.
                    290:         *
                    291:         *      Figure out where the buffer boundary between from and to is
                    292:         *      It's easy in VM, as buffers increase to high memory, but
                    293:         *      w/o VM, we alternate between two buffers, and want
                    294:         *      to look at the exact middle of the contiguous buffer region.
                    295:         */
                    296:        middlebuf = useVM ? emptybuf : &tokbuf[1];
                    297:        if (  ( (toktype *)from > (toktype *)middlebuf)
                    298:            ^ ( (toktype *)to > (toktype *)middlebuf)
                    299:           ){   /*split across a buffer boundary*/
                    300:                ptoken(from, SKIP);
                    301:                /*
                    302:                 *      Set the skip so it lands someplace beyond
                    303:                 *      the end of this buffer.
                    304:                 *      When we pull this skip out in the second pass,
                    305:                 *      we will temporarily move the current pointer
                    306:                 *      out beyond the end of the buffer, but immediately
                    307:                 *      do a compare and fail the compare, and then reset
                    308:                 *      all the pointers correctly to point into the next buffer.
                    309:                 */
                    310:                bskiplg(from,  TOKBUFLG + 1);
                    311:                /*
                    312:                 *      Now, force from to be in the same buffer as to
                    313:                 */
                    314:                (toktype *)from = (toktype *)&(emptybuf->toks[0]);
                    315:        }
                    316:        /*
                    317:         *      Now, to and from are in the same buffer
                    318:         */
                    319:        if (from > to)
                    320:                yyerror("Internal error: bad skip construction");
                    321:        else {
                    322:                if ( (diff = (toktype *)to - (toktype *)from) >= 
                    323:                        (sizeof(toktype) + sizeof(lgtype) + 1)) {
                    324:                                ptoken(from, SKIP);
                    325:                                bskipfromto(from, to);
                    326:                } else {
                    327:                        for ( ; diff > 0; --diff)
                    328:                                ptoken(from, VOID);
                    329:                }
                    330:        }
                    331: }
                    332: 
                    333: movestr(to, from, lg)
                    334:        register        char    *to, *from;
                    335:        register        int     lg;
                    336: {
                    337:        if (lg <= 0) return;
                    338:        do
                    339:                *to++ = *from++;
                    340:        while (--lg);
                    341: }
                    342: static int     newfflag = 0;
                    343: static char    *newfname;
                    344: int    scanlineno;             /*the scanner's linenumber*/
                    345: 
                    346: new_dot_s(namep)
                    347:        char    *namep;
                    348: {
                    349:        newfflag = 1;
                    350:        newfname = namep;
                    351:        dotsname = namep;
                    352:        lineno = 1;
                    353:        scanlineno = 1;
                    354: }
                    355: 
                    356: /*
                    357:  *     Maps characters to their use in assembly language
                    358:  */
                    359: #define EOFCHAR        (-1)
                    360: #define        NEEDCHAR (-2)
                    361: 
                    362: readonly short type[] = {
                    363:        NEEDSBUF,               /*fill up the input buffer*/
                    364:        SCANEOF,                /*hit the hard end of file*/
                    365:        SP,     BADCHAR,BADCHAR,BADCHAR,BADCHAR,BADCHAR,BADCHAR,BADCHAR,   /*\0..^G*/
                    366:        BADCHAR,SP,     NL,     BADCHAR,BADCHAR,SP,     BADCHAR,BADCHAR,   /*BS..SI*/
                    367:        BADCHAR,BADCHAR,BADCHAR,BADCHAR,BADCHAR,BADCHAR,BADCHAR,BADCHAR,   /*DLE..ETB*/
                    368:        BADCHAR,BADCHAR,BADCHAR,BADCHAR,BADCHAR,BADCHAR,BADCHAR,BADCHAR,   /*CAN..US*/
                    369:        SP,     ORNOT,  DQ,     SH,     LITOP,  REGOP,  AND,    SQ,  /*sp .. '*/
                    370:        LP,     RP,     MUL,    PLUS,   CM,     MINUS,  ALPH,   DIV, /*( .. /*/
                    371:        DIG,    DIG,    DIG,    DIG,    DIG,    DIG,    DIG,    DIG, /*0 .. 7*/
                    372:        DIG,    DIG,    COLON,  SEMI,   LSH,    BADCHAR,RSH,    BADCHAR, /*8 .. ?*/
                    373:        BADCHAR,ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,/*@ .. G*/
                    374:        ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,/*H .. BADCHAR*/
                    375:        ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,/*P .. V*/
                    376:        ALPH,   ALPH,   ALPH,   LB,     BADCHAR,RB,     XOR,    ALPH,/*W .. _*/
                    377:        SIZEQUOTE,ALPH, ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,/*` .. g*/
                    378:        ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,/*h .. o*/
                    379:        ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,/*p .. v*/
                    380:        ALPH,   ALPH,   ALPH,   BADCHAR,IOR,    BADCHAR,TILDE,  BADCHAR,/*x .. del*/
                    381: };
                    382: 
                    383: /*
                    384:  *     The table of possible uses for each character to test set inclusion.
                    385:  *     Different than the above table, which knows about tokens yylex
                    386:  *     is to return.
                    387:  */
                    388: #define        HEXFLAG         01              /* 'x' or 'X' */
                    389: #define        HEXLDIGIT       02              /* 'a' .. 'f' */
                    390: #define HEXUDIGIT      04              /* 'A' .. 'F' */
                    391: #define        ALPHA           010             /* 'A' .. 'Z', 'a' .. 'z', '_'*/
                    392: #define DIGIT          020             /* '0' .. '9' */
                    393: #define        FLOATEXP        040             /* 'd' 'e' 'D' 'E' */
                    394:                                                /*exponent field*/
                    395: #define SIGN           0100            /* '+' .. '-'*/
                    396: #define REGDIGIT       0200            /* '0' .. '5' */
                    397: #define SZSPECBEGIN    0400            /* 'b', 'B', 'l', 'L', 'w', 'W' */
                    398: #define POINT          01000           /* '.' */
                    399: #define SPACE          02000           /* '\t' or ' ' */
                    400: #define BSESCAPE       04000           /* bnrtf */
                    401: #define STRESCAPE      010000          /* '"', '\\', '\n' */
                    402: #define OCTDIGIT       020000          /* '0' .. '7' */
                    403: #define        FLOATFLAG       040000          /* 'd', 'D', 'f', 'F' */
                    404:                                                /*after leading 0*/
                    405: 
                    406: readonly short charsets[] = {
                    407:        0,      0,      0,      0,      0,      0,      0,      0,   /*\0..^G*/
                    408:        0,      SPACE,  STRESCAPE,0,    0,      0,      0,      0,   /*BS..SI*/
                    409:        0,      0,      0,      0,      0,      0,      0,      0,   /*DLE..ETB*/
                    410:        0,      0,      0,      0,      0,      0,      0,      0,   /*CAN..US*/
                    411:        SPACE,  0,      STRESCAPE,0,    0,      0,      0,      0,   /*sp.. '*/
                    412:        0,      0,      0,      SIGN,   0,      SIGN,   POINT+ALPHA,0, /*( .. /*/
                    413:        DIGIT+REGDIGIT+OCTDIGIT,        DIGIT+REGDIGIT+OCTDIGIT,     /*0..1*/
                    414:        DIGIT+REGDIGIT+OCTDIGIT,        DIGIT+REGDIGIT+OCTDIGIT,     /*2..3*/
                    415:        DIGIT+REGDIGIT+OCTDIGIT,        DIGIT+REGDIGIT+OCTDIGIT,     /*4..5*/
                    416:        DIGIT+OCTDIGIT,                 DIGIT+OCTDIGIT,              /*6..7*/
                    417:        DIGIT,  DIGIT,  0,      0,      0,      0,      0,      0,   /*8..?*/
                    418:        0,                                                           /*@*/
                    419:        ALPHA+HEXUDIGIT,ALPHA+HEXUDIGIT+SZSPECBEGIN,                 /*A..B*/
                    420:        ALPHA+HEXUDIGIT,ALPHA+HEXUDIGIT+FLOATEXP+FLOATFLAG,          /*C..D*/
                    421:        ALPHA+HEXUDIGIT+FLOATEXP,ALPHA+HEXUDIGIT+FLOATFLAG,          /*E..F*/
                    422:        ALPHA,                                                       /*G*/
                    423:        ALPHA,                  ALPHA,  ALPHA,  ALPHA,               /*H..K*/
                    424:        ALPHA+SZSPECBEGIN,      ALPHA,  ALPHA,  ALPHA,               /*L..O*/
                    425:        ALPHA,                  ALPHA,  ALPHA,  ALPHA,               /*P..S*/
                    426:        ALPHA,                  ALPHA,  ALPHA,  ALPHA+SZSPECBEGIN,   /*T..W*/
                    427:        ALPHA+HEXFLAG,  ALPHA,  ALPHA,  0,STRESCAPE,0,  0,      ALPHA,/*X.._*/
                    428: 
                    429:        0,
                    430:        ALPHA+HEXLDIGIT,ALPHA+HEXLDIGIT+BSESCAPE+SZSPECBEGIN,         /*a..b*/
                    431:        ALPHA+HEXLDIGIT,ALPHA+HEXLDIGIT+FLOATEXP+FLOATFLAG,           /*c..d*/
                    432:        ALPHA+HEXLDIGIT+FLOATEXP,ALPHA+HEXLDIGIT+BSESCAPE+FLOATFLAG,  /*e..f*/
                    433:        ALPHA,                                                        /*g*/
                    434:        ALPHA,                  ALPHA,  ALPHA,          ALPHA,        /*h..k*/
                    435:        ALPHA+SZSPECBEGIN,      ALPHA,  ALPHA+BSESCAPE, ALPHA,        /*l..o*/
                    436:        ALPHA,                  ALPHA,  ALPHA+BSESCAPE, ALPHA,        /*p..s*/
                    437:        ALPHA+BSESCAPE,         ALPHA,  ALPHA,          ALPHA+SZSPECBEGIN,/*t..w*/
                    438:        ALPHA+HEXFLAG,  ALPHA,  ALPHA,  0,0,    0,      0,      0,    /*x..del*/
                    439: 0};
                    440: 
                    441: #define INCHARSET(val, kind) (charsets[val] & (kind) )
                    442: static toktype oval = NL;
                    443: 
                    444: #define INBUFLG 2 + 2*BUFSIZ + 128
                    445: static char    inbuffer[INBUFLG];
                    446: static char    *InBufPtr = 0;
                    447: 
                    448: #ifdef  getchar
                    449: #undef getchar
                    450: #endif
                    451: #define getchar() *inbufptr++
                    452: 
                    453: #ifdef  ungetc
                    454: #undef ungetc
                    455: #endif
                    456: #define        ungetc(char, fileptr) *--inbufptr = char
                    457: 
                    458: char *fillinbuffer()
                    459: {
                    460:        register        char    *cp, *inbufptr;
                    461:        int             nread;
                    462: 
                    463:        inbufptr = &inbuffer[2];        /*allow enough room for two ungetcs*/
                    464:        nread = fread(inbufptr, 1, 2*BUFSIZ, stdin);
                    465:        if (nread == 2*BUFSIZ){
                    466:                cp = fgets(inbufptr+2*BUFSIZ, 128, stdin);      /*get next whole line*/
                    467:                if (cp != 0){
                    468:                        while(*cp++);   /*find the trailing null*/
                    469:                        *--cp = NEEDCHAR;       /*clobber with a NEED character*/
                    470:                        return(inbufptr);
                    471:                } else {
                    472:                        *(inbufptr + 2*BUFSIZ) = EOFCHAR;
                    473:                        return(inbufptr);
                    474:                }
                    475:        } else {
                    476:                if (nread == 0)         /*hard end of file*/
                    477:                        return(0);
                    478:                inbuffer[2+nread] = EOFCHAR;
                    479:                return(inbufptr);
                    480:        }
                    481: }
                    482: 
                    483: scan_dot_s(bufferbox)
                    484:        struct tokbufdesc *bufferbox;
                    485: {
                    486:        register int            yylval;/*lexical value*/
                    487:        register toktype        val;    /*the value returned; the character read*/
                    488:        register int    base;           /*the base of the number also counter*/
                    489:        register        char    *cp;    
                    490:        register        char    *inbufptr;
                    491:        register        struct          symtab  *op;
                    492:        register        unsigned        char    tag;
                    493: 
                    494:        register        ptrall  bufptr;         /*where to stuff tokens*/
                    495:                        ptrall  lgbackpatch;    /*where to stuff a string length*/
                    496:                        ptrall  bufub;          /*where not to stuff tokens*/
                    497:        register        int     maxstrlg;       /*how long a string can be*/
                    498:                        long    intval;         /*value of int*/
                    499:                        char    fltchr[64];     /*buffer for floating values*/
                    500:                        double  fltval;         /*floating value returned*/
                    501:                        int     linescrossed;   /*when doing strings and comments*/
                    502: 
                    503:        inbufptr = InBufPtr;
                    504:        if (inbufptr == 0){
                    505:                inbufptr = fillinbuffer();
                    506:                if (inbufptr == 0){     /*end of file*/
                    507:                  endoffile:
                    508:                        inbufptr = 0;
                    509:                        ptoken(bufptr, PARSEEOF);
                    510:                        goto done;
                    511:                }
                    512:        }
                    513: 
                    514:        (toktype *)bufptr = (toktype *) & (bufferbox->toks[0]); 
                    515:        (toktype *)bufub = &(bufferbox->toks[AVAILTOKS]);
                    516: 
                    517:        if (newfflag){
                    518: #ifdef DEBUG
                    519:        if (debug)
                    520:                printf(">>>>>>>>>>>>>(scanner) Starting to insert tokens into a new file: %s\n",
                    521:                                newfname);
                    522: #endif
                    523:                ptoken(bufptr, IFILE);
                    524:                ptoken(bufptr, STRING);
                    525:                val = strlen(newfname) + 1;
                    526:                movestr( (char *)&( ( (lgtype *)bufptr)[1]), newfname, val);
                    527:                bstrlg(bufptr, val);
                    528: 
                    529:                ptoken(bufptr, ILINENO);
                    530:                ptoken(bufptr, INT);
                    531:                pint(bufptr,  1);
                    532:                newfflag = 0;
                    533:        }
                    534: 
                    535:        while (bufptr < bufub){
                    536:    loop:
                    537:            switch(yylval = (type+2)[val = getchar()]) {
                    538:                case SCANEOF:
                    539:                        inbufptr = 0;
                    540:                        goto endoffile;
                    541: 
                    542:                case NEEDSBUF:
                    543:                        inbufptr = fillinbuffer();
                    544:                        if (inbufptr == 0)
                    545:                                goto endoffile;
                    546:                        goto loop;
                    547: 
                    548:                case DIV:               /*process C style comments*/
                    549:                        if ( (val = getchar()) == '*') {  /*comment prelude*/
                    550:                                int     incomment;
                    551:                                linescrossed = 0;
                    552:                                incomment = 1;
                    553:                                val = getchar();        /*skip over the * */
                    554:                                do{
                    555:                                        while ( (val != '*') &&
                    556:                                                (val != '\n') &&
                    557:                                                (val != EOFCHAR) &&
                    558:                                                (val != NEEDCHAR))
                    559:                                                        val = getchar();
                    560:                                        if (val == '\n'){
                    561:                                                scanlineno++;
                    562:                                                linescrossed++;
                    563:                                        } else
                    564:                                        if (val == EOFCHAR)
                    565:                                                goto endoffile;
                    566:                                        if (val == NEEDCHAR){
                    567:                                                inbufptr = fillinbuffer();
                    568:                                                if (inbufptr == 0)
                    569:                                                        goto endoffile;
                    570:                                                lineno++;
                    571:                                                incomment = 1;
                    572:                                                val = getchar(); /*pull in the new char*/
                    573:                                        } else {        /*its a star */
                    574:                                                val = getchar();
                    575:                                                incomment = val != '/';
                    576:                                        }
                    577:                                } while (incomment);
                    578:                                val = ILINESKIP;
                    579:                                yylval = linescrossed;
                    580:                                goto ret;
                    581:                        } else {        /*just an ordinary DIV*/
                    582:                                ungetc(val, stdin);
                    583:                                val = yylval = DIV;
                    584:                                goto ret;
                    585:                        }
                    586:                case SH:
                    587:                        if (oval == NL){
                    588:                                /*
                    589:                                 *      Attempt to recognize a C preprocessor
                    590:                                 *      style comment '^#[ \t]*[0-9]*[ \t]*".*"
                    591:                                 */
                    592:                                val = getchar();        /*bump the #*/
                    593:                                while (INCHARSET(val, SPACE))
                    594:                                        val = getchar();/*bump white */
                    595:                                if (INCHARSET(val, DIGIT)){
                    596:                                        intval = 0;
                    597:                                        while(INCHARSET(val, DIGIT)){
                    598:                                                intval = intval *10 + val - '0';
                    599:                                                val = getchar();
                    600:                                        }
                    601:                                        while (INCHARSET(val, SPACE))
                    602:                                                val = getchar();
                    603:                                        if (val == '"'){
                    604:                                                ptoken(bufptr, ILINENO);
                    605:                                                ptoken(bufptr, INT);
                    606:                                                pint(bufptr, intval - 1);
                    607:                                                ptoken(bufptr, IFILE);
                    608:                                                /*
                    609:                                                 *      The '"' has already been
                    610:                                                 *      munched
                    611:                                                 *      
                    612:                                                 *      eatstr will not eat
                    613:                                                 *      the trailing \n, so
                    614:                                                 *      it is given to the parser
                    615:                                                 *      and counted.
                    616:                                                 */
                    617:                                                goto eatstr;
                    618:                                        }
                    619:                                }
                    620:                        }
                    621:                        /*
                    622:                         *      Well, its just an ordinary decadent comment
                    623:                         */
                    624:                        while ((val != '\n') && (val != EOFCHAR)) 
                    625:                                val = getchar();
                    626:                        if (val == EOFCHAR)
                    627:                                goto endoffile;
                    628:                        val = yylval = oval = NL;
                    629:                        scanlineno++;
                    630:                        goto ret;
                    631:        
                    632:                case NL:
                    633:                        scanlineno++;
                    634:                        val = yylval;
                    635:                        goto ret;
                    636: 
                    637:                case SP:
                    638:                        oval = SP;      /*invalidate ^# meta comments*/
                    639:                        goto loop;
                    640:        
                    641:                case REGOP:             /* % , could be used as modulo, or register*/
                    642:                        val = getchar();
                    643:                        if (INCHARSET(val, DIGIT)){
                    644:                                yylval = val-'0';
                    645:                                if (val=='1') {
                    646:                                        if (INCHARSET( (val = getchar()), REGDIGIT))
                    647:                                                yylval = 10+val-'0';
                    648:                                        else
                    649:                                                ungetc(val, stdin);
                    650:                                }
                    651:                                /*
                    652:                                 *      God only knows what the original author
                    653:                                 *      wanted this undocumented feature to
                    654:                                 *      do.
                    655:                                 *              %5++ is really  r7
                    656:                                 */
                    657:                                while(INCHARSET( (val = getchar()), SIGN)) {
                    658:                                        if (val=='+')
                    659:                                                yylval++;
                    660:                                        else
                    661:                                                yylval--;
                    662:                                }
                    663:                                ungetc(val, stdin);
                    664:                                val = REG;
                    665:                        } else {
                    666:                                ungetc(val, stdin);
                    667:                                val = REGOP;
                    668:                        }
                    669:                        goto ret;
                    670:        
                    671:                case ALPH:
                    672:                        yylval = val;
                    673:                        if (INCHARSET(val, SZSPECBEGIN)){
                    674:                                if( (val = getchar()) == '`' || val == '^'){
                    675:                                        yylval |= 0100; /*convert to lower*/
                    676:                                        if (yylval == 'b') yylval = 1;
                    677:                                        else if (yylval == 'w') yylval = 2;
                    678:                                        else if (yylval == 'l') yylval = 4;
                    679:                                        else                    yylval = d124;
                    680:                                        val = SIZESPEC;
                    681:                                        goto ret;
                    682:                                } else {
                    683:                                        ungetc(val, stdin);
                    684:                                        val = yylval;   /*restore first character*/
                    685:                                }
                    686:                        }
                    687:                        cp = yytext;
                    688:                        do {
                    689:                                if (cp < &yytext[NCPS])
                    690:                                        *cp++ = val;
                    691:                        } while (INCHARSET ( (val = getchar()), ALPHA | DIGIT));
                    692:                        *cp = '\0';
                    693:                        while (INCHARSET(val, SPACE))
                    694:                                val = getchar();
                    695:                        ungetc(val, stdin);
                    696:                        tag = (op = *lookup(1))->tag;
                    697:                        if (tag && tag != LABELID){
                    698:                                yylval = ( (struct instab *)op)->opcode;
                    699:                                val = op->tag ;
                    700:                                goto ret;
                    701:                        } else {
                    702:                                /*
                    703:                                 *      Its a name... (Labels are subsets ofname)
                    704:                                 */
                    705:                                yylval = (int)op;
                    706:                                val = NAME;
                    707:                                goto ret;
                    708:                        }
                    709:        
                    710:                case DIG:
                    711:                        intval = val-'0';
                    712:                        if (val=='0') {
                    713:                                val = getchar();
                    714:                                if (INCHARSET(val, HEXFLAG)){
                    715:                                        base = 16;
                    716:                                } else
                    717:                                if (INCHARSET(val, FLOATFLAG)){
                    718:                                        char *p = fltchr;
                    719:                                        double atof();
                    720:        
                    721:                                        while ( (p < &fltchr[63]) &&
                    722:                                                INCHARSET(
                    723:                                                        (val=getchar()),
                    724:                                                        (DIGIT|SIGN|FLOATEXP|POINT)
                    725:                                                      )
                    726:                                              ) *p++ = val;
                    727:                                        ungetc(val, stdin);
                    728:                                        *p++ = '\0';
                    729:                                        fltval = atof(fltchr);
                    730:                                        val = FLTNUM;
                    731:                                        goto ret;
                    732:                                } else {
                    733:                                        ungetc(val, stdin);
                    734:                                        base = 8;
                    735:                                }
                    736:                        } else
                    737:                                base = 10;
                    738:                        while ( INCHARSET( (val = getchar()), DIGIT) || 
                    739:                                (base==16 && (INCHARSET(val, HEXLDIGIT|HEXUDIGIT) )
                    740:                                   )
                    741:                              ){
                    742:                                if (base==8)
                    743:                                        intval <<= 3;
                    744:                                else if (base==10)
                    745:                                        intval *= 10;
                    746:                                else {
                    747:                                        intval <<= 4;
                    748:                                        if (INCHARSET(val, HEXLDIGIT))
                    749:                                                val -= 'a' - 10 - '0';
                    750:                                        else if (INCHARSET(val, HEXUDIGIT))
                    751:                                                val -= 'A' - 10 - '0';
                    752:                                }
                    753:                                intval += val-'0';
                    754:                        }
                    755:                        ungetc(val, stdin);
                    756:                        val = INT;
                    757:                        goto ret;
                    758:        
                    759:                case LSH:
                    760:                case RSH:
                    761:                        /*
                    762:                         *      We allow the C style operators
                    763:                         *      << and >>, as well as < and >
                    764:                         */
                    765:                        if ( (base = getchar()) != val)
                    766:                                ungetc(base, stdin);
                    767:                        val = yylval;
                    768:                        goto ret;
                    769: 
                    770:                case MINUS:
                    771:                        if ( (val = getchar()) =='(')
                    772:                                yylval=val=MP;
                    773:                        else {
                    774:                                ungetc(val,stdin);
                    775:                                val=MINUS;
                    776:                        }
                    777:                        goto ret;
                    778:        
                    779:                case SQ:
                    780:                        if ((yylval = getchar()) == '\n')
                    781:                                scanlineno++;           /*not entirely correct*/
                    782:                        intval = yylval;
                    783:                        val = INT;
                    784:                        goto ret;
                    785:        
                    786:                case DQ:
                    787:                   eatstr:
                    788:                        linescrossed = 0;
                    789:                        maxstrlg = (char *)bufub - (char *)bufptr;
                    790: 
                    791:                        if (maxstrlg < MAXSTRLG) {
                    792:                                ungetc('"', stdin);
                    793:                                *(toktype *)bufptr = VOID ;
                    794:                                bufub = bufptr;
                    795:                                goto done;
                    796:                        }
                    797:                        if (maxstrlg > MAXSTRLG)
                    798:                                maxstrlg = MAXSTRLG;
                    799:                        
                    800:                        ptoken(bufptr, STRING);
                    801:                        lgbackpatch = bufptr;   /*this is where the size goes*/
                    802:                        bufptr += sizeof(lgtype);
                    803:                        /*
                    804:                         *      bufptr is now set to
                    805:                         *      be stuffed with characters from
                    806:                         *      the input
                    807:                         */
                    808: 
                    809:                        while (   (maxstrlg > 0)
                    810:                               && !(INCHARSET( (val = getchar()), STRESCAPE))
                    811:                              ){
                    812:                                stuff:
                    813:                                        maxstrlg-= 1;
                    814:                                        pchar(bufptr, val);
                    815:                                }
                    816:                        if (maxstrlg <= 0){     /*enough characters to fill a string buffer*/
                    817:                                ungetc('"', stdin);             /*will read it next*/
                    818:                        }
                    819:                        else if (val == '"');           /*done*/
                    820:                        else if (val == '\n'){
                    821:                                scanlineno++;
                    822:                                linescrossed++;
                    823:                                goto stuff;
                    824:                        } else {
                    825:                                val = getchar();                /*skip the '\\'*/
                    826:                                if ( INCHARSET(val, BSESCAPE)){
                    827:                                        switch (val){
                    828:                                          case 'b':  val = '\b'; goto stuff;
                    829:                                          case 'f':  val = '\f'; goto stuff;
                    830:                                          case 'n':  val = '\n'; goto stuff;
                    831:                                          case 'r':  val = '\r'; goto stuff;
                    832:                                          case 't':  val = '\t'; goto stuff;
                    833:                                        }
                    834:                                }
                    835:                                if ( !(INCHARSET(val,OCTDIGIT)) )  goto stuff;
                    836:                                base = 0;
                    837:                                intval = 0;
                    838:                                while ( (base < 3) && (INCHARSET(val, OCTDIGIT))){
                    839:                                        base++;intval <<= 3;intval += val - '0';
                    840:                                        val = getchar();
                    841:                                }
                    842:                                ungetc(val, stdin);
                    843:                                val = (char)intval;
                    844:                                goto stuff;
                    845:                        }
                    846:                        /*
                    847:                         *      bufptr now points at the next free slot
                    848:                         */
                    849:                        bstrfromto(lgbackpatch, bufptr);
                    850:                        if (linescrossed){
                    851:                                val = ILINESKIP;
                    852:                                yylval = linescrossed;
                    853:                                goto ret;
                    854:                        } else
                    855:                                goto builtval;
                    856:        
                    857:                case BADCHAR:
                    858:                        linescrossed = lineno;
                    859:                        lineno = scanlineno;
                    860:                        yyerror("Illegal character mapped: %d, char read:(octal) %o",
                    861:                                yylval, val);
                    862:                        lineno = linescrossed;
                    863:                        val = BADCHAR;
                    864:                        goto ret;
                    865:        
                    866:                default:
                    867:                        val = yylval;
                    868:                        goto ret;
                    869:                }       /*end of the switch*/
                    870:        /*
                    871:         *      here with one token, so stuff it
                    872:         */
                    873:        ret:    
                    874:        oval = val;
                    875:        ptoken(bufptr, val);
                    876:        switch(val){
                    877:                case    ILINESKIP:
                    878:                                pint(bufptr, yylval);
                    879:                                break;
                    880:                case    SIZESPEC:
                    881:                                pchar(bufptr, yylval);
                    882:                                break;
                    883:                case    INT:    plong(bufptr, intval);
                    884:                                break;
                    885:                case    FLTNUM: pdouble(bufptr, fltval);
                    886:                                break;
                    887:                case    NAME:   pptr(bufptr, (int)(struct symtab *)yylval);
                    888:                                break;
                    889:                case    REG:    pchar(bufptr, yylval);
                    890:                                break;  
                    891:                case    INST0:
                    892:                case    INSTn:
                    893:                                pchar(bufptr, yylval);
                    894:                                break;
                    895:                case    IJXXX:
                    896:                                pchar(bufptr, yylval);
                    897:                                pptr(bufptr, (int)(struct symtab *)symalloc());
                    898:                                break;
                    899:                case    ISTAB:
                    900:                case    ISTABSTR:
                    901:                case    ISTABNONE:
                    902:                case    ISTABDOT:
                    903:                case    IALIGN:
                    904:                                pptr(bufptr, (int)(struct symtab *)symalloc());
                    905:                                break;
                    906:        /*
                    907:         *      default:
                    908:         */
                    909:         }
                    910:         builtval: ;
                    911:    }                   /*end of the while to stuff the buffer*/
                    912:    done:
                    913:        bufferbox->tok_count = (toktype *)bufptr - &(bufferbox->toks[0]);
                    914: 
                    915:        /*
                    916:         *      This is a real kludge:
                    917:         *
                    918:         *      We put the last token in the buffer to be  a MINUS
                    919:         *      symbol.  This last token will never be picked up
                    920:         *      in the normal way, but can be looked at during
                    921:         *      a peekahead look that the short circuit expression
                    922:         *      evaluator uses to see if an expression is complicated.
                    923:         *
                    924:         *      Consider the following situation:
                    925:         *
                    926:         *      .word   45              +       47
                    927:         *        buffer 1      |  buffer 0
                    928:         *      the peekahead would want to look across the buffer,
                    929:         *      but will look in the buffer end zone, see the minus, and
                    930:         *      fail.
                    931:         */
                    932:        ptoken(bufptr, MINUS);
                    933:        InBufPtr = inbufptr;            /*copy this back*/
                    934: }

unix.superglobalmegacorp.com

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