|
|
1.1 root 1: # include "mfile1"
2: # include <a.out.h>
3: # include <stab.h>
4: # include <ctype.h>
5: /* temporarily */
6:
1.1.1.2 ! root 7: #define LXGET(c, m) (lxgcp = &yytext[0], lxmore(c, m))
! 8:
1.1 root 9:
10: # define A_ERR 0 /* illegal character */
11: # define A_LET 1 /* saw a letter */
12: # define A_DIG 2 /* saw a digit */
13: # define A_1C 3 /* return a single character */
14: # define A_STR 4 /* string */
15: # define A_CC 5 /* character constant */
16: # define A_BCD 6 /* GCOS BCD constant */
17: # define A_SL 7 /* saw a / */
18: # define A_DOT 8 /* saw a . */
19: # define A_PL 9 /* + */
20: # define A_MI 10 /* - */
21: # define A_EQ 11 /* = */
22: # define A_NOT 12 /* ! */
23: # define A_LT 13 /* < */
24: # define A_GT 14 /* > */
25: # define A_AND 16 /* & */
26: # define A_OR 17 /* | */
27: # define A_WS 18 /* whitespace (not \n) */
28: # define A_NL 19 /* \n */
29:
30: /* character classes */
31:
32: # define LEXLET 01
33: # define LEXDIG 02
34: # define LEXOCT 04
35: # define LEXHEX 010
36: # define LEXWS 020
37: # define LEXDOT 040
38:
39: /* reserved word actions */
40:
41: # define AR_TY 0 /* type word */
42: # define AR_RW 1 /* simple reserved word */
43: # define AR_CL 2 /* storage class word */
44: # define AR_S 3 /* struct */
45: # define AR_U 4 /* union */
46: # define AR_E 5 /* enum */
47: # define AR_A 6 /* asm */
48:
1.1.1.2 ! root 49: #ifndef ASMBUF
! 50: #define ASMBUF 100
! 51: #endif
! 52: static char asmbuf[ASMBUF + 1];
! 53: static char *asmp;
! 54:
1.1 root 55: /* text buffer */
56: #ifndef FLEXNAMES
57: # define LXTSZ 100
58: #else
59: #define LXTSZ BUFSIZ
60: #endif
61: char yytext[LXTSZ];
62: char * lxgcp;
63:
64: extern int proflg;
65: extern int gdebug;
66: int oldway; /* allocate storage so lint will compile as well */
67: #ifndef LINT
68: extern int lastloc;
69: #endif
70:
71: unsigned caloff();
72: /* ARGSUSED */
73: mainp1( argc, argv ) int argc; char *argv[]; { /* control multiple files */
74:
1.1.1.2 ! root 75: register int i;
1.1 root 76: register char *cp;
77: extern int idebug, bdebug, tdebug, edebug, ddebug, xdebug, gdebug;
78: extern unsigned int offsz;
79: int fdef = 0;
80: char *release = "PCC/364r1 tahoe 1.0";
81:
82: offsz = caloff();
83: for( i=1; i<argc; ++i ){
84: if( *(cp=argv[i]) == '-' && *++cp == 'X' ){
85: while( *++cp ){
86: switch( *cp ){
87:
88: case 'r':
89: fprintf( stderr, "Release: %s\n",
90: release );
91: break;
92:
93: case 'd':
94: ++ddebug;
95: break;
96: case 'i':
97: ++idebug;
98: break;
99: case 'b':
100: ++bdebug;
101: break;
102: case 't':
103: ++tdebug;
104: break;
105: case 'e':
106: ++edebug;
107: break;
108: case 'x':
109: ++xdebug;
110: break;
111: case 'P': /* profiling */
112: ++proflg;
113: break;
114: case 'G':
115: oldway = 1;
116: case 'g':
117: ++gdebug;
118: break;
119: }
120: }
121: }
122: else {
123: if( *(argv[i]) != '-' ) switch( fdef++ ) {
124: case 0:
125: case 1:
126: if( freopen(argv[i], fdef==1 ? "r" : "w", fdef==1 ? stdin : stdout) == NULL) {
127: fprintf(stderr, "ccom:can't open %s\n", argv[i]);
128: exit(1);
129: }
130: break;
131:
132: default:
133: ;
134: }
135: }
136: }
137:
138: # ifdef ONEPASS
139: p2init( argc, argv );
140: # endif
141:
142: for( i=0; i<SYMTSZ; ++i ) stab[i].stype = TNULL;
143:
144: lxinit();
145: tinit();
146: mkdope();
147:
148: lineno = 1;
149:
150: /* dimension table initialization */
151:
152: dimtab[NULL] = 0;
153: dimtab[CHAR] = SZCHAR;
154: dimtab[INT] = SZINT;
155: dimtab[FLOAT] = SZFLOAT;
156: dimtab[DOUBLE] = SZDOUBLE;
157: dimtab[LONG] = SZLONG;
158: dimtab[SHORT] = SZSHORT;
159: dimtab[UCHAR] = SZCHAR;
160: dimtab[USHORT] = SZSHORT;
161: dimtab[UNSIGNED] = SZINT;
162: dimtab[ULONG] = SZLONG;
163: /* starts past any of the above */
164: curdim = 16;
165: reached = 1;
166:
167: yyparse();
168: yyaccpt();
169:
170: ejobcode( nerrors ? 1 : 0 );
171: return(nerrors?1:0);
172:
173: }
174:
175: # ifdef ibm
176:
177: # define CSMASK 0377
178: # define CSSZ 256
179:
180: # else
181:
182: # define CSMASK 0177
183: # define CSSZ 128
184:
185: # endif
186:
187: short lxmask[CSSZ+1];
188:
189: lxenter( s, m ) register char *s; register short m; {
190: /* enter a mask into lxmask */
1.1.1.2 ! root 191: register int c;
1.1 root 192:
193: while( c= *s++ ) lxmask[c+1] |= m;
194:
195: }
196:
197:
198: # define lxget(c,m) (lxgcp=yytext,lxmore(c,m))
199:
1.1.1.2 ! root 200: lxmore( c, m ) register int c, m; {
1.1 root 201: register char *cp;
202:
203: *(cp = lxgcp) = c;
204: while( c=getchar(), lxmask[c+1]&m ){
205: if( cp < &yytext[LXTSZ-1] ){
206: *++cp = c;
207: }
208: }
209: ungetc(c,stdin);
210: *(lxgcp = cp+1) = '\0';
211: }
212:
213: struct lxdope {
214: short lxch; /* the character */
215: short lxact; /* the action to be performed */
216: short lxtok; /* the token number to be returned */
217: short lxval; /* the value to be returned */
218: } lxdope[] = {
219:
220: '@', A_ERR, 0, 0, /* illegal characters go here... */
221: '_', A_LET, 0, 0, /* letters point here */
222: '0', A_DIG, 0, 0, /* digits point here */
223: ' ', A_WS, 0, 0, /* whitespace goes here */
224: '\n', A_NL, 0, 0,
225: '"', A_STR, 0, 0, /* character string */
226: '\'', A_CC, 0, 0, /* character constant */
227: '`', A_BCD, 0, 0, /* GCOS BCD constant */
228: '(', A_1C, LP, 0,
229: ')', A_1C, RP, 0,
230: '{', A_1C, LC, 0,
231: '}', A_1C, RC, 0,
232: '[', A_1C, LB, 0,
233: ']', A_1C, RB, 0,
234: '*', A_1C, MUL, MUL,
235: '?', A_1C, QUEST, 0,
236: ':', A_1C, COLON, 0,
237: '+', A_PL, PLUS, PLUS,
238: '-', A_MI, MINUS, MINUS,
239: '/', A_SL, DIVOP, DIV,
240: '%', A_1C, DIVOP, MOD,
241: '&', A_AND, AND, AND,
242: '|', A_OR, OR, OR,
243: '^', A_1C, ER, ER,
244: '!', A_NOT, UNOP, NOT,
245: '~', A_1C, UNOP, COMPL,
246: ',', A_1C, CM, CM,
247: ';', A_1C, SM, 0,
248: '.', A_DOT, STROP, DOT,
249: '<', A_LT, RELOP, LT,
250: '>', A_GT, RELOP, GT,
251: '=', A_EQ, ASSIGN, ASSIGN,
252: -1, A_1C, 0, 0,
253: };
254:
255: struct lxdope *lxcp[CSSZ+1];
256:
257: lxinit(){
258: register struct lxdope *p;
1.1.1.2 ! root 259: register int i;
1.1 root 260: register char *cp;
261: /* set up character classes */
262:
263: lxenter( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$", LEXLET );
264: lxenter( "0123456789", LEXDIG );
265: lxenter( "0123456789abcdefABCDEF", LEXHEX );
266: /* \013 should become \v someday; \013 is OK for ASCII and EBCDIC */
267: lxenter( " \t\r\b\f\013", LEXWS );
268: lxenter( "01234567", LEXOCT );
269: lxmask['.'+1] |= LEXDOT;
270:
271: /* make lxcp point to appropriate lxdope entry for each character */
272:
273: /* initialize error entries */
274:
275: for( i= 0; i<=CSSZ; ++i ) lxcp[i] = lxdope;
276:
277: /* make unique entries */
278:
279: for( p=lxdope; ; ++p ) {
280: lxcp[p->lxch+1] = p;
281: if( p->lxch < 0 ) break;
282: }
283:
284: /* handle letters, digits, and whitespace */
285: /* by convention, first, second, and third places */
286:
287: cp = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$";
288: while( *cp ) lxcp[*cp++ + 1] = &lxdope[1];
289: cp = "123456789";
290: while( *cp ) lxcp[*cp++ + 1] = &lxdope[2];
291: cp = "\t\b\r\f\013";
292: while( *cp ) lxcp[*cp++ + 1] = &lxdope[3];
293:
294: /* first line might have title */
295: lxtitle();
296:
297: }
298:
299: int lxmatch; /* character to be matched in char or string constant */
300:
301: lxstr(ct){
302: /* match a string or character constant, up to lxmatch */
303:
1.1.1.2 ! root 304: register int c;
! 305: register int val;
! 306: register int i;
1.1 root 307:
308: i=0;
309: while( (c=getchar()) != lxmatch ){
310: switch( c ) {
311:
312: case EOF:
313: uerror( "unexpected EOF" );
314: break;
315:
316: case '\n':
317: uerror( "newline in string or char constant" );
318: ++lineno;
319: break;
320:
321: case '\\':
322: switch( c = getchar() ){
323:
324: case '\n':
325: ++lineno;
326: continue;
327:
328: default:
329: val = c;
330: goto mkcc;
331:
332: case 'n':
333: val = '\n';
334: goto mkcc;
335:
336: case 'r':
337: val = '\r';
338: goto mkcc;
339:
340: case 'b':
341: val = '\b';
342: goto mkcc;
343:
344: case 't':
345: val = '\t';
346: goto mkcc;
347:
348: case 'f':
349: val = '\f';
350: goto mkcc;
351:
352: case 'v':
353: val = '\013';
354: goto mkcc;
355:
356: case '0':
357: case '1':
358: case '2':
359: case '3':
360: case '4':
361: case '5':
362: case '6':
363: case '7':
364: val = c-'0';
365: c=getchar(); /* try for 2 */
366: if( lxmask[c+1] & LEXOCT ){
367: val = (val<<3) | (c-'0');
368: c = getchar(); /* try for 3 */
369: if( lxmask[c+1] & LEXOCT ){
370: val = (val<<3) | (c-'0');
371: }
372: else ungetc( c ,stdin);
373: }
374: else ungetc( c ,stdin);
375:
376: goto mkcc1;
377:
378: }
379: default:
380: val =c;
381: mkcc:
382: val = CCTRANS(val);
383: mkcc1:
384: if( lxmatch == '\'' ){
385: val = CHARCAST(val); /* it is, after all, a "character" constant */
386: makecc( val, i );
387: }
388: else { /* stash the byte into the string */
389: if( strflg ) {
390: if( ct==0 || i<ct ) putbyte( val );
391: else if( i == ct ) werror( "non-null byte ignored in string initializer" );
392: }
393: else bycode( val, i );
394: }
395: ++i;
396: continue;
397: }
398: break;
399: }
400: /* end of string or char constant */
401:
402: if( lxmatch == '"' ){
403: if( strflg ){ /* end the string */
404: if( ct==0 || i<ct ) putbyte( 0 ); /* the null at the end */
405: }
406: else { /* the initializer gets a null byte */
407: bycode( 0, i++ );
408: bycode( -1, i );
409: dimtab[curdim] = i; /* in case of later sizeof ... */
410: }
411: }
412: else { /* end the character constant */
413: if( i == 0 ) uerror( "empty character constant" );
414: if( i>(SZINT/SZCHAR) || ( (pflag||hflag)&&i>1) )
415: uerror( "too many characters in character constant" );
416: }
417: }
418:
419: lxcom(){
1.1.1.2 ! root 420: register int c;
1.1 root 421: /* saw a /*: process a comment */
422:
423: for(;;){
424:
425: switch( c = getchar() ){
426:
427: case EOF:
428: uerror( "unexpected EOF" );
429: return;
430:
431: case '\n':
432: ++lineno;
433:
434: default:
435: continue;
436:
437: case '*':
438: if( (c = getchar()) == '/' ) return;
439: else ungetc( c ,stdin);
440: continue;
441:
442: # ifdef LINT
443: case 'V':
444: lxget( c, LEXLET|LEXDIG );
445: {
446: extern int vaflag;
447: int i;
448: i = yytext[7]?yytext[7]-'0':0;
449: yytext[7] = '\0';
450: if( strcmp( yytext, "VARARGS" ) ) continue;
451: vaflag = i;
452: continue;
453: }
454: case 'L':
455: lxget( c, LEXLET );
456: if( strcmp( yytext, "LINTLIBRARY" ) ) continue;
457: {
458: extern int libflag;
459: libflag = 1;
460: }
461: continue;
462:
463: case 'A':
464: lxget( c, LEXLET );
465: if( strcmp( yytext, "ARGSUSED" ) ) continue;
466: {
467: extern int argflag, vflag;
468: argflag = 1;
469: vflag = 0;
470: }
471: continue;
472:
473: case 'N':
474: lxget( c, LEXLET );
475: if( strcmp( yytext, "NOTREACHED" ) ) continue;
476: reached = 0;
477: continue;
478: # endif
479: }
480: }
481: }
482:
483: yylex(){
1.1.1.2 ! root 484: register int lxchar;
! 485:
1.1 root 486: for(;;){
487:
488: register struct lxdope *p;
489: register struct symtab *sp;
490: int id;
491:
492: switch( (p=lxcp[(lxchar=getchar())+1])->lxact ){
493:
494: onechar:
495: ungetc( lxchar ,stdin);
496:
497: case A_1C:
498: /* eat up a single character, and return an opcode */
499:
500: yylval.intval = p->lxval;
501: return( p->lxtok );
502:
503: case A_ERR:
504: uerror( "illegal character: %03o (octal)", lxchar );
505: break;
506:
507: case A_LET:
508: /* collect an identifier, check for reserved word, and return */
509: lxget( lxchar, LEXLET|LEXDIG );
510: if( (lxchar=lxres()) > 0 ) return( lxchar ); /* reserved word */
511: if( lxchar== 0 ) continue;
512: #ifdef FLEXNAMES
513: id = lookup( hash(yytext),
514: #else
515: id = lookup( yytext,
516: #endif
517: /* tag name for struct/union/enum */
518: (stwart&TAGNAME)? STAG:
519: /* member name for struct/union */
520: (stwart&(INSTRUCT|INUNION|FUNNYNAME))?SMOS:0 );
521: sp = &stab[id];
522: if( sp->sclass == TYPEDEF && !stwart ){
523: stwart = instruct;
524: yylval.nodep = mkty( sp->stype, sp->dimoff, sp->sizoff );
525: return( TYPE );
526: }
527: stwart = (stwart&SEENAME) ? instruct : 0;
528: yylval.intval = id;
529: return( NAME );
530:
531: case A_DIG:
532: /* collect a digit string, then look at last one... */
533: lastcon = 0;
534: lxget( lxchar, LEXDIG );
535: switch( lxchar=getchar() ){
536:
537: case 'x':
538: case 'X':
539: if( yytext[0] != '0' && !yytext[1] ) uerror( "illegal hex constant" );
540: lxmore( lxchar, LEXHEX );
541: /* convert the value */
542: {
543: register char *cp;
544: for( cp = yytext+2; *cp; ++cp ){
545: /* this code won't work for all wild character sets,
546: but seems ok for ascii and ebcdic */
547: lastcon <<= 4;
548: if( isdigit( *cp ) ) lastcon += *cp-'0';
549: else if( isupper( *cp ) ) lastcon += *cp - 'A'+ 10;
550: else lastcon += *cp - 'a'+ 10;
551: }
552: }
553:
554: hexlong:
555: /* criterion for longness for hex and octal constants is that it
556: fit within 0177777 */
557: if( lastcon & ~0177777L ) yylval.intval = 1;
558: else yylval.intval = 0;
559:
560: goto islong;
561:
562: case '.':
563: lxmore( lxchar, LEXDIG );
564:
565: getfp:
566: if( (lxchar=getchar()) == 'e' || lxchar == 'E' ){ /* exponent */
567:
568: case 'e':
569: case 'E':
570: if( (lxchar=getchar()) == '+' || lxchar == '-' ){
571: *lxgcp++ = 'e';
572: }
573: else {
574: ungetc(lxchar,stdin);
575: lxchar = 'e';
576: }
577: lxmore( lxchar, LEXDIG );
578: /* now have the whole thing... */
579: }
580: else { /* no exponent */
581: ungetc( lxchar ,stdin);
582: }
583: return( isitfloat( yytext ) );
584:
585: default:
586: ungetc( lxchar ,stdin);
587: if( yytext[0] == '0' ){
588: /* convert in octal */
589: register char *cp;
590: for( cp = yytext+1; *cp; ++cp ){
591: lastcon <<= 3;
592: lastcon += *cp - '0';
593: }
594: goto hexlong;
595: }
596: else {
597: /* convert in decimal */
598: register char *cp;
599: for( cp = yytext; *cp; ++cp ){
600: lastcon = lastcon * 10 + *cp - '0';
601: }
602: }
603:
604: /* decide if it is long or not (decimal case) */
605:
606: /* if it is positive and fits in 15 bits, or negative and
607: and fits in 15 bits plus an extended sign, it is int; otherwise long */
608: /* if there is an l or L following, all bets are off... */
609:
610: { CONSZ v;
611: v = lastcon & ~077777L;
612: if( v == 0 || v == ~077777L ) yylval.intval = 0;
613: else yylval.intval = 1;
614: }
615:
616: islong:
617: /* finally, look for trailing L or l */
618: if( (lxchar = getchar()) == 'L' || lxchar == 'l' ) yylval.intval = 1;
619: else ungetc( lxchar ,stdin);
620: return( ICON );
621: }
622:
623: case A_DOT:
624: /* look for a dot: if followed by a digit, floating point */
625: lxchar = getchar();
626: if( lxmask[lxchar+1] & LEXDIG ){
627: ungetc(lxchar,stdin);
628: lxget( '.', LEXDIG );
629: goto getfp;
630: }
631: stwart = FUNNYNAME;
632: goto onechar;
633:
634: case A_STR:
635: /* string constant */
636: lxmatch = '"';
637: return( STRING );
638:
639: case A_CC:
640: /* character constant */
641: lxmatch = '\'';
642: lastcon = 0;
643: lxstr(0);
644: yylval.intval = 0;
645: return( ICON );
646:
647: case A_BCD:
648: {
1.1.1.2 ! root 649: register int i;
1.1 root 650: int j;
651: for( i=0; i<LXTSZ; ++i ){
652: if( ( j = getchar() ) == '`' ) break;
653: if( j == '\n' ){
654: uerror( "newline in BCD constant" );
655: break;
656: }
657: yytext[i] = j;
658: }
659: yytext[i] = '\0';
660: if( i>6 ) uerror( "BCD constant exceeds 6 characters" );
661: # ifdef gcos
662: else strtob( yytext, &lastcon, i );
663: lastcon >>= 6*(6-i);
664: # else
665: uerror( "gcos BCD constant illegal" );
666: # endif
667: yylval.intval = 0; /* not long */
668: return( ICON );
669: }
670:
671: case A_SL:
672: /* / */
673: if( (lxchar=getchar()) != '*' ) goto onechar;
674: lxcom();
675: case A_WS:
676: continue;
677:
678: case A_NL:
679: ++lineno;
680: lxtitle();
681: continue;
682:
683: case A_NOT:
684: /* ! */
685: if( (lxchar=getchar()) != '=' ) goto onechar;
686: yylval.intval = NE;
687: return( EQUOP );
688:
689: case A_MI:
690: /* - */
691: if( (lxchar=getchar()) == '-' ){
692: yylval.intval = DECR;
693: return( INCOP );
694: }
695: if( lxchar != '>' ) goto onechar;
696: stwart = FUNNYNAME;
697: yylval.intval=STREF;
698: return( STROP );
699:
700: case A_PL:
701: /* + */
702: if( (lxchar=getchar()) != '+' ) goto onechar;
703: yylval.intval = INCR;
704: return( INCOP );
705:
706: case A_AND:
707: /* & */
708: if( (lxchar=getchar()) != '&' ) goto onechar;
709: return( yylval.intval = ANDAND );
710:
711: case A_OR:
712: /* | */
713: if( (lxchar=getchar()) != '|' ) goto onechar;
714: return( yylval.intval = OROR );
715:
716: case A_LT:
717: /* < */
718: if( (lxchar=getchar()) == '<' ){
719: yylval.intval = LS;
720: return( SHIFTOP );
721: }
722: if( lxchar != '=' ) goto onechar;
723: yylval.intval = LE;
724: return( RELOP );
725:
726: case A_GT:
727: /* > */
728: if( (lxchar=getchar()) == '>' ){
729: yylval.intval = RS;
730: return(SHIFTOP );
731: }
732: if( lxchar != '=' ) goto onechar;
733: yylval.intval = GE;
734: return( RELOP );
735:
736: case A_EQ:
737: /* = */
738: switch( lxchar = getchar() ){
739:
740: case '=':
741: yylval.intval = EQ;
742: return( EQUOP );
743:
744: case '+':
745: yylval.intval = ASG PLUS;
746: break;
747:
748: case '-':
749: yylval.intval = ASG MINUS;
750:
751: warn:
752: if( lxmask[ (lxchar=getchar())+1] & (LEXLET|LEXDIG|LEXDOT) ){
753: werror( "ambiguous assignment: assignment op taken" );
754: }
755: ungetc( lxchar ,stdin);
756: break;
757:
758: case '*':
759: yylval.intval = ASG MUL;
760: goto warn;
761:
762: case '/':
763: yylval.intval = ASG DIV;
764: break;
765:
766: case '%':
767: yylval.intval = ASG MOD;
768: break;
769:
770: case '&':
771: yylval.intval = ASG AND;
772: break;
773:
774: case '|':
775: yylval.intval = ASG OR;
776: break;
777:
778: case '^':
779: yylval.intval = ASG ER;
780: break;
781:
782: case '<':
783: if( (lxchar=getchar()) != '<' ){
784: uerror( "=<%c illegal", lxchar );
785: }
786: yylval.intval = ASG LS;
787: break;
788:
789: case '>':
790: if( (lxchar=getchar()) != '>' ){
791: uerror( "=>%c illegal", lxchar );
792: }
793: yylval.intval = ASG RS;
794: break;
795:
796: default:
797: goto onechar;
798:
799: }
800:
801: return( ASOP );
802:
803: default:
804: cerror( "yylex error, character %03o (octal)", lxchar );
805:
806: }
807:
808: /* ordinarily, repeat here... */
809: cerror( "out of switch in yylex" );
810:
811: }
812:
813: }
814:
815: struct lxrdope {
816: /* dope for reserved, in alphabetical order */
817:
818: char *lxrch; /* name of reserved word */
819: short lxract; /* reserved word action */
820: short lxrval; /* value to be returned */
821: } lxrdope[] = {
822:
823: "asm", AR_A, 0,
824: "auto", AR_CL, AUTO,
825: "break", AR_RW, BREAK,
826: "char", AR_TY, CHAR,
827: "case", AR_RW, CASE,
828: "continue", AR_RW, CONTINUE,
829: "double", AR_TY, DOUBLE,
830: "default", AR_RW, DEFAULT,
831: "do", AR_RW, DO,
832: "extern", AR_CL, EXTERN,
833: "else", AR_RW, ELSE,
834: "enum", AR_E, ENUM,
835: "for", AR_RW, FOR,
836: "float", AR_TY, FLOAT,
837: "fortran", AR_CL, FORTRAN,
838: "goto", AR_RW, GOTO,
839: "if", AR_RW, IF,
840: "int", AR_TY, INT,
841: "long", AR_TY, LONG,
842: "return", AR_RW, RETURN,
843: "register", AR_CL, REGISTER,
844: "switch", AR_RW, SWITCH,
845: "struct", AR_S, 0,
846: "sizeof", AR_RW, SIZEOF,
847: "short", AR_TY, SHORT,
848: "static", AR_CL, STATIC,
849: "typedef", AR_CL, TYPEDEF,
850: "unsigned", AR_TY, UNSIGNED,
851: "union", AR_U, 0,
852: "void", AR_TY, UNDEF, /* tymerge adds FTN */
853: "while", AR_RW, WHILE,
854: "", 0, 0, /* to stop the search */
855: };
856:
857: lxres() {
858: /* check to see of yytext is reserved; if so,
859: /* do the appropriate action and return */
860: /* otherwise, return -1 */
861:
1.1.1.2 ! root 862: register int c, ch;
1.1 root 863: register struct lxrdope *p;
864:
865: ch = yytext[0];
866:
867: if( !islower(ch) ) return( -1 );
868:
869: switch( ch ){
870:
871: case 'a':
872: c=0; break;
873: case 'b':
874: c=2; break;
875: case 'c':
876: c=3; break;
877: case 'd':
878: c=6; break;
879: case 'e':
880: c=9; break;
881: case 'f':
882: c=12; break;
883: case 'g':
884: c=15; break;
885: case 'i':
886: c=16; break;
887: case 'l':
888: c=18; break;
889: case 'r':
890: c=19; break;
891: case 's':
892: c=21; break;
893: case 't':
894: c=26; break;
895: case 'u':
896: c=27; break;
897: case 'v':
898: c=29; break;
899: case 'w':
900: c=30; break;
901:
902: default:
903: return( -1 );
904: }
905:
906: for( p= lxrdope+c; p->lxrch[0] == ch; ++p ){
907: if( !strcmp( yytext, p->lxrch ) ){ /* match */
908: switch( p->lxract ){
909:
910: case AR_TY:
911: /* type word */
912: stwart = instruct;
913: yylval.nodep = mkty( (TWORD)p->lxrval, 0, p->lxrval );
914: return( TYPE );
915:
916: case AR_RW:
917: /* ordinary reserved word */
918: return( yylval.intval = p->lxrval );
919:
920: case AR_CL:
921: /* class word */
922: yylval.intval = p->lxrval;
923: return( CLASS );
924:
925: case AR_S:
926: /* struct */
927: stwart = INSTRUCT|SEENAME|TAGNAME;
928: yylval.intval = INSTRUCT;
929: return( STRUCT );
930:
931: case AR_U:
932: /* union */
933: stwart = INUNION|SEENAME|TAGNAME;
934: yylval.intval = INUNION;
935: return( STRUCT );
936:
937: case AR_E:
938: /* enums */
939: stwart = SEENAME|TAGNAME;
940: return( yylval.intval = ENUM );
941:
1.1.1.2 ! root 942: case AR_A: /* asm */
! 943: LXGET(' ', LEXWS);
! 944: if (getchar() == '(')
! 945: {
! 946: LXGET(' ', LEXWS);
! 947: if (getchar() == '"')
! 948: {
! 949: asmp = &asmbuf[0];
! 950: while ((c = getchar()) != EOF && c != '\n' && c != '"')
! 951: {
! 952: if (asmp <= &asmbuf[ASMBUF])
! 953: *asmp++ = c;
! 954: }
! 955: if (c == '"' && asmp <= &asmbuf[ASMBUF])
! 956: {
! 957: LXGET(' ', LEXWS);
! 958: if (getchar() == ')')
! 959: {
! 960: *asmp = '\0';
! 961: return (ASM);
! 962: }
! 963: }
1.1 root 964: }
965:
1.1.1.2 ! root 966: }
! 967: if (c == '\n')
! 968: (void)ungetc('\n', stdin);
1.1 root 969: uerror( "bad asm construction" );
1.1.1.2 ! root 970: return (0);
1.1 root 971: default:
972: cerror( "bad AR_?? action" );
973: }
974: }
975: }
976: return( -1 );
977: }
978:
979: extern int labelno;
980:
981: lxtitle(){
982: /* called after a newline; set linenumber and file name */
983:
1.1.1.2 ! root 984: register int c, val;
1.1 root 985: register char *cp, *cq;
986:
987: for(;;){ /* might be several such lines in a row */
988: if( (c=getchar()) != '#' ){
989: if( c != EOF ) ungetc(c,stdin);
990: #ifndef LINT
991: if ( lastloc != PROG) return;
992: cp = ftitle;
993: cq = ititle;
994: while ( *cp ) if (*cp++ != *cq++) return;
995: if ( *cq ) return;
996: psline();
997: #endif
998: return;
999: }
1000:
1001: lxget( ' ', LEXWS );
1002: val = 0;
1003: for( c=getchar(); isdigit(c); c=getchar() ){
1004: val = val*10+ c - '0';
1005: }
1006: ungetc( c, stdin );
1007: lineno = val;
1008: lxget( ' ', LEXWS );
1009: if( (c=getchar()) != '\n' ){
1010: for( cp=ftitle; c!='\n'; c=getchar(),++cp ){
1011: *cp = c;
1012: }
1013: *cp = '\0';
1014: #ifndef LINT
1015: if (ititle[0] == '\0') {
1016: cp = ftitle;
1017: cq = ititle;
1018: while ( *cp )
1019: *cq++ = *cp++;
1020: *cq = '\0';
1021: *--cq = '\0';
1022: #ifndef FLEXNAMES
1023: for ( cp = ititle+1; *(cp-1); cp += 8 ) {
1024: pstab(cp, N_SO);
1025: if (gdebug) printf("0,0,LL%d\n", labelno);
1026: }
1027: #else
1028: pstab(ititle+1, N_SO);
1029: if (gdebug) printf("0,0,LL%d\n", labelno);
1030: #endif
1031:
1032: *cq = '"';
1033: printf("LL%d:\n", labelno++);
1034: }
1035: #endif
1036: }
1037: }
1038: }
1039:
1.1.1.2 ! root 1040: /*
! 1041: * Output assembler string in asmbuf.
! 1042: */
! 1043:
! 1044: asmout()
! 1045: {
! 1046:
! 1047: #ifndef LINT
! 1048: fprintf(stdout, "%s%s\n", ASMRP, &asmbuf[0]);
! 1049: #endif
! 1050: }
! 1051:
1.1 root 1052: #ifdef FLEXNAMES
1053: #define NSAVETAB 4096
1054: char *savetab;
1055: int saveleft;
1056:
1057: char *
1058: savestr(cp)
1059: register char *cp;
1060: {
1061: register int len;
1062:
1063: len = strlen(cp) + 1;
1064: if (len > saveleft) {
1065: saveleft = NSAVETAB;
1066: if (len > saveleft)
1067: saveleft = len;
1068: savetab = (char *)malloc(saveleft);
1069: if (savetab == 0)
1070: cerror("Ran out of memory (savestr)");
1071: }
1072: strncpy(savetab, cp, len);
1073: cp = savetab;
1074: savetab += len;
1075: saveleft -= len;
1076: return (cp);
1077: }
1078:
1079: /*
1080: * The definition for the segmented hash tables.
1081: */
1082: #define MAXHASH 20
1083: #define HASHINC 1013
1084: struct ht {
1085: char **ht_low;
1086: char **ht_high;
1087: int ht_used;
1088: } htab[MAXHASH];
1089:
1090: char *
1091: hash(s)
1092: char *s;
1093: {
1094: register char **h;
1.1.1.2 ! root 1095: register int i;
1.1 root 1096: register char *cp;
1097: struct ht *htp;
1098: int sh;
1099:
1100: /*
1101: * The hash function is a modular hash of
1102: * the sum of the characters with the sum
1103: * doubled before each successive character
1104: * is added.
1105: */
1106: cp = s;
1107: i = 0;
1108: while (*cp)
1109: i = i*2 + *cp++;
1110: sh = (i&077777) % HASHINC;
1111: cp = s;
1112: /*
1113: * There are as many as MAXHASH active
1114: * hash tables at any given point in time.
1115: * The search starts with the first table
1116: * and continues through the active tables
1117: * as necessary.
1118: */
1119: for (htp = htab; htp < &htab[MAXHASH]; htp++) {
1120: if (htp->ht_low == 0) {
1121: register char **hp =
1122: (char **) calloc(sizeof (char **), HASHINC);
1123: if (hp == 0)
1124: cerror("ran out of memory (hash)");
1125: htp->ht_low = hp;
1126: htp->ht_high = htp->ht_low + HASHINC;
1127: }
1128: h = htp->ht_low + sh;
1129: /*
1130: * quadratic rehash increment
1131: * starts at 1 and incremented
1132: * by two each rehash.
1133: */
1134: i = 1;
1135: do {
1136: if (*h == 0) {
1137: if (htp->ht_used > (HASHINC * 3)/4)
1138: break;
1139: htp->ht_used++;
1140: *h = savestr(cp);
1141: return (*h);
1142: }
1143: if (**h == *cp && strcmp(*h, cp) == 0)
1144: return (*h);
1145: h += i;
1146: i += 2;
1147: if (h >= htp->ht_high)
1148: h -= HASHINC;
1149: } while (i < HASHINC);
1150: }
1151: cerror("ran out of hash tables");
1152: }
1153: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.