Annotation of 3BSD/cmd/as/asscan.c, revision 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.