Added initial stack direction support. Didnt convert xstack but are
[fw/sdcc] / src / SDCC.y
1 /*-----------------------------------------------------------------------
2
3   SDCC.y - parser definition file for sdcc :
4           Written By : Sandeep Dutta . sandeep.dutta@usa.net (1997)
5
6    This program is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by the
8    Free Software Foundation; either version 2, or (at your option) any
9    later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19    
20    In other words, you are welcome to use, share and improve this program.
21    You are forbidden to forbid anyone else to use, share and improve
22    what you give them.   Help stamp out software-hoarding!  
23 -------------------------------------------------------------------------*/
24 %{
25 #include <stdio.h>
26 #include <stdarg.h> 
27 #include <string.h>
28 #include "SDCCglobl.h"
29 #include "SDCCsymt.h"
30 #include "SDCChasht.h"
31 #include "SDCCval.h"
32 #include "SDCCmem.h"
33 #include "SDCCast.h"
34 extern int yyerror (char *);
35 extern FILE     *yyin;
36 extern char srcLstFname[];
37 int NestLevel = 0 ;     /* current NestLevel       */
38 int stackPtr  = 1 ;     /* stack pointer           */
39 int xstackPtr = 0 ;     /* xstack pointer          */
40 int reentrant = 0 ; 
41 int blockNo   = 0 ;     /* sequential block number  */
42 int currBlockno=0 ;
43 extern int yylex();
44 int yyparse(void);
45 extern int noLineno ;
46 char lbuff[1024];      /* local buffer */
47
48 /* break & continue stacks */
49 STACK_DCL(continueStack  ,symbol *,MAX_NEST_LEVEL)
50 STACK_DCL(breakStack  ,symbol *,MAX_NEST_LEVEL)
51 STACK_DCL(forStack  ,symbol *,MAX_NEST_LEVEL)
52 STACK_DCL(swStk   ,ast   *,MAX_NEST_LEVEL)
53 STACK_DCL(blockNum,int,MAX_NEST_LEVEL*3)
54
55 value *cenum = NULL  ;  /* current enumeration  type chain*/
56
57 %}
58 %union {
59     symbol     *sym ;      /* symbol table pointer       */
60     structdef  *sdef;      /* structure definition       */
61     char       yychar[SDCC_NAME_MAX+1];
62     link       *lnk ;      /* declarator  or specifier   */
63     int        yyint;      /* integer value returned     */
64     value      *val ;      /* for integer constant       */
65     initList   *ilist;     /* initial list               */
66     char       yyinline[MAX_INLINEASM]; /* inlined assembler code */
67     ast       *asts;     /* expression tree            */
68 }
69
70 %token <yychar> IDENTIFIER TYPE_NAME
71 %token <val>   CONSTANT   STRING_LITERAL
72 %token SIZEOF 
73 %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
74 %token AND_OP OR_OP 
75 %token <yyint> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
76 %token <yyint> SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
77 %token <yyint> XOR_ASSIGN OR_ASSIGN
78 %token TYPEDEF EXTERN STATIC AUTO REGISTER CODE INTERRUPT SFR AT SBIT
79 %token REENTRANT USING  XDATA DATA IDATA PDATA VAR_ARGS CRITICAL
80 %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT
81 %token STRUCT UNION ENUM ELIPSIS RANGE FAR _XDATA _CODE _GENERIC _NEAR _PDATA _IDATA
82 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN 
83 %token <yyinline> INLINEASM
84 %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT
85 %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL  ENDFUNCTION JUMPTABLE
86 %token RRC RLC 
87 %token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND
88
89 %type <yyint>  Interrupt_storage
90 %type <sym> identifier  declarator  declarator2 enumerator_list enumerator
91 %type <sym> struct_declarator
92 %type <sym> struct_declarator_list  struct_declaration   struct_declaration_list
93 %type <sym> declaration init_declarator_list init_declarator
94 %type <sym> declaration_list identifier_list parameter_identifier_list
95 %type <sym> declarator2_using_reentrant while do for
96 %type <lnk> pointer type_specifier_list type_specifier type_name
97 %type <lnk> storage_class_specifier struct_or_union_specifier
98 %type <lnk> declaration_specifiers  sfr_reg_bit type_specifier2
99 %type <lnk> using_reentrant using_reentrant_interrupt enum_specifier
100 %type <lnk> abstract_declarator abstract_declarator2 far_near_pointer far_near
101 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
102 %type <sdef> stag opt_stag
103 %type <asts> primary_expr
104 %type <asts> postfix_expr unary_expr cast_expr multiplicative_expr
105 %type <asts> additive_expr shift_expr relational_expr equality_expr
106 %type <asts> and_expr exclusive_or_expr inclusive_or_expr logical_or_expr
107 %type <asts> logical_and_expr conditional_expr assignment_expr constant_expr
108 %type <asts> expr argument_expr_list function_definition expr_opt
109 %type <asts> statement_list statement labeled_statement compound_statement
110 %type <asts> expression_statement selection_statement iteration_statement
111 %type <asts> jump_statement function_body else_statement string_literal
112 %type <ilist> initializer initializer_list
113 %type <yyint> unary_operator  assignment_operator struct_or_union
114
115 %start file
116
117 %%
118
119 file
120    : external_definition       
121    | file external_definition
122    ;
123
124 external_definition
125    : function_definition     { blockNo=0;}
126    | declaration             { 
127                                addSymChain ($1);
128                                allocVariables ($1) ;
129                                cleanUpLevel (SymbolTab,1);
130                              }
131    ;
132
133 function_definition
134    : declarator function_body  {   /* function type not specified */
135                                    /* assume it to be 'int'       */
136                                    addDecl($1,0,newIntLink());
137                                    $$ = createFunction($1,$2); 
138                                } 
139    | declaration_specifiers declarator function_body  
140                                 {   
141                                     pointerTypes($2->type,copyLinkChain($1));
142                                     addDecl($2,0,$1); 
143                                     $$ = createFunction($2,$3);   
144                                 }
145    ;
146
147 using_reentrant
148    : using_reentrant_interrupt
149    | using_reentrant_interrupt using_reentrant { $$ = mergeSpec($1,$2); }
150    ;
151
152 using_reentrant_interrupt
153    :  USING CONSTANT {
154                         $$ = newLink() ;
155                         $$->class = SPECIFIER   ;
156                         SPEC_BNKF($$) = 1;
157                         SPEC_BANK($$) = (int) floatFromVal($2);                       
158                      }
159    |  REENTRANT      {  $$ = newLink ();
160                         $$->class = SPECIFIER   ;
161                         SPEC_RENT($$) = 1;
162                      }
163    |  CRITICAL       {  $$ = newLink ();
164                         $$->class = SPECIFIER   ;
165                         SPEC_CRTCL($$) = 1;
166                      }
167    |  Interrupt_storage
168                      {
169                         $$ = newLink () ;
170                         $$->class = SPECIFIER ;
171                         SPEC_INTN($$) = $1 ;
172                         SPEC_INTRTN($$) = 1;
173                      }
174    ;
175
176 function_body
177    : compound_statement                   
178    | declaration_list compound_statement
179          {
180             werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
181             exit(1);
182          }
183    ;
184
185 primary_expr
186    : identifier      {  $$ = newAst(EX_VALUE,symbolVal($1));  }
187    | CONSTANT        {  $$ = newAst(EX_VALUE,$1);  }
188    | string_literal  
189    | '(' expr ')'    {  $$ = $2 ;                   }
190    ;
191          
192 string_literal
193     : STRING_LITERAL                    { $$ = newAst(EX_VALUE,$1); }
194     ;
195
196 postfix_expr
197    : primary_expr
198    | postfix_expr '[' expr ']'          { $$ = newNode  ('[', $1, $3) ; }
199    | postfix_expr '(' ')'               { $$ = newNode  (CALL,$1,NULL); 
200                                           $$->left->funcName = 1;}
201    | postfix_expr '(' argument_expr_list ')'
202           {        
203             $$ = newNode  (CALL,$1,$3) ; $$->left->funcName = 1;
204           }
205    | postfix_expr '.' identifier       
206                       {    
207                         $3 = newSymbol($3->name,NestLevel);
208                         $3->implicit = 1;
209                         $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst(EX_VALUE,symbolVal($3)));
210 /*                      $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ;                   */
211                       }
212    | postfix_expr PTR_OP identifier    
213                       { 
214                         $3 = newSymbol($3->name,NestLevel);
215                         $3->implicit = 1;                       
216                         $$ = newNode(PTR_OP,$1,newAst(EX_VALUE,symbolVal($3)));
217                       }
218    | postfix_expr INC_OP   
219                       { $$ = newNode(INC_OP,$1,NULL);}
220    | postfix_expr DEC_OP
221                       { $$ = newNode(DEC_OP,$1,NULL); }
222    ;
223
224 argument_expr_list
225    : assignment_expr 
226    | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
227    ;
228
229 unary_expr
230    : postfix_expr
231    | INC_OP unary_expr        { $$ = newNode(INC_OP,NULL,$2);  }
232    | DEC_OP unary_expr        { $$ = newNode(DEC_OP,NULL,$2);  }
233    | unary_operator cast_expr { $$ = newNode($1,$2,NULL)    ;  }
234    | SIZEOF unary_expr        { $$ = newNode(SIZEOF,NULL,$2);  }
235    | SIZEOF '(' type_name ')' { $$ = newAst(EX_VALUE,sizeofOp($3)); }
236    ;
237               
238 unary_operator
239    : '&'    { $$ = '&' ;}
240    | '*'    { $$ = '*' ;}
241    | '+'    { $$ = '+' ;}
242    | '-'    { $$ = '-' ;}
243    | '~'    { $$ = '~' ;}
244    | '!'    { $$ = '!' ;}
245    ;
246
247 cast_expr
248    : unary_expr
249    | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst(EX_LINK,$2),$4); }
250    ;
251
252 multiplicative_expr
253    : cast_expr
254    | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
255    | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
256    | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
257    ;
258
259 additive_expr
260    : multiplicative_expr
261    | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
262    | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
263    ;
264
265 shift_expr
266    : additive_expr
267    | shift_expr LEFT_OP additive_expr  { $$ = newNode(LEFT_OP,$1,$3); }
268    | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
269    ;
270
271 relational_expr
272    : shift_expr
273    | relational_expr '<' shift_expr    { $$ = newNode('<',$1,$3); }
274    | relational_expr '>' shift_expr    { $$ = newNode('>',$1,$3); }
275    | relational_expr LE_OP shift_expr  { 
276        /* $$ = newNode(LE_OP,$1,$3); */
277        /* getting 8051 specific here : will change
278           LE_OP operation to "not greater than" i.e.
279           ( a <= b ) === ( ! ( a > b )) */
280        $$ = newNode('!', 
281                     newNode('>', $1 , $3 ),
282                     NULL);
283    }
284    | relational_expr GE_OP shift_expr  { 
285        /* $$ = newNode(GE_OP,$1,$3) ; */
286        /* getting 8051 specific here : will change
287           GE_OP operation to "not less than" i.e.
288           ( a >= b ) === ( ! ( a < b )) */
289        $$ = newNode('!',
290                     newNode('<', $1 , $3 ),
291                     NULL);
292    }
293    ;
294
295 equality_expr
296    : relational_expr
297    | equality_expr EQ_OP relational_expr  { $$ = newNode(EQ_OP,$1,$3);}
298    | equality_expr NE_OP relational_expr  
299           { 
300               /* $$ = newNode(NE_OP,$1,$3); */
301               /* NE_OP changed :            
302                  expr1 != expr2 is equivalent to
303                  (! expr1 == expr2) */
304               $$ = newNode('!',
305                            newNode(EQ_OP,$1,$3),
306                            NULL);
307           }       
308    ;
309
310 and_expr
311    : equality_expr
312    | and_expr '&' equality_expr  { $$ = newNode('&',$1,$3);}
313    ;
314
315 exclusive_or_expr
316    : and_expr
317    | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
318    ;
319
320 inclusive_or_expr
321    : exclusive_or_expr
322    | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
323    ;
324
325 logical_and_expr
326    : inclusive_or_expr
327    | logical_and_expr AND_OP inclusive_or_expr 
328                                  { $$ = newNode(AND_OP,$1,$3);}
329    ;
330
331 logical_or_expr
332    : logical_and_expr
333    | logical_or_expr OR_OP logical_and_expr  
334                                  { $$ = newNode(OR_OP,$1,$3); }
335    ;
336
337 conditional_expr
338    : logical_or_expr
339    | logical_or_expr '?' logical_or_expr ':' conditional_expr  
340                      {
341                         $$ = newNode(':',$3,$5) ;
342                         $$ = newNode('?',$1,$$) ;
343                      }                        
344    ;
345
346 assignment_expr
347    : conditional_expr
348    | unary_expr assignment_operator assignment_expr   
349                      { 
350                                  
351                              switch ($2) {
352                              case '=':
353                                      $$ = newNode($2,$1,$3);
354                                      break;
355                              case MUL_ASSIGN:
356                                      $$ = newNode('=',$1,newNode('*',copyAst($1),$3));
357                                      break;
358                              case DIV_ASSIGN:
359                                      $$ = newNode('=',$1,newNode('/',copyAst($1),$3));
360                                      break;
361                              case ADD_ASSIGN:
362                                      $$ = newNode('=',$1,newNode('+',copyAst($1),$3));
363                                      break;
364                              case SUB_ASSIGN:
365                                      $$ = newNode('=',$1,newNode('-',copyAst($1),$3));
366                                      break;
367                              case LEFT_ASSIGN:
368                                      $$ = newNode('=',$1,newNode(LEFT_OP,copyAst($1),$3));
369                                      break;
370                              case RIGHT_ASSIGN:
371                                      $$ = newNode('=',$1,newNode(RIGHT_OP,copyAst($1),$3));
372                                      break;
373                              case AND_ASSIGN:
374                                      $$ = newNode('=',$1,newNode('&',copyAst($1),$3));
375                                      break;
376                              case XOR_ASSIGN:
377                                      $$ = newNode('=',$1,newNode('^',copyAst($1),$3));
378                                      break;
379                              case OR_ASSIGN:
380                                      $$ = newNode('=',$1,newNode('|',copyAst($1),$3));
381                                      break;
382                              default :
383                                      $$ = NULL;
384                              }
385                                      
386                      }
387 ;
388
389 assignment_operator
390    : '='             { $$ = '=' ;}
391    | MUL_ASSIGN
392    | DIV_ASSIGN
393    | MOD_ASSIGN
394    | ADD_ASSIGN
395    | SUB_ASSIGN
396    | LEFT_ASSIGN
397    | RIGHT_ASSIGN
398    | AND_ASSIGN
399    | XOR_ASSIGN
400    | OR_ASSIGN
401    ;
402
403 expr
404    : assignment_expr
405    | expr ',' assignment_expr { $$ = newNode(',',$1,$3);}
406    ;
407
408 constant_expr
409    : conditional_expr 
410    ;
411
412 declaration
413    : declaration_specifiers ';'  { $$ = NULL ; }
414    | declaration_specifiers init_declarator_list ';'
415       {
416          /* add the specifier list to the id */
417          symbol *sym , *sym1;
418
419          for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
420              link *lnk = copyLinkChain($1);
421              /* do the pointer stuff */
422              pointerTypes(sym->type,lnk);
423              addDecl (sym,0,lnk) ;
424          }
425         
426          $$ = sym1 ;
427       }
428    ;
429
430 declaration_specifiers
431    : storage_class_specifier                                            { $$ = $1; }
432    | storage_class_specifier declaration_specifiers { 
433      /* if the decl $2 is not a specifier */
434      /* find the spec and replace it      */
435      if ( !IS_SPEC($2)) {
436        link *lnk = $2 ;
437        while (lnk && !IS_SPEC(lnk->next))
438          lnk = lnk->next;
439        lnk->next = mergeSpec($1,lnk->next);
440        $$ = $2 ;
441      }
442      else
443        $$ = mergeSpec($1,$2); 
444    }
445    | type_specifier                                 { $$ = $1; }
446    | type_specifier declaration_specifiers          { 
447      /* if the decl $2 is not a specifier */
448      /* find the spec and replace it      */
449      if ( !IS_SPEC($2)) {
450        link *lnk = $2 ;
451        while (lnk && !IS_SPEC(lnk->next))
452          lnk = lnk->next;
453        lnk->next = mergeSpec($1,lnk->next);
454        $$ = $2 ;
455      }
456      else
457        $$ = mergeSpec($1,$2); 
458    }
459    ;
460
461 init_declarator_list
462    : init_declarator
463    | init_declarator_list ',' init_declarator      { $3->next = $1 ; $$ = $3;}
464    ;
465
466 init_declarator
467    : declarator                  { $1->ival = NULL ; }
468    | declarator '=' initializer  { $1->ival = $3   ; }
469    ;
470
471
472 storage_class_specifier
473    : TYPEDEF   {
474                   $$ = newLink () ;
475                   $$->class = SPECIFIER ;
476                   SPEC_TYPEDEF($$) = 1 ;
477                }
478    | EXTERN    {
479                   $$ = newLink();
480                   $$->class = SPECIFIER ;
481                   SPEC_EXTR($$) = 1 ;
482                }
483    | STATIC    {
484                   $$ = newLink ();
485                   $$->class = SPECIFIER ;
486                   SPEC_STAT($$) = 1 ;
487                }
488    | AUTO      {
489                   $$ = newLink () ;
490                   $$->class = SPECIFIER ;
491                   SPEC_SCLS($$) = S_AUTO  ;
492                }
493    | REGISTER  {
494                   $$ = newLink ();
495                   $$->class = SPECIFIER ;
496                   SPEC_SCLS($$) = S_REGISTER ;
497                }
498    ;
499
500 Interrupt_storage
501    : INTERRUPT CONSTANT  { $$ = (int) floatFromVal($2) ;  }
502    ;
503
504 type_specifier
505    : type_specifier2
506    | type_specifier2 AT CONSTANT
507         {
508            /* add this to the storage class specifier  */
509            SPEC_ABSA($1) = 1;   /* set the absolute addr flag */
510            /* now get the abs addr from value */
511            SPEC_ADDR($1) = (int) floatFromVal ($3) ;
512         }
513    ;
514
515 type_specifier2
516    : CHAR   {
517                $$=newLink();
518                $$->class = SPECIFIER   ;
519                SPEC_NOUN($$) = V_CHAR  ;
520             }
521    | SHORT  {
522                $$=newLink();
523                $$->class = SPECIFIER   ;
524                SPEC_LONG($$) = 0      ;
525                SPEC_SHORT($$) = 1        ;
526             }
527    | INT    {
528                $$=newLink();
529                $$->class = SPECIFIER   ;
530                SPEC_NOUN($$) = V_INT   ;
531             }
532    | LONG   {
533                $$=newLink();
534                $$->class = SPECIFIER   ;
535                SPEC_LONG($$) = 1       ;
536                SPEC_SHORT($$) = 0;
537             }
538    | SIGNED {
539                $$=newLink();
540                $$->class = SPECIFIER   ;
541                SPEC_USIGN($$) = 0       ;
542             }
543    | UNSIGNED  {
544                $$=newLink();
545                $$->class = SPECIFIER   ;
546                SPEC_USIGN($$) = 1       ;
547             }
548    | VOID   {
549                $$=newLink();
550                $$->class = SPECIFIER   ;
551                SPEC_NOUN($$) = V_VOID  ;
552             }
553    | CONST  {
554                $$=newLink();
555                $$->class = SPECIFIER ;
556                SPEC_SCLS($$) = S_CONSTANT ;
557                SPEC_CONST($$) = 1;
558             }
559    | VOLATILE  {
560                $$=newLink();
561                $$->class = SPECIFIER ;
562                SPEC_VOLATILE($$) = 1 ;
563             }
564    | FLOAT  {
565                $$=newLink();
566                SPEC_NOUN($$) = V_FLOAT;
567                $$->class = SPECIFIER ;
568             }
569    | XDATA     {
570                   $$ = newLink ();
571                   $$->class = SPECIFIER ;
572                   SPEC_SCLS($$) = S_XDATA  ;
573                }
574    | CODE      {
575                   $$ = newLink () ;
576                   $$->class = SPECIFIER  ;
577                   SPEC_SCLS($$) = S_CODE ;                 
578                }
579    | DATA      {
580                   $$ = newLink ();
581                   $$->class = SPECIFIER ;
582                   SPEC_SCLS($$) = S_DATA   ;
583                }
584    | IDATA     {
585                   $$ = newLink ();
586                   $$->class = SPECIFIER ;
587                   SPEC_SCLS($$) = S_IDATA  ;
588                }
589    | PDATA     { 
590                   $$ = newLink ();
591                   $$->class = SPECIFIER ;
592                   SPEC_SCLS($$) = S_PDATA  ;
593                }
594    | BIT    {
595                $$=newLink();
596                $$->class = SPECIFIER   ;
597                SPEC_NOUN($$) = V_BIT   ;
598                SPEC_SCLS($$) = S_BIT   ;
599                SPEC_BLEN($$) = 1;
600                SPEC_BSTR($$) = 0;
601             }
602
603    | struct_or_union_specifier
604    | enum_specifier     {                           
605                            cenum = NULL ;
606                            $$ = $1 ;                              
607                         }
608    | TYPE_NAME    
609          {
610             symbol *sym;
611             link   *p  ;
612
613             sym = findSym(TypedefTab,NULL,$1) ;
614             $$ = p = copyLinkChain(sym->type);
615             SPEC_TYPEDEF(getSpec(p)) = 0;
616          }
617    | sfr_reg_bit
618    ;
619
620 sfr_reg_bit
621    :  SBIT  {
622                $$ = newLink() ;
623                $$->class = SPECIFIER ;
624                SPEC_NOUN($$) = V_SBIT;
625                SPEC_SCLS($$) = S_SBIT;
626             }
627    |  SFR   {
628                $$ = newLink() ;
629                $$->class = SPECIFIER ;
630                SPEC_NOUN($$) = V_CHAR;
631                SPEC_SCLS($$) = S_SFR ;
632                SPEC_USIGN($$) = 1 ;
633             }
634    ;
635
636 struct_or_union_specifier
637    : struct_or_union opt_stag '{' struct_declaration_list '}'
638         {
639            structdef *sdef ;
640
641            /* Create a structdef   */
642            sdef = $2 ;
643            sdef->fields   = reverseSyms($4) ;   /* link the fields */
644            sdef->size  = compStructSize($1,sdef);   /* update size of  */
645
646            /* Create the specifier */
647            $$ = newLink () ;
648            $$->class = SPECIFIER   ;
649            SPEC_NOUN($$) = V_STRUCT;
650            SPEC_STRUCT($$)= sdef ;
651         }
652    | struct_or_union stag
653          {
654             $$ = newLink() ;
655             $$->class = SPECIFIER   ;
656             SPEC_NOUN($$) = V_STRUCT;
657             SPEC_STRUCT($$) = $2 ;
658          }
659    ;
660
661 struct_or_union
662    : STRUCT          { $$ = STRUCT ; }
663    | UNION           { $$ = UNION  ; }
664    ;
665
666 opt_stag
667    : stag
668    |  {  /* synthesize a name add to structtable */
669          $$ = newStruct(genSymName(NestLevel)) ;
670          $$->level = NestLevel ;
671          addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ;
672       }
673    ;
674
675 stag
676    :  identifier  {  /* add name to structure table */
677                      $$ = findSymWithBlock (StructTab,$1,currBlockno);
678                      if (! $$ ) {
679                         $$ = newStruct($1->name) ;
680                         $$->level = NestLevel ;
681                         addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ;                  
682                      }
683                   }
684    ;
685
686 struct_declaration_list
687    : struct_declaration
688    | struct_declaration_list struct_declaration
689        {
690            symbol *sym = $2;
691            /* go to the end of the chain */
692            while (sym->next) sym = sym->next;
693
694            sym->next = $1 ;
695            $$ = $2;
696        }
697    ;
698
699 struct_declaration
700    : type_specifier_list struct_declarator_list ';'
701        {
702            /* add this type to all the symbols */
703            symbol *sym ;
704            for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
705                
706                pointerTypes(sym->type,copyLinkChain($1));
707                if (!sym->type) {
708                    sym->type = copyLinkChain($1);
709                    sym->etype = getSpec(sym->type);
710                }
711                else
712                    addDecl (sym,0,cloneSpec($1));              
713                
714            }
715            $$ = $2;
716        }
717    ;
718
719 struct_declarator_list
720    : struct_declarator
721    | struct_declarator_list ',' struct_declarator
722        {
723            $3->next  = $1 ;
724            $$ = $3 ;
725        }
726    ;
727
728 struct_declarator
729    : declarator
730    | ':' constant_expr  {  
731                            $$ = newSymbol (genSymName(NestLevel),NestLevel) ; 
732                            $$->bitVar = (int) floatFromVal(constExprValue($2,TRUE));
733                         }                        
734    | declarator ':' constant_expr 
735                         { 
736                           $1->bitVar = (int) floatFromVal(constExprValue($3,TRUE));                     
737                         }
738    ;
739
740 enum_specifier
741    : ENUM            '{' enumerator_list '}' {
742                                                 addSymChain ($3);
743                                                 allocVariables(reverseSyms($3)) ;
744                                                 $$ = copyLinkChain(cenum->type);
745                                              }
746    | ENUM identifier '{' enumerator_list '}' {
747                                                 symbol *csym ;
748
749                                                 $2->type = copyLinkChain(cenum->type);
750                                                 $2->etype = getSpec($2->type);
751                                                 /* add this to the enumerator table */
752                                                 if (!(csym=findSym(enumTab,$2,$2->name)) && 
753                                                     (csym && csym->level == $2->level))
754                                                    werror(E_DUPLICATE_TYPEDEF,csym->name);
755
756                                                 addSym ( enumTab,$2,$2->name,$2->level,$2->block);
757                                                 addSymChain ($4);
758                                                 allocVariables (reverseSyms($4));
759                                                 $$ = copyLinkChain(cenum->type);
760                                                 SPEC_SCLS(getSpec($$)) = 0 ;
761                                              }
762    | ENUM identifier                         {
763                                                 symbol *csym ;
764
765                                                 /* check the enumerator table */
766                                                 if ((csym = findSym(enumTab,$2,$2->name)))
767                                                    $$ = copyLinkChain(csym->type);
768                                                 else  {
769                                                    $$ = newLink() ;
770                                                    $$->class = SPECIFIER   ;
771                                                    SPEC_NOUN($$) = V_INT   ;
772                                                 }
773
774                                                 SPEC_SCLS(getSpec($$)) = 0 ;
775                                              }
776    ;
777
778 enumerator_list
779    : enumerator
780    | enumerator_list ',' enumerator {
781                                        $3->next = $1 ;
782                                        $$ = $3  ;
783                                     }
784    ;
785
786 enumerator
787    : identifier opt_assign_expr  {
788                                     /* make the symbol one level up */
789                                     $1->level-- ;
790                                     $1->type = copyLinkChain($2->type); 
791                                     $1->etype= getSpec($1->type);
792                                     SPEC_ENUM($1->etype) = 1;
793                                     $$ = $1 ;
794
795                                  }
796    ;
797
798 opt_assign_expr
799    :  '='   constant_expr  {
800                               value *val ;
801                                                         
802                               val = constExprValue($2,TRUE);                         
803                               $$ = cenum = val ;
804                            }                           
805    |                       {                              
806                               if (cenum)  {
807                                  sprintf(lbuff,"%d",(int) floatFromVal(cenum)+1);
808                                  $$ = cenum = constVal(lbuff);
809                               }
810                               else {
811                                  sprintf(lbuff,"%d",0);
812                                  $$ = cenum = constVal(lbuff);
813                               }   
814                            }
815    ;
816
817 declarator
818    : declarator2_using_reentrant        { $$ = $1; }
819    | pointer declarator2_using_reentrant
820          {
821              addDecl ($2,0,reverseLink($1));
822              $$ = $2 ;
823          }
824    ;
825
826 declarator2_using_reentrant
827    : declarator2                  { $$ = $1 ; } 
828    | declarator2 using_reentrant  { addDecl ($1,0,$2); }     
829    ;
830
831 declarator2
832    : identifier
833    | '(' declarator ')'     { $$ = $2; }
834    | declarator2 '[' ']'
835          {
836             link   *p;
837
838             p = newLink ();
839             DCL_TYPE(p) = ARRAY ;
840             DCL_ELEM(p) = 0     ;
841             addDecl($1,0,p);
842          }
843    | declarator2 '[' constant_expr ']'
844          {
845             link   *p ;
846                         value *tval;
847                         
848             p = (tval = constExprValue($3,TRUE))->etype;
849             /* if it is not a constant then Error  */
850             if ( SPEC_SCLS(p) != S_LITERAL)
851                werror(E_CONST_EXPECTED) ;
852             else {
853                p = newLink ();
854                DCL_TYPE(p) = ARRAY ;
855                DCL_ELEM(p) = (int) floatFromVal(tval) ;
856                addDecl($1,0,p);
857             }                           
858          }
859    | declarator2 '('  ')'       {  addDecl ($1,FUNCTION,NULL) ;   }
860    | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
861          {
862            
863              addDecl ($1,FUNCTION,NULL) ;
864            
865              $1->hasVargs = IS_VARG($4);
866              $1->args = reverseVal($4)  ;
867              
868              /* nest level was incremented to take care of the parms  */
869              NestLevel-- ;
870              currBlockno--;
871              $$ = $1;
872          }
873    | declarator2 '(' parameter_identifier_list ')'
874          {         
875            werror(E_OLD_STYLE,$1->name) ;         
876            
877            /* assume it returns an it */
878            $1->type = $1->etype = newIntLink();
879            $$ = $1 ;
880          }
881    ;
882
883 pointer
884    : far_near_pointer { $$ = $1 ;}
885    | far_near_pointer type_specifier_list   
886          {
887              $$ = $1  ;         
888              DCL_TSPEC($1) = $2;
889          }
890    | far_near_pointer pointer         
891          {
892              $$ = $1 ;          
893              $$->next = $2 ;
894          }
895    | far_near_pointer type_specifier_list pointer
896          {
897              $$ = $1 ;               
898              if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
899                  DCL_PTR_CONST($1) = SPEC_CONST($2);
900                  DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
901                  switch (SPEC_SCLS($2)) {
902                  case S_XDATA:
903                      DCL_TYPE($3) = FPOINTER;
904                      break;
905                  case S_IDATA:
906                      DCL_TYPE($3) = IPOINTER ;
907                      break;
908                  case S_PDATA:
909                      DCL_TYPE($3) = PPOINTER ;
910                      break;
911                  case S_DATA:
912                      DCL_TYPE($3) = POINTER ;
913                      break;
914                  case S_CODE:
915                      DCL_PTR_CONST($3) = 1;
916                      DCL_TYPE($3) = CPOINTER ;
917                      break;
918                  }
919              }
920              else 
921                  werror (W_PTR_TYPE_INVALID);
922              $$->next = $3 ;
923          }
924    ;
925
926 far_near_pointer
927    :  far_near '*'   {
928                         if ($1 == NULL) {
929                            $$ = newLink();
930                            DCL_TYPE($$) = POINTER ;
931                         }
932                         else
933                            $$ = $1 ;
934       }
935    ;
936
937 far_near
938    : _XDATA    { $$ = newLink() ; DCL_TYPE($$) = FPOINTER ; }
939    | _CODE     { $$ = newLink() ; DCL_TYPE($$) = CPOINTER ;  DCL_PTR_CONST($$) = 1;}
940    | _PDATA    { $$ = newLink() ; DCL_TYPE($$) = PPOINTER ; } 
941    | _IDATA    { $$ = newLink() ; DCL_TYPE($$) = IPOINTER ; }
942    | _NEAR     { $$ = NULL ; }
943    | _GENERIC  { $$ = newLink() ; DCL_TYPE($$) = GPOINTER ; } 
944    |           { $$ = newLink() ; DCL_TYPE($$) = UPOINTER ; }
945    ;
946
947 type_specifier_list
948    : type_specifier
949    | type_specifier_list type_specifier         {  $$ = mergeSpec ($1,$2); }
950    ;
951
952 parameter_identifier_list
953    : identifier_list
954    | identifier_list ',' ELIPSIS
955    ;
956
957 identifier_list
958    : identifier
959    | identifier_list ',' identifier         
960          {            
961            $3->next = $1;
962            $$ = $3 ;
963          }
964    ;
965
966 parameter_type_list
967         : parameter_list
968         | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
969         ;
970
971 parameter_list
972    : parameter_declaration 
973    | parameter_list ',' parameter_declaration
974          {
975             $3->next = $1 ;
976             $$ = $3 ;       
977          }
978    ;
979
980 parameter_declaration
981    : type_specifier_list declarator 
982                {        
983                   symbol *loop ;
984                   pointerTypes($2->type,$1);
985                   addDecl ($2,0,$1);              
986                   for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
987                   addSymChain ($2);
988                   $$ = symbolVal($2);
989                }
990    | type_name { 
991                   $$ = newValue() ; 
992                   $$->type = $1;
993                   $$->etype = getSpec($$->type);
994                }
995    ;
996
997 type_name
998    : type_specifier_list  { $$ = $1 ;}
999    | type_specifier_list abstract_declarator 
1000                {
1001                  /* go to the end of the list */
1002                  link *p;
1003                  pointerTypes($2,$1);
1004                  for ( p = $2 ; p->next ; p=p->next);
1005                   p->next = $1 ;
1006                   $$ = $2 ;
1007                }   
1008    ;
1009
1010 abstract_declarator
1011    : pointer { $$ = reverseLink($1); }
1012    | abstract_declarator2
1013    | pointer abstract_declarator2   { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;} 
1014    ;
1015
1016 abstract_declarator2
1017    : '(' abstract_declarator ')'    { $$ = $2 ; }
1018    | '[' ']'                        {             
1019                                        $$ = newLink ();
1020                                        DCL_TYPE($$) = ARRAY ;
1021                                        DCL_ELEM($$) = 0     ;
1022                                     }
1023    | '[' constant_expr ']'          { 
1024                                        value *val ;
1025                                        $$ = newLink ();
1026                                        DCL_TYPE($$) = ARRAY ;
1027                                        DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1028                                     }
1029    | abstract_declarator2 '[' ']'   {
1030                                        $$ = newLink ();
1031                                        DCL_TYPE($$) = ARRAY ;
1032                                        DCL_ELEM($$) = 0     ;
1033                                        $$->next = $1 ;
1034                                     }
1035    | abstract_declarator2 '[' constant_expr ']'
1036                                     {
1037                                        value *val ;
1038                                        $$ = newLink ();
1039                                        DCL_TYPE($$) = ARRAY ;
1040                                        DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1041                                        $$->next = $1 ;
1042                                     }
1043    | '(' ')'                        { $$ = NULL;}
1044    | '(' parameter_type_list ')'    { $$ = NULL;}   
1045    | abstract_declarator2 '(' ')'
1046    | abstract_declarator2 '(' parameter_type_list ')'
1047    ;
1048
1049 initializer
1050    : assignment_expr                { $$ = newiList(INIT_NODE,$1); }
1051    | '{'  initializer_list '}'      { $$ = newiList(INIT_DEEP,revinit($2)); }
1052    | '{'  initializer_list ',' '}'  { $$ = newiList(INIT_DEEP,revinit($2)); }
1053    ;
1054
1055 initializer_list
1056    : initializer
1057    | initializer_list ',' initializer  {  $3->next = $1; $$ = $3; }
1058    ;
1059
1060 statement
1061    : labeled_statement
1062    | compound_statement
1063    | expression_statement
1064    | selection_statement
1065    | iteration_statement
1066    | jump_statement
1067    | INLINEASM  ';'      {
1068                             ast *ex = newNode(INLINEASM,NULL,NULL);
1069                             ALLOC_ATOMIC(ex->values.inlineasm,strlen($1));
1070                             strcpy(ex->values.inlineasm,$1);                        
1071                             $$ = ex;
1072                          }   
1073    ;
1074
1075 labeled_statement
1076    : identifier ':' statement          {  $$ = createLabel($1,$3);  }   
1077    | CASE constant_expr ':' statement  {  $$ = createCase(STACK_PEEK(swStk),$2,$4); }
1078    | DEFAULT ':' statement             {  $$ = createDefault(STACK_PEEK(swStk),$3); }
1079    ;
1080
1081 start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ;  }
1082             ;
1083
1084 end_block   : '}'     { currBlockno = STACK_POP(blockNum); }           
1085             ;
1086
1087 compound_statement
1088    : start_block end_block                    { $$ = createBlock(NULL,NULL); }
1089    | start_block statement_list end_block     { $$ = createBlock(NULL,$2) ;  }
1090    | start_block 
1091           declaration_list                    { addSymChain($2); }
1092      end_block                                { $$ = createBlock($2,NULL) ;  }
1093    | start_block 
1094           declaration_list                    {  addSymChain ($2); }
1095           statement_list   
1096      end_block                                {$$ = createBlock($2,$4)   ;  }
1097    | error ';'                                { $$ = NULL ; }
1098    ;
1099
1100 declaration_list
1101    : declaration        
1102      {
1103        /* if this is typedef declare it immediately */
1104        if ( $1 && IS_TYPEDEF($1->etype)) {
1105          allocVariables ($1);
1106          $$ = NULL ;
1107        }
1108        else
1109          $$ = $1 ;
1110      }
1111
1112    | declaration_list declaration
1113      {
1114        symbol   *sym;
1115        
1116        /* if this is a typedef */
1117        if ($2 && IS_TYPEDEF($2->etype)) {
1118          allocVariables ($2);
1119          $$ = $1 ;
1120        }
1121        else {
1122                                 /* get to the end of the previous decl */
1123          if ( $1 ) {
1124            $$ = sym = $1 ;
1125            while (sym->next)
1126              sym = sym->next ;
1127            sym->next = $2;
1128          } 
1129          else
1130            $$ = $2 ;
1131        }
1132      }
1133    ;
1134
1135 statement_list
1136    : statement
1137    | statement_list statement          {  $$ = newNode(NULLOP,$1,$2) ;}
1138    ;
1139
1140 expression_statement
1141    : ';'                { $$ = NULL;}
1142    | expr ';' 
1143    ;
1144
1145 else_statement
1146    :  ELSE  statement   { $$ = $2  ; }
1147    |                    { $$ = NULL;}
1148    ;
1149
1150   
1151 selection_statement
1152    : IF '(' expr ')'  statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
1153    | SWITCH '(' expr ')'   { 
1154                               ast *ex ;                              
1155                               static   int swLabel = 0 ;
1156
1157                               /* create a node for expression  */
1158                               ex = newNode(SWITCH,$3,NULL);
1159                               STACK_PUSH(swStk,ex);   /* save it in the stack */
1160                               ex->values.switchVals.swNum = swLabel ;
1161                                  
1162                               /* now create the label */
1163                               sprintf(lbuff,"_swBrk_%d",swLabel++);
1164                               $<sym>$  =  newSymbol(lbuff,NestLevel);
1165                               /* put label in the break stack  */
1166                               STACK_PUSH(breakStack,$<sym>$);   
1167                            }
1168      statement             {  
1169                               /* get back the switch form the stack  */
1170                               $$ = STACK_POP(swStk)  ;
1171                               $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1172                               STACK_POP(breakStack);   
1173                            }
1174         ;
1175
1176 while : WHILE  {  /* create and push the continue , break & body labels */
1177                   static int Lblnum = 0 ;
1178                   /* continue */
1179                   sprintf (lbuff,"_whilecontinue_%d",Lblnum);
1180                   STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1181                   /* break */
1182                   sprintf (lbuff,"_whilebreak_%d",Lblnum);
1183                   STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1184                   /* body */
1185                   sprintf (lbuff,"_whilebody_%d",Lblnum++);
1186                   $$ = newSymbol(lbuff,NestLevel);
1187                }
1188
1189 do : DO {  /* create and push the continue , break & body Labels */
1190            static int Lblnum = 0 ;
1191
1192            /* continue */
1193            sprintf(lbuff,"_docontinue_%d",Lblnum);
1194            STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1195            /* break */
1196            sprintf (lbuff,"_dobreak_%d",Lblnum);
1197            STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1198            /* do body */
1199            sprintf (lbuff,"_dobody_%d",Lblnum++);
1200            $$ = newSymbol (lbuff,NestLevel);       
1201         }
1202 for : FOR { /* create & push continue, break & body labels */
1203             static int Lblnum = 0 ;
1204          
1205             /* continue */
1206             sprintf (lbuff,"_forcontinue_%d",Lblnum);
1207             STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1208             /* break    */
1209             sprintf (lbuff,"_forbreak_%d",Lblnum);
1210             STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1211             /* body */
1212             sprintf (lbuff,"_forbody_%d",Lblnum);
1213             $$ = newSymbol(lbuff,NestLevel);
1214             /* condition */
1215             sprintf (lbuff,"_forcond_%d",Lblnum++);
1216             STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1217           }
1218
1219 iteration_statement  
1220    : while '(' expr ')'  statement 
1221                          { 
1222                            noLineno++ ;
1223                            $$ = createWhile ( $1, STACK_POP(continueStack),
1224                                               STACK_POP(breakStack), $3, $5 ); 
1225                            $$->lineno = $1->lineDef ;
1226                            noLineno-- ;
1227                          }
1228    | do statement   WHILE '(' expr ')' ';' 
1229                         { 
1230                           noLineno++ ; 
1231                           $$ = createDo ( $1 , STACK_POP(continueStack), 
1232                                           STACK_POP(breakStack), $5, $2);
1233                           $$->lineno = $1->lineDef ;
1234                           noLineno-- ;
1235                         }                                                 
1236    | for '(' expr_opt   ';' expr_opt ';' expr_opt ')'  statement   
1237                         {
1238                           noLineno++ ;  
1239                           
1240                           /* if break or continue statement present
1241                              then create a general case loop */
1242                           if (STACK_PEEK(continueStack)->isref ||
1243                               STACK_PEEK(breakStack)->isref) {
1244                               $$ = createFor ($1, STACK_POP(continueStack),
1245                                               STACK_POP(breakStack) ,
1246                                               STACK_POP(forStack)   ,
1247                                               $3 , $5 , $7, $9 );
1248                           } else {
1249                               $$ = newNode(FOR,$9,NULL);
1250                               AST_FOR($$,trueLabel) = $1;
1251                               AST_FOR($$,continueLabel) =  STACK_POP(continueStack);
1252                               AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1253                               AST_FOR($$,condLabel)  = STACK_POP(forStack)  ;
1254                               AST_FOR($$,initExpr)   = $3;
1255                               AST_FOR($$,condExpr)   = $5;
1256                               AST_FOR($$,loopExpr)   = $7;
1257                           }
1258                           
1259                           noLineno-- ;
1260                         }
1261 ;
1262
1263 expr_opt
1264         :                       { $$ = NULL ; }
1265         |       expr
1266         ;
1267
1268 jump_statement          
1269    : GOTO identifier ';'   { 
1270                               $2->islbl = 1;
1271                               $$ = newAst(EX_VALUE,symbolVal($2)); 
1272                               $$ = newNode(GOTO,$$,NULL);
1273                            }
1274    | CONTINUE ';'          {  
1275        /* make sure continue is in context */
1276        if (STACK_PEEK(continueStack) == NULL) {
1277            werror(E_BREAK_CONTEXT);
1278            $$ = NULL;
1279        }
1280        else {
1281            $$ = newAst(EX_VALUE,symbolVal(STACK_PEEK(continueStack)));      
1282            $$ = newNode(GOTO,$$,NULL);
1283            /* mark the continue label as referenced */
1284            STACK_PEEK(continueStack)->isref = 1;
1285        }
1286    }
1287    | BREAK ';'             { 
1288        if (STACK_PEEK(breakStack) == NULL) {
1289            werror(E_BREAK_CONTEXT);
1290            $$ = NULL;
1291        } else {
1292            $$ = newAst(EX_VALUE,symbolVal(STACK_PEEK(breakStack)));
1293            $$ = newNode(GOTO,$$,NULL);
1294            STACK_PEEK(breakStack)->isref = 1;
1295        }
1296    }
1297    | RETURN ';'            { $$ = newNode(RETURN,NULL,NULL)    ; }
1298    | RETURN expr ';'       { $$ = newNode(RETURN,NULL,$2) ; } 
1299    ;
1300
1301 identifier
1302    : IDENTIFIER   { $$ = newSymbol ($1,NestLevel) ; }
1303    ;
1304 %%
1305
1306 extern unsigned char *yytext;
1307 extern int column;
1308 extern char *filename;
1309 extern int fatalError;
1310
1311 int yyerror(char *s)
1312 {
1313    fflush(stdout);
1314
1315    if ( yylineno )
1316         fprintf(stderr,"\n%s(%d) %s: token -> '%s' ; column %d\n",
1317                 filename,yylineno,
1318                 s,yytext,column);
1319    fatalError++;
1320    return 0;
1321 }
1322