|
|
1.1 root 1: %term NAME 2
2: %term STRING 3
3: %term ICON 4
4: %term FCON 5
5: %term PLUS 6
6: %term MINUS 8
7: %term MUL 11
8: %term AND 14
9: %term OR 17
10: %term ER 19
11: %term QUEST 21
12: %term COLON 22
13: %term ANDAND 23
14: %term OROR 24
15:
16: /* special interfaces for yacc alone */
17: /* These serve as abbreviations of 2 or more ops:
18: ASOP =, = ops
19: RELOP LE,LT,GE,GT
20: EQUOP EQ,NE
21: DIVOP DIV,MOD
22: SHIFTOP LS,RS
23: ICOP ICR,DECR
24: UNOP NOT,COMPL
25: STROP DOT,STREF
26:
27: */
28: %term ASOP 25
29: %term RELOP 26
30: %term EQUOP 27
31: %term DIVOP 28
32: %term SHIFTOP 29
33: %term INCOP 30
34: %term UNOP 31
35: %term STROP 32
36:
37: /* reserved words, etc */
38: %term TYPE 33
39: %term CLASS 34
40: %term STRUCT 35
41: %term RETURN 36
42: %term GOTO 37
43: %term IF 38
44: %term ELSE 39
45: %term SWITCH 40
46: %term BREAK 41
47: %term CONTINUE 42
48: %term WHILE 43
49: %term DO 44
50: %term FOR 45
51: %term DEFAULT 46
52: %term CASE 47
53: %term SIZEOF 48
54: %term ENUM 49
55:
56:
57: /* little symbols, etc. */
58: /* namely,
59:
60: LP (
61: RP )
62:
63: LC {
64: RC }
65:
66: LB [
67: RB ]
68:
69: CM ,
70: SM ;
71:
72: */
73:
74: %term LP 50
75: %term RP 51
76: %term LC 52
77: %term RC 53
78: %term LB 54
79: %term RB 55
80: %term CM 56
81: %term SM 57
82: %term ASSIGN 58
1.1.1.2 ! root 83: %term ASM 59
1.1 root 84:
85: /* at last count, there were 7 shift/reduce, 1 reduce/reduce conflicts
86: /* these involved:
87: if/else
88: recognizing functions in various contexts, including declarations
89: error recovery
90: */
91:
92: %left CM
93: %right ASOP ASSIGN
94: %right QUEST COLON
95: %left OROR
96: %left ANDAND
97: %left OR
98: %left ER
99: %left AND
100: %left EQUOP
101: %left RELOP
102: %left SHIFTOP
103: %left PLUS MINUS
104: %left MUL DIVOP
105: %right UNOP
106: %right INCOP SIZEOF
107: %left LB LP STROP
108: %{
109: # include "mfile1"
110: %}
111:
112: /* define types */
113: %start ext_def_list
114:
115: %type <intval> con_e ifelprefix ifprefix whprefix forprefix doprefix switchpart
116: enum_head str_head name_lp
117: %type <nodep> e .e term attributes oattributes type enum_dcl struct_dcl
118: cast_type null_decl funct_idn declarator fdeclarator nfdeclarator
119: elist
120:
121: %token <intval> CLASS NAME STRUCT RELOP CM DIVOP PLUS MINUS SHIFTOP MUL AND OR ER ANDAND OROR
122: ASSIGN STROP INCOP UNOP ICON
123: %token <nodep> TYPE
124:
125: %%
126:
127: %{
128: static int fake = 0;
129: #ifndef FLEXNAMES
130: static char fakename[NCHNAM+1];
131: #else
132: static char fakename[24];
133: #endif
134: %}
135:
136: ext_def_list: ext_def_list external_def
137: |
1.1.1.2 ! root 138: ={ beg_file(); /* do implementation dep. stuff now */
! 139: ftnend(); }
1.1 root 140: ;
141: external_def: data_def
142: ={ curclass = SNULL; blevel = 0; }
1.1.1.2 ! root 143: | ASM SM
! 144: {
! 145: asmout();
! 146: curclass = SNULL;
! 147: blevel = 0;
! 148: }
1.1 root 149: | error
150: ={ curclass = SNULL; blevel = 0; }
151: ;
152: data_def:
153: oattributes SM
154: ={ $1->in.op = FREE; }
155: | oattributes init_dcl_list SM
156: ={ $1->in.op = FREE; }
157: | oattributes fdeclarator {
158: defid( tymerge($1,$2), curclass==STATIC?STATIC:EXTDEF );
159: #ifndef LINT
160: pfstab(stab[$2->tn.rval].sname);
161: #endif
162: } function_body
163: ={
164: if( blevel ) cerror( "function level error" );
165: if( reached ) retstat |= NRETVAL;
166: $1->in.op = FREE;
167: ftnend();
168: }
169: ;
170:
171: function_body: arg_dcl_list compoundstmt
172: ;
173: arg_dcl_list: arg_dcl_list declaration
174: | ={ blevel = 1; }
175: ;
176:
177: stmt_list: stmt_list statement
178: | /* empty */
179: ={ bccode();
180: locctr(PROG);
181: }
182: ;
183:
184: r_dcl_stat_list : dcl_stat_list attributes SM
185: ={ $2->in.op = FREE;
186: #ifndef LINT
187: plcstab(blevel);
188: #endif
189: }
190: | dcl_stat_list attributes init_dcl_list SM
191: ={ $2->in.op = FREE;
192: #ifndef LINT
193: plcstab(blevel);
194: #endif
195: }
196: ;
197:
198: dcl_stat_list : dcl_stat_list attributes SM
199: ={ $2->in.op = FREE; }
200: | dcl_stat_list attributes init_dcl_list SM
201: ={ $2->in.op = FREE; }
202: | /* empty */
203: ;
204: declaration: attributes declarator_list SM
205: ={ curclass = SNULL; $1->in.op = FREE; }
206: | attributes SM
207: ={ curclass = SNULL; $1->in.op = FREE; }
208: | error SM
209: ={ curclass = SNULL; }
210: ;
211: oattributes: attributes
212: | /* VOID */
213: ={ $$ = mkty(INT,0,INT); curclass = SNULL; }
214: ;
215: attributes: class type
216: ={ $$ = $2; }
217: | type class
218: | class
219: ={ $$ = mkty(INT,0,INT); }
220: | type
221: ={ curclass = SNULL ; }
222: | type class type
223: ={ $1->in.type = types( $1->in.type, $3->in.type, UNDEF );
224: $3->in.op = FREE;
225: }
226: ;
227:
228:
229: class: CLASS
230: ={ curclass = $1; }
231: ;
232:
233: type: TYPE
234: | TYPE TYPE
235: ={ $1->in.type = types( $1->in.type, $2->in.type, UNDEF );
236: $2->in.op = FREE;
237: }
238: | TYPE TYPE TYPE
239: ={ $1->in.type = types( $1->in.type, $2->in.type, $3->in.type );
240: $2->in.op = $3->in.op = FREE;
241: }
242: | struct_dcl
243: | enum_dcl
244: ;
245:
246: enum_dcl: enum_head LC moe_list optcomma RC
247: ={ $$ = dclstruct($1); }
248: | ENUM NAME
249: ={ $$ = rstruct($2,0); stwart = instruct; }
250: ;
251:
252: enum_head: ENUM
253: ={ $$ = bstruct(-1,0); stwart = SEENAME; }
254: | ENUM NAME
255: ={ $$ = bstruct($2,0); stwart = SEENAME; }
256: ;
257:
258: moe_list: moe
259: | moe_list CM moe
260: ;
261:
262: moe: NAME
263: ={ moedef( $1 ); }
264: | NAME ASSIGN con_e
265: ={ strucoff = $3; moedef( $1 ); }
266: ;
267:
268: struct_dcl: str_head LC type_dcl_list optsemi RC
269: ={ $$ = dclstruct($1); }
270: | STRUCT NAME
271: ={ $$ = rstruct($2,$1); }
272: ;
273:
274: str_head: STRUCT
275: ={ $$ = bstruct(-1,$1); stwart=0; }
276: | STRUCT NAME
277: ={ $$ = bstruct($2,$1); stwart=0; }
278: ;
279:
280: type_dcl_list: type_declaration
281: | type_dcl_list SM type_declaration
282: ;
283:
284: type_declaration: type declarator_list
285: ={ curclass = SNULL; stwart=0; $1->in.op = FREE; }
286: | type
287: ={ if( curclass != MOU ){
288: curclass = SNULL;
289: }
290: else {
291: sprintf( fakename, "$%dFAKE", fake++ );
292: #ifdef FLEXSTRINGS
293: /* No need to hash this, we won't look it up */
294: defid( tymerge($1, bdty(NAME,NIL,lookup( savestr(fakename), SMOS ))), curclass );
295: #else
296: defid( tymerge($1, bdty(NAME,NIL,lookup( fakename, SMOS ))), curclass );
297: #endif
298: werror("structure typed union member must be named");
299: }
300: stwart = 0;
301: $1->in.op = FREE;
302: }
303: ;
304:
305:
306: declarator_list: declarator
307: ={ defid( tymerge($<nodep>0,$1), curclass); stwart = instruct; }
308: | declarator_list CM {$<nodep>$=$<nodep>0;} declarator
309: ={ defid( tymerge($<nodep>0,$4), curclass); stwart = instruct; }
310: ;
311: declarator: fdeclarator
312: | nfdeclarator
313: | nfdeclarator COLON con_e
314: %prec CM
315: ={ if( !(instruct&INSTRUCT) ) uerror( "field outside of structure" );
316: if( $3<0 || $3 >= FIELD ){
317: uerror( "illegal field size" );
318: $3 = 1;
319: }
320: defid( tymerge($<nodep>0,$1), FIELD|$3 );
321: $$ = NIL;
322: }
323: | COLON con_e
324: %prec CM
325: ={ if( !(instruct&INSTRUCT) ) uerror( "field outside of structure" );
326: falloc( stab, $2, -1, $<nodep>0 ); /* alignment or hole */
327: $$ = NIL;
328: }
329: | error
330: ={ $$ = NIL; }
331: ;
332:
333: /* int (a)(); is not a function --- sorry! */
334: nfdeclarator: MUL nfdeclarator
335: ={ umul:
336: $$ = bdty( UNARY MUL, $2, 0 ); }
337: | nfdeclarator LP RP
338: ={ uftn:
339: $$ = bdty( UNARY CALL, $1, 0 ); }
340: | nfdeclarator LB RB
341: ={ uary:
342: $$ = bdty( LB, $1, 0 ); }
343: | nfdeclarator LB con_e RB
344: ={ bary:
345: if( (int)$3 <= 0 ) werror( "zero or negative subscript" );
346: $$ = bdty( LB, $1, $3 ); }
347: | NAME
348: ={ $$ = bdty( NAME, NIL, $1 ); }
349: | LP nfdeclarator RP
350: ={ $$=$2; }
351: ;
352: fdeclarator: MUL fdeclarator
353: ={ goto umul; }
354: | fdeclarator LP RP
355: ={ goto uftn; }
356: | fdeclarator LB RB
357: ={ goto uary; }
358: | fdeclarator LB con_e RB
359: ={ goto bary; }
360: | LP fdeclarator RP
361: ={ $$ = $2; }
362: | name_lp name_list RP
363: ={
364: if( blevel!=0 ) uerror("function declaration in bad context");
365: $$ = bdty( UNARY CALL, bdty(NAME,NIL,$1), 0 );
366: stwart = 0;
367: }
368: | name_lp RP
369: ={
370: $$ = bdty( UNARY CALL, bdty(NAME,NIL,$1), 0 );
371: stwart = 0;
372: }
373: ;
374:
375: name_lp: NAME LP
376: ={
377: /* turn off typedefs for argument names */
378: stwart = SEENAME;
379: if( stab[$1].sclass == SNULL )
380: stab[$1].stype = FTN;
381: }
382: ;
383:
384: name_list: NAME
385: ={ ftnarg( $1 ); stwart = SEENAME; }
386: | name_list CM NAME
387: ={ ftnarg( $3 ); stwart = SEENAME; }
388: | error
389: ;
390: /* always preceeded by attributes: thus the $<nodep>0's */
391: init_dcl_list: init_declarator
392: %prec CM
393: | init_dcl_list CM {$<nodep>$=$<nodep>0;} init_declarator
394: ;
395: /* always preceeded by attributes */
396: xnfdeclarator: nfdeclarator
397: ={ defid( $1 = tymerge($<nodep>0,$1), curclass);
398: beginit($1->tn.rval);
399: }
400: | error
401: ;
402: /* always preceeded by attributes */
403: init_declarator: nfdeclarator
404: ={ nidcl( tymerge($<nodep>0,$1) ); }
405: | fdeclarator
406: ={ defid( tymerge($<nodep>0,$1), uclass(curclass) );
407: }
408: | xnfdeclarator optasgn e
409: %prec CM
410: ={ doinit( $3 );
411: endinit(); }
412: | xnfdeclarator optasgn LC init_list optcomma RC
413: ={ endinit(); }
414: | error
415: ;
416:
417: init_list: initializer
418: %prec CM
419: | init_list CM initializer
420: ;
421: initializer: e
422: %prec CM
423: ={ doinit( $1 ); }
424: | ibrace init_list optcomma RC
425: ={ irbrace(); }
426: ;
427:
428: optcomma : /* VOID */
429: | CM
430: ;
431:
432: optsemi : /* VOID */
433: | SM
434: ;
435:
436: optasgn : /* VOID */
437: ={ werror( "old-fashioned initialization: use =" ); }
438: | ASSIGN
439: ;
440:
441: ibrace : LC
442: ={ ilbrace(); }
443: ;
444:
445: /* STATEMENTS */
446:
447: compoundstmt: dcmpstmt
448: | cmpstmt
449: ;
450:
451: dcmpstmt: begin r_dcl_stat_list stmt_list RC
452: ={
453: #ifndef LINT
454: prcstab(blevel);
455: #endif
456: --blevel;
457: if( blevel == 1 ) blevel = 0;
458: clearst( blevel );
459: checkst( blevel );
460: autooff = *--psavbc;
461: regvar = *--psavbc;
462: }
463: ;
464:
465: cmpstmt: begin stmt_list RC
466: ={ --blevel;
467: if( blevel == 1 ) blevel = 0;
468: clearst( blevel );
469: checkst( blevel );
470: autooff = *--psavbc;
471: regvar = *--psavbc;
472: }
473: ;
474:
475: begin: LC
476: ={ if( blevel == 1 ) dclargs();
477: ++blevel;
478: if( psavbc > &asavbc[BCSZ-2] ) cerror( "nesting too deep" );
479: *psavbc++ = regvar;
480: *psavbc++ = autooff;
481: }
482: ;
483:
484: statement: e SM
485: ={ ecomp( $1 ); }
1.1.1.2 ! root 486: | ASM SM
! 487: {
! 488: asmout();
! 489: }
1.1 root 490: | compoundstmt
491: | ifprefix statement
492: ={ deflab($1);
493: reached = 1;
494: }
495: | ifelprefix statement
496: ={ if( $1 != NOLAB ){
497: deflab( $1 );
498: reached = 1;
499: }
500: }
501: | whprefix statement
502: ={ branch( contlab );
503: deflab( brklab );
504: if( (flostat&FBRK) || !(flostat&FLOOP)) reached = 1;
505: else reached = 0;
506: resetbc(0);
507: }
508: | doprefix statement WHILE LP e RP SM
509: ={ deflab( contlab );
510: if( flostat & FCONT ) reached = 1;
511: ecomp( buildtree( CBRANCH, buildtree( NOT, $5, NIL ), bcon( $1 ) ) );
512: deflab( brklab );
513: reached = 1;
514: resetbc(0);
515: }
516: | forprefix .e RP statement
517: ={ deflab( contlab );
518: if( flostat&FCONT ) reached = 1;
519: if( $2 ) ecomp( $2 );
520: branch( $1 );
521: deflab( brklab );
522: if( (flostat&FBRK) || !(flostat&FLOOP) ) reached = 1;
523: else reached = 0;
524: resetbc(0);
525: }
526: | switchpart statement
527: ={ if( reached ) branch( brklab );
528: deflab( $1 );
529: swend();
530: deflab(brklab);
531: if( (flostat&FBRK) || !(flostat&FDEF) ) reached = 1;
532: resetbc(FCONT);
533: }
534: | BREAK SM
535: ={ if( brklab == NOLAB ) uerror( "illegal break");
536: else if(reached) branch( brklab );
537: flostat |= FBRK;
538: if( brkflag ) goto rch;
539: reached = 0;
540: }
541: | CONTINUE SM
542: ={ if( contlab == NOLAB ) uerror( "illegal continue");
543: else branch( contlab );
544: flostat |= FCONT;
545: goto rch;
546: }
547: | RETURN SM
548: ={ retstat |= NRETVAL;
549: branch( retlab );
550: rch:
551: if( !reached ) werror( "statement not reached");
552: reached = 0;
553: }
554: | RETURN e SM
555: ={ register NODE *temp;
556: idname = curftn;
557: temp = buildtree( NAME, NIL, NIL );
558: if(temp->in.type == TVOID)
559: uerror("void function %s cannot return value",
560: stab[idname].sname);
561: temp->in.type = DECREF( temp->in.type );
562: temp = buildtree( RETURN, temp, $2 );
563: /* now, we have the type of the RHS correct */
564: temp->in.left->in.op = FREE;
565: temp->in.op = FREE;
566: ecomp( buildtree( FORCE, temp->in.right, NIL ) );
567: retstat |= RETVAL;
568: branch( retlab );
569: reached = 0;
570: }
571: | GOTO NAME SM
572: ={ register NODE *q;
573: q = block( FREE, NIL, NIL, INT|ARY, 0, INT );
574: q->tn.rval = idname = $2;
575: defid( q, ULABEL );
576: stab[idname].suse = -lineno;
577: branch( stab[idname].offset );
578: goto rch;
579: }
580: | SM
581: | error SM
582: | error RC
583: | label statement
584: ;
585: label: NAME COLON
586: ={ register NODE *q;
587: q = block( FREE, NIL, NIL, INT|ARY, 0, LABEL );
588: q->tn.rval = $1;
589: defid( q, LABEL );
590: reached = 1;
591: }
592: | CASE e COLON
593: ={ addcase($2);
594: reached = 1;
595: }
596: | DEFAULT COLON
597: ={ reached = 1;
598: adddef();
599: flostat |= FDEF;
600: }
601: ;
602: doprefix: DO
603: ={ savebc();
604: if( !reached ) werror( "loop not entered at top");
605: brklab = getlab();
606: contlab = getlab();
607: deflab( $$ = getlab() );
608: reached = 1;
609: }
610: ;
611: ifprefix: IF LP e RP
612: ={ ecomp( buildtree( CBRANCH, $3, bcon( $$=getlab()) ) ) ;
613: reached = 1;
614: }
615: ;
616: ifelprefix: ifprefix statement ELSE
617: ={ if( reached ) branch( $$ = getlab() );
618: else $$ = NOLAB;
619: deflab( $1 );
620: reached = 1;
621: }
622: ;
623:
624: whprefix: WHILE LP e RP
625: ={ savebc();
626: if( !reached ) werror( "loop not entered at top");
627: if( $3->in.op == ICON && $3->tn.lval != 0 ) flostat = FLOOP;
628: deflab( contlab = getlab() );
629: reached = 1;
630: brklab = getlab();
631: if( flostat == FLOOP ) tfree( $3 );
632: else ecomp( buildtree( CBRANCH, $3, bcon( brklab) ) );
633: }
634: ;
635: forprefix: FOR LP .e SM .e SM
636: ={ if( $3 ) ecomp( $3 );
637: else if( !reached ) werror( "loop not entered at top");
638: savebc();
639: contlab = getlab();
640: brklab = getlab();
641: deflab( $$ = getlab() );
642: reached = 1;
643: if( $5 ) ecomp( buildtree( CBRANCH, $5, bcon( brklab) ) );
644: else flostat |= FLOOP;
645: }
646: ;
647: switchpart: SWITCH LP e RP
648: ={ savebc();
649: brklab = getlab();
650: ecomp( buildtree( FORCE, $3, NIL ) );
651: branch( $$ = getlab() );
652: swstart();
653: reached = 0;
654: }
655: ;
656: /* EXPRESSIONS */
657: con_e: { $<intval>$=instruct; stwart=instruct=0; } e
658: %prec CM
659: ={ $$ = icons( $2 ); instruct=$<intval>1; }
660: ;
661: .e: e
662: |
663: ={ $$=0; }
664: ;
665: elist: e
666: %prec CM
667: | elist CM e
668: ={ goto bop; }
669: ;
670:
671: e: e RELOP e
672: ={
673: preconf:
674: if( yychar==RELOP||yychar==EQUOP||yychar==AND||yychar==OR||yychar==ER ){
675: precplaint:
676: if( hflag ) werror( "precedence confusion possible: parenthesize!" );
677: }
678: bop:
679: $$ = buildtree( $2, $1, $3 );
680: }
681: | e CM e
682: ={ $2 = COMOP;
683: goto bop;
684: }
685: | e DIVOP e
686: ={ goto bop; }
687: | e PLUS e
688: ={ if(yychar==SHIFTOP) goto precplaint; else goto bop; }
689: | e MINUS e
690: ={ if(yychar==SHIFTOP ) goto precplaint; else goto bop; }
691: | e SHIFTOP e
692: ={ if(yychar==PLUS||yychar==MINUS) goto precplaint; else goto bop; }
693: | e MUL e
694: ={ goto bop; }
695: | e EQUOP e
696: ={ goto preconf; }
697: | e AND e
698: ={ if( yychar==RELOP||yychar==EQUOP ) goto preconf; else goto bop; }
699: | e OR e
700: ={ if(yychar==RELOP||yychar==EQUOP) goto preconf; else goto bop; }
701: | e ER e
702: ={ if(yychar==RELOP||yychar==EQUOP) goto preconf; else goto bop; }
703: | e ANDAND e
704: ={ goto bop; }
705: | e OROR e
706: ={ goto bop; }
707: | e MUL ASSIGN e
708: ={ abop:
709: $$ = buildtree( ASG $2, $1, $4 );
710: }
711: | e DIVOP ASSIGN e
712: ={ goto abop; }
713: | e PLUS ASSIGN e
714: ={ goto abop; }
715: | e MINUS ASSIGN e
716: ={ goto abop; }
717: | e SHIFTOP ASSIGN e
718: ={ goto abop; }
719: | e AND ASSIGN e
720: ={ goto abop; }
721: | e OR ASSIGN e
722: ={ goto abop; }
723: | e ER ASSIGN e
724: ={ goto abop; }
725: | e QUEST e COLON e
726: ={ $$=buildtree(QUEST, $1, buildtree( COLON, $3, $5 ) );
727: }
728: | e ASOP e
729: ={ werror( "old-fashioned assignment operator" ); goto bop; }
730: | e ASSIGN e
731: ={ goto bop; }
732: | term
733: ;
734: term: term INCOP
735: ={ $$ = buildtree( $2, $1, bcon(1) ); }
736: | MUL term
737: ={ ubop:
738: $$ = buildtree( UNARY $1, $2, NIL );
739: }
740: | AND term
741: ={ if( ISFTN($2->in.type) || ISARY($2->in.type) ){
742: werror( "& before array or function: ignored" );
743: $$ = $2;
744: }
745: else goto ubop;
746: }
747: | MINUS term
748: ={ goto ubop; }
749: | UNOP term
750: ={
751: $$ = buildtree( $1, $2, NIL );
752: }
753: | INCOP term
754: ={ $$ = buildtree( $1==INCR ? ASG PLUS : ASG MINUS,
755: $2,
756: bcon(1) );
757: }
758: | SIZEOF term
759: ={ $$ = doszof( $2 ); }
760: | LP cast_type RP term %prec INCOP
761: ={ $$ = buildtree( CAST, $2, $4 );
762: $$->in.left->in.op = FREE;
763: $$->in.op = FREE;
764: $$ = $$->in.right;
765: }
766: | SIZEOF LP cast_type RP %prec SIZEOF
767: ={ $$ = doszof( $3 ); }
768: | term LB e RB
769: ={ $$ = buildtree( UNARY MUL, buildtree( PLUS, $1, $3 ), NIL ); }
770: | funct_idn RP
771: ={ $$=buildtree(UNARY CALL,$1,NIL); }
772: | funct_idn elist RP
773: ={ $$=buildtree(CALL,$1,$2); }
774: | term STROP NAME
775: ={ if( $2 == DOT ){
776: if( notlval( $1 ) )uerror("structure reference must be addressable");
777: $1 = buildtree( UNARY AND, $1, NIL );
778: }
779: idname = $3;
780: $$ = buildtree( STREF, $1, buildtree( NAME, NIL, NIL ) );
781: }
782: | NAME
783: ={ idname = $1;
784: /* recognize identifiers in initializations */
785: if( blevel==0 && stab[idname].stype == UNDEF ) {
786: register NODE *q;
787: #ifndef FLEXNAMES
788: werror( "undeclared initializer name %.8s", stab[idname].sname );
789: #else
790: werror( "undeclared initializer name %s", stab[idname].sname );
791: #endif
792: q = block( FREE, NIL, NIL, INT, 0, INT );
793: q->tn.rval = idname;
794: defid( q, EXTERN );
795: }
796: $$=buildtree(NAME,NIL,NIL);
797: stab[$1].suse = -lineno;
798: }
799: | ICON
800: ={ $$=bcon(0);
801: $$->tn.lval = lastcon;
802: $$->tn.rval = NONAME;
803: if( $1 ) $$->fn.csiz = $$->in.type = ctype(LONG);
804: }
805: | FCON
806: ={ $$=buildtree(FCON,NIL,NIL);
807: $$->fpn.dval = dcon;
808: }
809: | STRING
810: ={ $$ = getstr(); /* get string contents */ }
811: | LP e RP
812: ={ $$=$2; }
813: ;
814:
815: cast_type: type null_decl
816: ={
817: $$ = tymerge( $1, $2 );
818: $$->in.op = NAME;
819: $1->in.op = FREE;
820: }
821: ;
822:
823: null_decl: /* empty */
824: ={ $$ = bdty( NAME, NIL, -1 ); }
825: | LP RP
826: ={ $$ = bdty( UNARY CALL, bdty(NAME,NIL,-1),0); }
827: | LP null_decl RP LP RP
828: ={ $$ = bdty( UNARY CALL, $2, 0 ); }
829: | MUL null_decl
830: ={ goto umul; }
831: | null_decl LB RB
832: ={ goto uary; }
833: | null_decl LB con_e RB
834: ={ goto bary; }
835: | LP null_decl RP
836: ={ $$ = $2; }
837: ;
838:
839: funct_idn: NAME LP
840: ={ if( stab[$1].stype == UNDEF ){
841: register NODE *q;
842: q = block( FREE, NIL, NIL, FTN|INT, 0, INT );
843: q->tn.rval = $1;
844: defid( q, EXTERN );
845: }
846: idname = $1;
847: $$=buildtree(NAME,NIL,NIL);
848: stab[idname].suse = -lineno;
849: }
850: | term LP
851: ;
852: %%
853:
854: NODE *
855: mkty( t, d, s ) unsigned t; {
856: return( block( TYPE, NIL, NIL, t, d, s ) );
857: }
858:
859: NODE *
860: bdty( op, p, v ) NODE *p; {
861: register NODE *q;
862:
863: q = block( op, p, NIL, INT, 0, INT );
864:
865: switch( op ){
866:
867: case UNARY MUL:
868: case UNARY CALL:
869: break;
870:
871: case LB:
872: q->in.right = bcon(v);
873: break;
874:
875: case NAME:
876: q->tn.rval = v;
877: break;
878:
879: default:
880: cerror( "bad bdty" );
881: }
882:
883: return( q );
884: }
885:
886: dstash( n ){ /* put n into the dimension table */
887: if( curdim >= DIMTABSZ-1 ){
888: cerror( "dimension table overflow");
889: }
890: dimtab[ curdim++ ] = n;
891: }
892:
893: savebc() {
894: if( psavbc > & asavbc[BCSZ-4 ] ){
895: cerror( "whiles, fors, etc. too deeply nested");
896: }
897: *psavbc++ = brklab;
898: *psavbc++ = contlab;
899: *psavbc++ = flostat;
900: *psavbc++ = swx;
901: flostat = 0;
902: }
903:
904: resetbc(mask){
905:
906: swx = *--psavbc;
907: flostat = *--psavbc | (flostat&mask);
908: contlab = *--psavbc;
909: brklab = *--psavbc;
910:
911: }
912:
913: addcase(p) NODE *p; { /* add case to switch */
914:
915: p = optim( p ); /* change enum to ints */
916: if( p->in.op != ICON ){
917: uerror( "non-constant case expression");
918: return;
919: }
920: if( swp == swtab ){
921: uerror( "case not in switch");
922: return;
923: }
924: if( swp >= &swtab[SWITSZ] ){
925: cerror( "switch table overflow");
926: }
927: swp->sval = p->tn.lval;
928: deflab( swp->slab = getlab() );
929: ++swp;
930: tfree(p);
931: }
932:
933: adddef(){ /* add default case to switch */
934: if( swtab[swx].slab >= 0 ){
935: uerror( "duplicate default in switch");
936: return;
937: }
938: if( swp == swtab ){
939: uerror( "default not inside switch");
940: return;
941: }
942: deflab( swtab[swx].slab = getlab() );
943: }
944:
945: swstart(){
946: /* begin a switch block */
947: if( swp >= &swtab[SWITSZ] ){
948: cerror( "switch table overflow");
949: }
950: swx = swp - swtab;
951: swp->slab = -1;
952: ++swp;
953: }
954:
955: swend(){ /* end a switch block */
956:
957: register struct sw *swbeg, *p, *q, *r, *r1;
958: CONSZ temp;
959: int tempi;
960:
961: swbeg = &swtab[swx+1];
962:
963: /* sort */
964:
965: r1 = swbeg;
966: r = swp-1;
967:
968: while( swbeg < r ){
969: /* bubble largest to end */
970: for( q=swbeg; q<r; ++q ){
971: if( q->sval > (q+1)->sval ){
972: /* swap */
973: r1 = q+1;
974: temp = q->sval;
975: q->sval = r1->sval;
976: r1->sval = temp;
977: tempi = q->slab;
978: q->slab = r1->slab;
979: r1->slab = tempi;
980: }
981: }
982: r = r1;
983: r1 = swbeg;
984: }
985:
986: /* it is now sorted */
987:
988: for( p = swbeg+1; p<swp; ++p ){
989: if( p->sval == (p-1)->sval ){
990: uerror( "duplicate case in switch, %d", tempi=p->sval );
991: return;
992: }
993: }
994:
995: genswitch( swbeg-1, swp-swbeg );
996: swp = swbeg-1;
997: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.