Annotation of 43BSD/bin/as/asscan2.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1982 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  */
        !             6: 
        !             7: #ifndef lint
        !             8: static char sccsid[] = "@(#)asscan2.c  5.1 (Berkeley) 4/30/85";
        !             9: #endif not lint
        !            10: 
        !            11: #include "asscanl.h"
        !            12: 
        !            13: static inttoktype      oval = NL;
        !            14: #define        ASINBUFSIZ      4096
        !            15: char   inbufunget[8];
        !            16: char   inbuffer[ASINBUFSIZ];
        !            17: char   *Ginbufptr = inbuffer;
        !            18: int    Ginbufcnt = 0;
        !            19: int    scannerhadeof;
        !            20: 
        !            21: fillinbuffer()
        !            22: {
        !            23:                int     nread;
        !            24:                int     goal;
        !            25:                int     got;
        !            26: 
        !            27:        nread = 0;
        !            28:        if (scannerhadeof == 0){
        !            29:                goal = sizeof(inbuffer);
        !            30:                do {
        !            31:                        got = read(stdin->_file, inbuffer + nread, goal);
        !            32:                        if (got == 0)
        !            33:                                scannerhadeof = 1;
        !            34:                        if (got <= 0)
        !            35:                                break;
        !            36:                        nread += got;
        !            37:                        goal -= got;
        !            38:                } while (goal);
        !            39:        } else {
        !            40:                scannerhadeof = 0;
        !            41:        }
        !            42:        /*
        !            43:         *      getchar assumes that Ginbufcnt and Ginbufptr
        !            44:         *      are adjusted as if one character has been removed
        !            45:         *      from the input.
        !            46:         */
        !            47:        if (nread == 0){
        !            48:                inbuffer[0] = EOFCHAR;
        !            49:                nread = 1;
        !            50:        }
        !            51:        Ginbufcnt = nread - 1;
        !            52:        Ginbufptr = inbuffer + 1;
        !            53: }
        !            54: 
        !            55: scan_dot_s(bufferbox)
        !            56:        struct tokbufdesc *bufferbox;
        !            57: {
        !            58:        reg     char    *inbufptr;
        !            59:        reg     int     inbufcnt;
        !            60:        reg     int     ryylval;        /* local copy of lexical value */
        !            61:        extern  int     yylval;         /* global copy of lexical value */
        !            62:        reg     int     val;            /* the value returned */
        !            63:                int     i;              /* simple counter */
        !            64:        reg     char    *rcp;   
        !            65:                int     ch;             /* treated as a character */
        !            66:                int     ch1;            /* shadow value */
        !            67:                struct  symtab  *op;
        !            68:                ptrall  lgbackpatch;    /* where to stuff a string length */
        !            69:        reg     ptrall  bufptr;         /* where to stuff tokens */
        !            70:                ptrall  bufub;          /* where not to stuff tokens */
        !            71:                long    intval;         /* value of int */
        !            72:                int     linescrossed;   /* when doing strings and comments */
        !            73:                struct  Opcode          opstruct;
        !            74:        reg     int     strlg;          /* the length of a string */
        !            75: 
        !            76:        (bytetoktype *)bufptr = (bytetoktype *) & (bufferbox->toks[0]); 
        !            77:        (bytetoktype *)bufub = &(bufferbox->toks[AVAILTOKS]);
        !            78: 
        !            79:        MEMTOREGBUF;
        !            80:        if (newfflag){
        !            81:                newfflag = 0;
        !            82:                ryylval = (int)savestr(newfname, strlen(newfname)+1, STR_BOTH);
        !            83: 
        !            84:                ptoken(bufptr, IFILE);
        !            85:                ptoken(bufptr, STRING);
        !            86:                pptr(bufptr, ryylval);
        !            87: 
        !            88:                ptoken(bufptr, ILINENO);
        !            89:                ptoken(bufptr, INT);
        !            90:                pint(bufptr,  1);
        !            91:        }
        !            92: 
        !            93:        while (bufptr < bufub){
        !            94:    loop:
        !            95:         switch(ryylval = (type+1)[ch = getchar()]) {
        !            96:        case SCANEOF:
        !            97:        endoffile: ;
        !            98:                inbufptr = 0;
        !            99:                ptoken(bufptr, PARSEEOF);
        !           100:                goto done;
        !           101: 
        !           102:        case DIV:               /*process C style comments*/
        !           103:                if ( (ch = getchar()) == '*') {  /*comment prelude*/
        !           104:                        int     incomment;
        !           105:                        linescrossed = 0;
        !           106:                        incomment = 1;
        !           107:                        ch = getchar(); /*skip over the * */
        !           108:                        while(incomment){
        !           109:                                switch(ch){
        !           110:                                case '*':
        !           111:                                        ch = getchar();
        !           112:                                        incomment = (ch != '/');
        !           113:                                        break;
        !           114:                                case '\n':
        !           115:                                        scanlineno++;
        !           116:                                        linescrossed++;
        !           117:                                        ch = getchar();
        !           118:                                        break;
        !           119:                                case EOFCHAR:
        !           120:                                        goto endoffile;
        !           121:                                default:
        !           122:                                        ch = getchar();
        !           123:                                        break;
        !           124:                                }
        !           125:                        }
        !           126:                        val = ILINESKIP;
        !           127:                        ryylval = linescrossed;
        !           128:                        goto ret;
        !           129:                } else {        /*just an ordinary DIV*/
        !           130:                        ungetc(ch);
        !           131:                        val = ryylval = DIV;
        !           132:                        goto ret;
        !           133:                }
        !           134:        case SH:
        !           135:                if (oval == NL){
        !           136:                        /*
        !           137:                         *      Attempt to recognize a C preprocessor
        !           138:                         *      style comment '^#[ \t]*[0-9]*[ \t]*".*"
        !           139:                         */
        !           140:                        ch = getchar(); /*bump the #*/
        !           141:                        while (INCHARSET(ch, SPACE))
        !           142:                                ch = getchar();/*bump white */
        !           143:                        if (INCHARSET(ch, DIGIT)){
        !           144:                                intval = 0;
        !           145:                                while(INCHARSET(ch, DIGIT)){
        !           146:                                        intval = intval*10 + ch - '0';
        !           147:                                        ch = getchar();
        !           148:                                }
        !           149:                                while (INCHARSET(ch, SPACE))
        !           150:                                        ch = getchar();
        !           151:                                if (ch == '"'){
        !           152:                                        ptoken(bufptr, ILINENO);
        !           153:                                        ptoken(bufptr, INT);
        !           154:                                        pint(bufptr, intval - 1);
        !           155:                                        ptoken(bufptr, IFILE);
        !           156:                                        /*
        !           157:                                         *      The '"' has already been
        !           158:                                         *      munched
        !           159:                                         *      
        !           160:                                         *      eatstr will not eat
        !           161:                                         *      the trailing \n, so
        !           162:                                         *      it is given to the parser
        !           163:                                         *      and counted.
        !           164:                                         */
        !           165:                                        goto eatstr;
        !           166:                                }
        !           167:                        }
        !           168:                }
        !           169:                /*
        !           170:                 *      Well, its just an ordinary decadent comment
        !           171:                 */
        !           172:                while ((ch != '\n') && (ch != EOFCHAR)) 
        !           173:                        ch = getchar();
        !           174:                if (ch == EOFCHAR)
        !           175:                        goto endoffile;
        !           176:                val = ryylval = oval = NL;
        !           177:                scanlineno++;
        !           178:                goto ret;
        !           179: 
        !           180:        case NL:
        !           181:                scanlineno++;
        !           182:                val = ryylval;
        !           183:                goto ret;
        !           184: 
        !           185:        case SP:
        !           186:                oval = SP;      /*invalidate ^# meta comments*/
        !           187:                goto loop;
        !           188: 
        !           189:        case REGOP:             /* % , could be used as modulo, or register*/
        !           190:                ch = getchar();
        !           191:                if (INCHARSET(ch, DIGIT)){
        !           192:                        ryylval = ch-'0';
        !           193:                        if (ch=='1') {
        !           194:                                if (INCHARSET( (ch = getchar()), REGDIGIT))
        !           195:                                        ryylval = 10+ch-'0';
        !           196:                                else
        !           197:                                        ungetc(ch);
        !           198:                        }
        !           199:                        /*
        !           200:                         *      God only knows what the original author
        !           201:                         *      wanted this undocumented feature to
        !           202:                         *      do.
        !           203:                         *              %5++ is really  r7
        !           204:                         */
        !           205:                        while(INCHARSET( (ch = getchar()), SIGN)) {
        !           206:                                if (ch=='+')
        !           207:                                        ryylval++;
        !           208:                                else
        !           209:                                        ryylval--;
        !           210:                        }
        !           211:                        ungetc(ch);
        !           212:                        val = REG;
        !           213:                } else {
        !           214:                        ungetc(ch);
        !           215:                        val = REGOP;
        !           216:                }
        !           217:                goto ret;
        !           218: 
        !           219:        case ALPH:
        !           220:                ch1 = ch;
        !           221:                if (INCHARSET(ch, SZSPECBEGIN)){
        !           222:                        if( (ch = getchar()) == '`' || ch == '^'){
        !           223:                                ch1 |= 0100;    /*convert to lower*/
        !           224:                                switch(ch1){
        !           225:                                case 'b':       ryylval = 1;    break;
        !           226:                                case 'w':       ryylval = 2;    break;
        !           227:                                case 'l':       ryylval = 4;    break;
        !           228:                                default:        ryylval = d124; break;
        !           229:                                }
        !           230:                                val = SIZESPEC;
        !           231:                                goto ret;
        !           232:                        } else {
        !           233:                                ungetc(ch);
        !           234:                                ch = ch1;       /*restore first character*/
        !           235:                        }
        !           236:                }
        !           237:                rcp = yytext;
        !           238:                do {
        !           239:                        if (rcp < &yytext[NCPName])
        !           240:                                *rcp++ = ch;
        !           241:                } while (INCHARSET ( (ch = getchar()), ALPHA | DIGIT));
        !           242:                *rcp = '\0';
        !           243:                while (INCHARSET(ch, SPACE))
        !           244:                        ch = getchar();
        !           245:                ungetc(ch);
        !           246:        
        !           247:                switch((op = *lookup(1))->s_tag){
        !           248:                case 0:
        !           249:                case LABELID:
        !           250:                        /*
        !           251:                         *      Its a name... (Labels are subsets of name)
        !           252:                         */
        !           253:                        ryylval = (int)op;
        !           254:                        val = NAME;
        !           255:                        break;
        !           256:                case INST0:
        !           257:                case INSTn:
        !           258:                case IJXXX:
        !           259:                        opstruct.Op_popcode = ( (struct instab *)op)->i_popcode;
        !           260:                        opstruct.Op_eopcode = ( (struct instab *)op)->i_eopcode;
        !           261:                        val = op->s_tag;
        !           262:                        break;
        !           263:                default:
        !           264:                        ryylval = ( (struct instab *)op)->i_popcode;
        !           265:                        val = op->s_tag;
        !           266:                        break;
        !           267:                }
        !           268:                goto ret;
        !           269: 
        !           270:        case DIG:
        !           271:                /*
        !           272:                 *      restore local inbufptr and inbufcnt
        !           273:                 */
        !           274:                REGTOMEMBUF;
        !           275:                val = number(ch);
        !           276:                MEMTOREGBUF;
        !           277:                /*
        !           278:                 *      yylval or yybignum has been stuffed as a side
        !           279:                 *      effect to number(); get the global yylval
        !           280:                 *      into our fast local copy in case it was an INT.
        !           281:                 */
        !           282:                ryylval = yylval;
        !           283:                goto ret;
        !           284: 
        !           285:        case LSH:
        !           286:        case RSH:
        !           287:                /*
        !           288:                 *      We allow the C style operators
        !           289:                 *      << and >>, as well as < and >
        !           290:                 */
        !           291:                if ( (ch1 = getchar()) != ch)
        !           292:                        ungetc(ch1);
        !           293:                val = ryylval;
        !           294:                goto ret;
        !           295: 
        !           296:        case MINUS:
        !           297:                if ( (ch = getchar()) =='(')
        !           298:                        ryylval=val=MP;
        !           299:                else {
        !           300:                        ungetc(ch);
        !           301:                        val=MINUS;
        !           302:                }
        !           303:                goto ret;
        !           304: 
        !           305:        case SQ:
        !           306:                if ((ryylval = getchar()) == '\n')
        !           307:                        scanlineno++;           /*not entirely correct*/
        !           308:                val = INT;
        !           309:                goto ret;
        !           310: 
        !           311:        case DQ:
        !           312:           eatstr:
        !           313:                linescrossed = 0;
        !           314:                for (strlg = 0; /*VOID*/; strlg++){
        !           315:                    switch(ch = getchar()){
        !           316:                    case '"':
        !           317:                        goto tailDQ;
        !           318:                    default:
        !           319:                    stuff:
        !           320:                        putc(ch, strfile);
        !           321:                        break;
        !           322:                    case '\n':
        !           323:                        yywarning("New line in a string constant");
        !           324:                        scanlineno++;
        !           325:                        linescrossed++;
        !           326:                        ch = getchar();
        !           327:                        switch(ch){
        !           328:                        case EOFCHAR:
        !           329:                                putc('\n', strfile);
        !           330:                                ungetc(EOFCHAR);
        !           331:                                goto tailDQ;
        !           332:                        default:
        !           333:                                ungetc(ch);
        !           334:                                ch = '\n';
        !           335:                                goto stuff;
        !           336:                        }
        !           337:                        break;
        !           338: 
        !           339:                    case '\\':
        !           340:                        ch = getchar();         /*skip the '\\'*/
        !           341:                        if ( INCHARSET(ch, BSESCAPE)){
        !           342:                                switch (ch){
        !           343:                                  case 'b':  ch = '\b'; goto stuff;
        !           344:                                  case 'f':  ch = '\f'; goto stuff;
        !           345:                                  case 'n':  ch = '\n'; goto stuff;
        !           346:                                  case 'r':  ch = '\r'; goto stuff;
        !           347:                                  case 't':  ch = '\t'; goto stuff;
        !           348:                                }
        !           349:                        }
        !           350:                        if ( !(INCHARSET(ch, OCTDIGIT)) ) 
        !           351:                                goto stuff;
        !           352:                        i = 0;
        !           353:                        intval = 0;
        !           354:                        while ( (i < 3) && (INCHARSET(ch, OCTDIGIT))){
        !           355:                                i++;
        !           356:                                intval <<= 3;
        !           357:                                intval += ch - '0';
        !           358:                                ch = getchar();
        !           359:                        }
        !           360:                        ungetc(ch);
        !           361:                        ch = (char)intval;
        !           362:                        goto stuff;
        !           363:                    }
        !           364:                }
        !           365:        tailDQ: ;
        !           366:                /*
        !           367:                 *      account for any lines that were crossed
        !           368:                 */
        !           369:                if (linescrossed){
        !           370:                        ptoken(bufptr, ILINESKIP);
        !           371:                        pint(bufptr, linescrossed);
        !           372:                }
        !           373:                /*
        !           374:                 *      Cheat: append a trailing null to the string
        !           375:                 *      and then adjust the string length to ignore
        !           376:                 *      the trailing null.  If any STRING client requires
        !           377:                 *      the trailing null, the client can just change STRLEN
        !           378:                 */
        !           379:                putc(0, strfile);
        !           380:                ryylval = (int)savestr((char *)0, strlg + 1, STR_FILE);
        !           381:                val = STRING;
        !           382:                ((struct strdesc *)ryylval)->sd_strlen -= 1;
        !           383:                goto ret;
        !           384: 
        !           385:        case BADCHAR:
        !           386:                linescrossed = lineno;
        !           387:                lineno = scanlineno;
        !           388:                yyerror("Illegal character mapped: %d, char read:(octal) %o",
        !           389:                        ryylval, ch);
        !           390:                lineno = linescrossed;
        !           391:                val = BADCHAR;
        !           392:                goto ret;
        !           393: 
        !           394:        default:
        !           395:                val = ryylval;
        !           396:                goto ret;
        !           397:        }       /*end of the switch*/
        !           398:        /*
        !           399:         *      here with one token, so stuff it
        !           400:         */
        !           401:    ret:        
        !           402:        oval = val;
        !           403:        ptoken(bufptr, val);
        !           404:        switch(val){
        !           405:                case    ILINESKIP:
        !           406:                                pint(bufptr, ryylval);
        !           407:                                break;
        !           408:                case    SIZESPEC:
        !           409:                                pchar(bufptr, ryylval);
        !           410:                                break;
        !           411:                case    BFINT:  plong(bufptr, ryylval);
        !           412:                                break;
        !           413:                case    INT:    plong(bufptr, ryylval);
        !           414:                                break;
        !           415:                case    BIGNUM: pnumber(bufptr, yybignum);
        !           416:                                break;
        !           417:                case    STRING: pptr(bufptr, (int)(char *)ryylval);
        !           418:                                break;
        !           419:                case    NAME:   pptr(bufptr, (int)(struct symtab *)ryylval);
        !           420:                                break;
        !           421:                case    REG:    pchar(bufptr, ryylval);
        !           422:                                break;  
        !           423:                case    INST0:
        !           424:                case    INSTn:
        !           425:                                popcode(bufptr, opstruct);
        !           426:                                break;
        !           427:                case    IJXXX:
        !           428:                                popcode(bufptr, opstruct);
        !           429:                                pptr(bufptr, (int)(struct symtab *)symalloc());
        !           430:                                break;
        !           431:                case    ISTAB:
        !           432:                case    ISTABSTR:
        !           433:                case    ISTABNONE:
        !           434:                case    ISTABDOT:
        !           435:                case    IALIGN:
        !           436:                                pptr(bufptr, (int)(struct symtab *)symalloc());
        !           437:                                break;
        !           438:        /*
        !           439:         *      default:
        !           440:         */
        !           441:         }
        !           442:         builtval: ;
        !           443:    }                   /*end of the while to stuff the buffer*/
        !           444:    done:
        !           445:        bufferbox->tok_count = (bytetoktype *)bufptr - &(bufferbox->toks[0]);
        !           446:        /*
        !           447:         *      This is a real kludge:
        !           448:         *
        !           449:         *      We put the last token in the buffer to be  a MINUS
        !           450:         *      symbol.  This last token will never be picked up
        !           451:         *      in the normal way, but can be looked at during
        !           452:         *      a peekahead look that the short circuit expression
        !           453:         *      evaluator uses to see if an expression is complicated.
        !           454:         *
        !           455:         *      Consider the following situation:
        !           456:         *
        !           457:         *      .word   45              +       47
        !           458:         *        buffer 1      |  buffer 0
        !           459:         *      the peekahead would want to look across the buffer,
        !           460:         *      but will look in the buffer end zone, see the minus, and
        !           461:         *      fail.
        !           462:         */
        !           463:        ptoken(bufptr, MINUS);
        !           464:        REGTOMEMBUF;
        !           465: }

unix.superglobalmegacorp.com

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