Annotation of 43BSDReno/pgrm/as.tahoe/asscan2.c, revision 1.1

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

unix.superglobalmegacorp.com

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