|
|
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.