|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.