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