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