Some code cleanup & fixed problem of used bdefore definitions
[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 EEPROM 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 _EEPROM
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    | EEPROM      {
580                   $$ = newLink () ;
581                   $$->class = SPECIFIER  ;
582                   SPEC_SCLS($$) = S_EEPROM ;
583                }
584    | DATA      {
585                   $$ = newLink ();
586                   $$->class = SPECIFIER ;
587                   SPEC_SCLS($$) = S_DATA   ;
588                }
589    | IDATA     {
590                   $$ = newLink ();
591                   $$->class = SPECIFIER ;
592                   SPEC_SCLS($$) = S_IDATA  ;
593                }
594    | PDATA     { 
595                   $$ = newLink ();
596                   $$->class = SPECIFIER ;
597                   SPEC_SCLS($$) = S_PDATA  ;
598                }
599    | BIT    {
600                $$=newLink();
601                $$->class = SPECIFIER   ;
602                SPEC_NOUN($$) = V_BIT   ;
603                SPEC_SCLS($$) = S_BIT   ;
604                SPEC_BLEN($$) = 1;
605                SPEC_BSTR($$) = 0;
606             }
607
608    | struct_or_union_specifier
609    | enum_specifier     {                           
610                            cenum = NULL ;
611                            $$ = $1 ;                              
612                         }
613    | TYPE_NAME    
614          {
615             symbol *sym;
616             link   *p  ;
617
618             sym = findSym(TypedefTab,NULL,$1) ;
619             $$ = p = copyLinkChain(sym->type);
620             SPEC_TYPEDEF(getSpec(p)) = 0;
621          }
622    | sfr_reg_bit
623    ;
624
625 sfr_reg_bit
626    :  SBIT  {
627                $$ = newLink() ;
628                $$->class = SPECIFIER ;
629                SPEC_NOUN($$) = V_SBIT;
630                SPEC_SCLS($$) = S_SBIT;
631             }
632    |  SFR   {
633                $$ = newLink() ;
634                $$->class = SPECIFIER ;
635                SPEC_NOUN($$) = V_CHAR;
636                SPEC_SCLS($$) = S_SFR ;
637                SPEC_USIGN($$) = 1 ;
638             }
639    ;
640
641 struct_or_union_specifier
642    : struct_or_union opt_stag '{' struct_declaration_list '}'
643         {
644            structdef *sdef ;
645
646            /* Create a structdef   */
647            sdef = $2 ;
648            sdef->fields   = reverseSyms($4) ;   /* link the fields */
649            sdef->size  = compStructSize($1,sdef);   /* update size of  */
650
651            /* Create the specifier */
652            $$ = newLink () ;
653            $$->class = SPECIFIER   ;
654            SPEC_NOUN($$) = V_STRUCT;
655            SPEC_STRUCT($$)= sdef ;
656         }
657    | struct_or_union stag
658          {
659             $$ = newLink() ;
660             $$->class = SPECIFIER   ;
661             SPEC_NOUN($$) = V_STRUCT;
662             SPEC_STRUCT($$) = $2 ;
663          }
664    ;
665
666 struct_or_union
667    : STRUCT          { $$ = STRUCT ; }
668    | UNION           { $$ = UNION  ; }
669    ;
670
671 opt_stag
672    : stag
673    |  {  /* synthesize a name add to structtable */
674          $$ = newStruct(genSymName(NestLevel)) ;
675          $$->level = NestLevel ;
676          addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ;
677       }
678    ;
679
680 stag
681    :  identifier  {  /* add name to structure table */
682                      $$ = findSymWithBlock (StructTab,$1,currBlockno);
683                      if (! $$ ) {
684                         $$ = newStruct($1->name) ;
685                         $$->level = NestLevel ;
686                         addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ;                  
687                      }
688                   }
689    ;
690
691 struct_declaration_list
692    : struct_declaration
693    | struct_declaration_list struct_declaration
694        {
695            symbol *sym = $2;
696            /* go to the end of the chain */
697            while (sym->next) sym = sym->next;
698
699            sym->next = $1 ;
700            $$ = $2;
701        }
702    ;
703
704 struct_declaration
705    : type_specifier_list struct_declarator_list ';'
706        {
707            /* add this type to all the symbols */
708            symbol *sym ;
709            for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
710                
711                pointerTypes(sym->type,copyLinkChain($1));
712                if (!sym->type) {
713                    sym->type = copyLinkChain($1);
714                    sym->etype = getSpec(sym->type);
715                }
716                else
717                    addDecl (sym,0,cloneSpec($1));              
718                
719            }
720            $$ = $2;
721        }
722    ;
723
724 struct_declarator_list
725    : struct_declarator
726    | struct_declarator_list ',' struct_declarator
727        {
728            $3->next  = $1 ;
729            $$ = $3 ;
730        }
731    ;
732
733 struct_declarator
734    : declarator
735    | ':' constant_expr  {  
736                            $$ = newSymbol (genSymName(NestLevel),NestLevel) ; 
737                            $$->bitVar = (int) floatFromVal(constExprValue($2,TRUE));
738                         }                        
739    | declarator ':' constant_expr 
740                         { 
741                           $1->bitVar = (int) floatFromVal(constExprValue($3,TRUE));                     
742                         }
743    ;
744
745 enum_specifier
746    : ENUM            '{' enumerator_list '}' {
747                                                 addSymChain ($3);
748                                                 allocVariables(reverseSyms($3)) ;
749                                                 $$ = copyLinkChain(cenum->type);
750                                              }
751    | ENUM identifier '{' enumerator_list '}' {
752                                                 symbol *csym ;
753
754                                                 $2->type = copyLinkChain(cenum->type);
755                                                 $2->etype = getSpec($2->type);
756                                                 /* add this to the enumerator table */
757                                                 if (!(csym=findSym(enumTab,$2,$2->name)) && 
758                                                     (csym && csym->level == $2->level))
759                                                    werror(E_DUPLICATE_TYPEDEF,csym->name);
760
761                                                 addSym ( enumTab,$2,$2->name,$2->level,$2->block);
762                                                 addSymChain ($4);
763                                                 allocVariables (reverseSyms($4));
764                                                 $$ = copyLinkChain(cenum->type);
765                                                 SPEC_SCLS(getSpec($$)) = 0 ;
766                                              }
767    | ENUM identifier                         {
768                                                 symbol *csym ;
769
770                                                 /* check the enumerator table */
771                                                 if ((csym = findSym(enumTab,$2,$2->name)))
772                                                    $$ = copyLinkChain(csym->type);
773                                                 else  {
774                                                    $$ = newLink() ;
775                                                    $$->class = SPECIFIER   ;
776                                                    SPEC_NOUN($$) = V_INT   ;
777                                                 }
778
779                                                 SPEC_SCLS(getSpec($$)) = 0 ;
780                                              }
781    ;
782
783 enumerator_list
784    : enumerator
785    | enumerator_list ',' enumerator {
786                                        $3->next = $1 ;
787                                        $$ = $3  ;
788                                     }
789    ;
790
791 enumerator
792    : identifier opt_assign_expr  {
793                                     /* make the symbol one level up */
794                                     $1->level-- ;
795                                     $1->type = copyLinkChain($2->type); 
796                                     $1->etype= getSpec($1->type);
797                                     SPEC_ENUM($1->etype) = 1;
798                                     $$ = $1 ;
799
800                                  }
801    ;
802
803 opt_assign_expr
804    :  '='   constant_expr  {
805                               value *val ;
806                                                         
807                               val = constExprValue($2,TRUE);                         
808                               $$ = cenum = val ;
809                            }                           
810    |                       {                              
811                               if (cenum)  {
812                                  sprintf(lbuff,"%d",(int) floatFromVal(cenum)+1);
813                                  $$ = cenum = constVal(lbuff);
814                               }
815                               else {
816                                  sprintf(lbuff,"%d",0);
817                                  $$ = cenum = constVal(lbuff);
818                               }   
819                            }
820    ;
821
822 declarator
823    : declarator2_using_reentrant        { $$ = $1; }
824    | pointer declarator2_using_reentrant
825          {
826              addDecl ($2,0,reverseLink($1));
827              $$ = $2 ;
828          }
829    ;
830
831 declarator2_using_reentrant
832    : declarator2                  { $$ = $1 ; } 
833    | declarator2 using_reentrant  { addDecl ($1,0,$2); }     
834    ;
835
836 declarator2
837    : identifier
838    | '(' declarator ')'     { $$ = $2; }
839    | declarator2 '[' ']'
840          {
841             link   *p;
842
843             p = newLink ();
844             DCL_TYPE(p) = ARRAY ;
845             DCL_ELEM(p) = 0     ;
846             addDecl($1,0,p);
847          }
848    | declarator2 '[' constant_expr ']'
849          {
850             link   *p ;
851                         value *tval;
852                         
853             p = (tval = constExprValue($3,TRUE))->etype;
854             /* if it is not a constant then Error  */
855             if ( SPEC_SCLS(p) != S_LITERAL)
856                werror(E_CONST_EXPECTED) ;
857             else {
858                p = newLink ();
859                DCL_TYPE(p) = ARRAY ;
860                DCL_ELEM(p) = (int) floatFromVal(tval) ;
861                addDecl($1,0,p);
862             }                           
863          }
864    | declarator2 '('  ')'       {  addDecl ($1,FUNCTION,NULL) ;   }
865    | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
866          {
867            
868              addDecl ($1,FUNCTION,NULL) ;
869            
870              $1->hasVargs = IS_VARG($4);
871              $1->args = reverseVal($4)  ;
872              
873              /* nest level was incremented to take care of the parms  */
874              NestLevel-- ;
875              currBlockno--;
876              $$ = $1;
877          }
878    | declarator2 '(' parameter_identifier_list ')'
879          {         
880            werror(E_OLD_STYLE,$1->name) ;         
881            
882            /* assume it returns an it */
883            $1->type = $1->etype = newIntLink();
884            $$ = $1 ;
885          }
886    ;
887
888 pointer
889    : far_near_pointer { $$ = $1 ;}
890    | far_near_pointer type_specifier_list   
891          {
892              $$ = $1  ;         
893              DCL_TSPEC($1) = $2;
894          }
895    | far_near_pointer pointer         
896          {
897              $$ = $1 ;          
898              $$->next = $2 ;
899          }
900    | far_near_pointer type_specifier_list pointer
901          {
902              $$ = $1 ;               
903              if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
904                  DCL_PTR_CONST($1) = SPEC_CONST($2);
905                  DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
906                  switch (SPEC_SCLS($2)) {
907                  case S_XDATA:
908                      DCL_TYPE($3) = FPOINTER;
909                      break;
910                  case S_IDATA:
911                      DCL_TYPE($3) = IPOINTER ;
912                      break;
913                  case S_PDATA:
914                      DCL_TYPE($3) = PPOINTER ;
915                      break;
916                  case S_DATA:
917                      DCL_TYPE($3) = POINTER ;
918                      break;
919                  case S_CODE:
920                      DCL_PTR_CONST($3) = 1;
921                      DCL_TYPE($3) = CPOINTER ;
922                  case S_EEPROM:
923                      DCL_TYPE($3) = EEPPOINTER;
924                      break;
925                  default:
926                      werror(W_PTR_TYPE_INVALID);
927                  }
928              }
929              else 
930                  werror (W_PTR_TYPE_INVALID);
931              $$->next = $3 ;
932          }
933    ;
934
935 far_near_pointer
936    :  far_near '*'   {
937                         if ($1 == NULL) {
938                            $$ = newLink();
939                            DCL_TYPE($$) = POINTER ;
940                         }
941                         else
942                            $$ = $1 ;
943       }
944    ;
945
946 far_near
947    : _XDATA    { $$ = newLink() ; DCL_TYPE($$) = FPOINTER ; }
948    | _CODE     { $$ = newLink() ; DCL_TYPE($$) = CPOINTER ;  DCL_PTR_CONST($$) = 1;}
949    | _PDATA    { $$ = newLink() ; DCL_TYPE($$) = PPOINTER ; } 
950    | _IDATA    { $$ = newLink() ; DCL_TYPE($$) = IPOINTER ; }
951    | _NEAR     { $$ = NULL ; }
952    | _GENERIC  { $$ = newLink() ; DCL_TYPE($$) = GPOINTER ; } 
953    | _EEPROM   { $$ = newLink() ; DCL_TYPE($$) = EEPPOINTER ;} 
954    |           { $$ = newLink() ; DCL_TYPE($$) = UPOINTER ; }
955    ;
956
957 type_specifier_list
958    : type_specifier
959    | type_specifier_list type_specifier         {  $$ = mergeSpec ($1,$2); }
960    ;
961
962 parameter_identifier_list
963    : identifier_list
964    | identifier_list ',' ELIPSIS
965    ;
966
967 identifier_list
968    : identifier
969    | identifier_list ',' identifier         
970          {            
971            $3->next = $1;
972            $$ = $3 ;
973          }
974    ;
975
976 parameter_type_list
977         : parameter_list
978         | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
979         ;
980
981 parameter_list
982    : parameter_declaration 
983    | parameter_list ',' parameter_declaration
984          {
985             $3->next = $1 ;
986             $$ = $3 ;       
987          }
988    ;
989
990 parameter_declaration
991    : type_specifier_list declarator 
992                {        
993                   symbol *loop ;
994                   pointerTypes($2->type,$1);
995                   addDecl ($2,0,$1);              
996                   for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
997                   addSymChain ($2);
998                   $$ = symbolVal($2);
999                }
1000    | type_name { 
1001                   $$ = newValue() ; 
1002                   $$->type = $1;
1003                   $$->etype = getSpec($$->type);
1004                }
1005    ;
1006
1007 type_name
1008    : type_specifier_list  { $$ = $1 ;}
1009    | type_specifier_list abstract_declarator 
1010                {
1011                  /* go to the end of the list */
1012                  link *p;
1013                  pointerTypes($2,$1);
1014                  for ( p = $2 ; p->next ; p=p->next);
1015                   p->next = $1 ;
1016                   $$ = $2 ;
1017                }   
1018    ;
1019
1020 abstract_declarator
1021    : pointer { $$ = reverseLink($1); }
1022    | abstract_declarator2
1023    | pointer abstract_declarator2   { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;} 
1024    ;
1025
1026 abstract_declarator2
1027    : '(' abstract_declarator ')'    { $$ = $2 ; }
1028    | '[' ']'                        {             
1029                                        $$ = newLink ();
1030                                        DCL_TYPE($$) = ARRAY ;
1031                                        DCL_ELEM($$) = 0     ;
1032                                     }
1033    | '[' constant_expr ']'          { 
1034                                        value *val ;
1035                                        $$ = newLink ();
1036                                        DCL_TYPE($$) = ARRAY ;
1037                                        DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1038                                     }
1039    | abstract_declarator2 '[' ']'   {
1040                                        $$ = newLink ();
1041                                        DCL_TYPE($$) = ARRAY ;
1042                                        DCL_ELEM($$) = 0     ;
1043                                        $$->next = $1 ;
1044                                     }
1045    | abstract_declarator2 '[' constant_expr ']'
1046                                     {
1047                                        value *val ;
1048                                        $$ = newLink ();
1049                                        DCL_TYPE($$) = ARRAY ;
1050                                        DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1051                                        $$->next = $1 ;
1052                                     }
1053    | '(' ')'                        { $$ = NULL;}
1054    | '(' parameter_type_list ')'    { $$ = NULL;}   
1055    | abstract_declarator2 '(' ')'
1056    | abstract_declarator2 '(' parameter_type_list ')'
1057    ;
1058
1059 initializer
1060    : assignment_expr                { $$ = newiList(INIT_NODE,$1); }
1061    | '{'  initializer_list '}'      { $$ = newiList(INIT_DEEP,revinit($2)); }
1062    | '{'  initializer_list ',' '}'  { $$ = newiList(INIT_DEEP,revinit($2)); }
1063    ;
1064
1065 initializer_list
1066    : initializer
1067    | initializer_list ',' initializer  {  $3->next = $1; $$ = $3; }
1068    ;
1069
1070 statement
1071    : labeled_statement
1072    | compound_statement
1073    | expression_statement
1074    | selection_statement
1075    | iteration_statement
1076    | jump_statement
1077    | INLINEASM  ';'      {
1078                             ast *ex = newNode(INLINEASM,NULL,NULL);
1079                             ALLOC_ATOMIC(ex->values.inlineasm,strlen($1));
1080                             strcpy(ex->values.inlineasm,$1);                        
1081                             $$ = ex;
1082                          }   
1083    ;
1084
1085 labeled_statement
1086    : identifier ':' statement          {  $$ = createLabel($1,$3);  }   
1087    | CASE constant_expr ':' statement  {  $$ = createCase(STACK_PEEK(swStk),$2,$4); }
1088    | DEFAULT ':' statement             {  $$ = createDefault(STACK_PEEK(swStk),$3); }
1089    ;
1090
1091 start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ;  }
1092             ;
1093
1094 end_block   : '}'     { currBlockno = STACK_POP(blockNum); }           
1095             ;
1096
1097 compound_statement
1098    : start_block end_block                    { $$ = createBlock(NULL,NULL); }
1099    | start_block statement_list end_block     { $$ = createBlock(NULL,$2) ;  }
1100    | start_block 
1101           declaration_list                    { addSymChain($2); }
1102      end_block                                { $$ = createBlock($2,NULL) ;  }
1103    | start_block 
1104           declaration_list                    {  addSymChain ($2); }
1105           statement_list   
1106      end_block                                {$$ = createBlock($2,$4)   ;  }
1107    | error ';'                                { $$ = NULL ; }
1108    ;
1109
1110 declaration_list
1111    : declaration        
1112      {
1113        /* if this is typedef declare it immediately */
1114        if ( $1 && IS_TYPEDEF($1->etype)) {
1115          allocVariables ($1);
1116          $$ = NULL ;
1117        }
1118        else
1119          $$ = $1 ;
1120      }
1121
1122    | declaration_list declaration
1123      {
1124        symbol   *sym;
1125        
1126        /* if this is a typedef */
1127        if ($2 && IS_TYPEDEF($2->etype)) {
1128          allocVariables ($2);
1129          $$ = $1 ;
1130        }
1131        else {
1132                                 /* get to the end of the previous decl */
1133          if ( $1 ) {
1134            $$ = sym = $1 ;
1135            while (sym->next)
1136              sym = sym->next ;
1137            sym->next = $2;
1138          } 
1139          else
1140            $$ = $2 ;
1141        }
1142      }
1143    ;
1144
1145 statement_list
1146    : statement
1147    | statement_list statement          {  $$ = newNode(NULLOP,$1,$2) ;}
1148    ;
1149
1150 expression_statement
1151    : ';'                { $$ = NULL;}
1152    | expr ';' 
1153    ;
1154
1155 else_statement
1156    :  ELSE  statement   { $$ = $2  ; }
1157    |                    { $$ = NULL;}
1158    ;
1159
1160   
1161 selection_statement
1162    : IF '(' expr ')'  statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
1163    | SWITCH '(' expr ')'   { 
1164                               ast *ex ;                              
1165                               static   int swLabel = 0 ;
1166
1167                               /* create a node for expression  */
1168                               ex = newNode(SWITCH,$3,NULL);
1169                               STACK_PUSH(swStk,ex);   /* save it in the stack */
1170                               ex->values.switchVals.swNum = swLabel ;
1171                                  
1172                               /* now create the label */
1173                               sprintf(lbuff,"_swBrk_%d",swLabel++);
1174                               $<sym>$  =  newSymbol(lbuff,NestLevel);
1175                               /* put label in the break stack  */
1176                               STACK_PUSH(breakStack,$<sym>$);   
1177                            }
1178      statement             {  
1179                               /* get back the switch form the stack  */
1180                               $$ = STACK_POP(swStk)  ;
1181                               $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1182                               STACK_POP(breakStack);   
1183                            }
1184         ;
1185
1186 while : WHILE  {  /* create and push the continue , break & body labels */
1187                   static int Lblnum = 0 ;
1188                   /* continue */
1189                   sprintf (lbuff,"_whilecontinue_%d",Lblnum);
1190                   STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1191                   /* break */
1192                   sprintf (lbuff,"_whilebreak_%d",Lblnum);
1193                   STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1194                   /* body */
1195                   sprintf (lbuff,"_whilebody_%d",Lblnum++);
1196                   $$ = newSymbol(lbuff,NestLevel);
1197                }
1198
1199 do : DO {  /* create and push the continue , break & body Labels */
1200            static int Lblnum = 0 ;
1201
1202            /* continue */
1203            sprintf(lbuff,"_docontinue_%d",Lblnum);
1204            STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1205            /* break */
1206            sprintf (lbuff,"_dobreak_%d",Lblnum);
1207            STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1208            /* do body */
1209            sprintf (lbuff,"_dobody_%d",Lblnum++);
1210            $$ = newSymbol (lbuff,NestLevel);       
1211         }
1212 for : FOR { /* create & push continue, break & body labels */
1213             static int Lblnum = 0 ;
1214          
1215             /* continue */
1216             sprintf (lbuff,"_forcontinue_%d",Lblnum);
1217             STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1218             /* break    */
1219             sprintf (lbuff,"_forbreak_%d",Lblnum);
1220             STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1221             /* body */
1222             sprintf (lbuff,"_forbody_%d",Lblnum);
1223             $$ = newSymbol(lbuff,NestLevel);
1224             /* condition */
1225             sprintf (lbuff,"_forcond_%d",Lblnum++);
1226             STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1227           }
1228
1229 iteration_statement  
1230    : while '(' expr ')'  statement 
1231                          { 
1232                            noLineno++ ;
1233                            $$ = createWhile ( $1, STACK_POP(continueStack),
1234                                               STACK_POP(breakStack), $3, $5 ); 
1235                            $$->lineno = $1->lineDef ;
1236                            noLineno-- ;
1237                          }
1238    | do statement   WHILE '(' expr ')' ';' 
1239                         { 
1240                           noLineno++ ; 
1241                           $$ = createDo ( $1 , STACK_POP(continueStack), 
1242                                           STACK_POP(breakStack), $5, $2);
1243                           $$->lineno = $1->lineDef ;
1244                           noLineno-- ;
1245                         }                                                 
1246    | for '(' expr_opt   ';' expr_opt ';' expr_opt ')'  statement   
1247                         {
1248                           noLineno++ ;  
1249                           
1250                           /* if break or continue statement present
1251                              then create a general case loop */
1252                           if (STACK_PEEK(continueStack)->isref ||
1253                               STACK_PEEK(breakStack)->isref) {
1254                               $$ = createFor ($1, STACK_POP(continueStack),
1255                                               STACK_POP(breakStack) ,
1256                                               STACK_POP(forStack)   ,
1257                                               $3 , $5 , $7, $9 );
1258                           } else {
1259                               $$ = newNode(FOR,$9,NULL);
1260                               AST_FOR($$,trueLabel) = $1;
1261                               AST_FOR($$,continueLabel) =  STACK_POP(continueStack);
1262                               AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1263                               AST_FOR($$,condLabel)  = STACK_POP(forStack)  ;
1264                               AST_FOR($$,initExpr)   = $3;
1265                               AST_FOR($$,condExpr)   = $5;
1266                               AST_FOR($$,loopExpr)   = $7;
1267                           }
1268                           
1269                           noLineno-- ;
1270                         }
1271 ;
1272
1273 expr_opt
1274         :                       { $$ = NULL ; }
1275         |       expr
1276         ;
1277
1278 jump_statement          
1279    : GOTO identifier ';'   { 
1280                               $2->islbl = 1;
1281                               $$ = newAst(EX_VALUE,symbolVal($2)); 
1282                               $$ = newNode(GOTO,$$,NULL);
1283                            }
1284    | CONTINUE ';'          {  
1285        /* make sure continue is in context */
1286        if (STACK_PEEK(continueStack) == NULL) {
1287            werror(E_BREAK_CONTEXT);
1288            $$ = NULL;
1289        }
1290        else {
1291            $$ = newAst(EX_VALUE,symbolVal(STACK_PEEK(continueStack)));      
1292            $$ = newNode(GOTO,$$,NULL);
1293            /* mark the continue label as referenced */
1294            STACK_PEEK(continueStack)->isref = 1;
1295        }
1296    }
1297    | BREAK ';'             { 
1298        if (STACK_PEEK(breakStack) == NULL) {
1299            werror(E_BREAK_CONTEXT);
1300            $$ = NULL;
1301        } else {
1302            $$ = newAst(EX_VALUE,symbolVal(STACK_PEEK(breakStack)));
1303            $$ = newNode(GOTO,$$,NULL);
1304            STACK_PEEK(breakStack)->isref = 1;
1305        }
1306    }
1307    | RETURN ';'            { $$ = newNode(RETURN,NULL,NULL)    ; }
1308    | RETURN expr ';'       { $$ = newNode(RETURN,NULL,$2) ; } 
1309    ;
1310
1311 identifier
1312    : IDENTIFIER   { $$ = newSymbol ($1,NestLevel) ; }
1313    ;
1314 %%
1315
1316 extern unsigned char *yytext;
1317 extern int column;
1318 extern char *filename;
1319 extern int fatalError;
1320
1321 int yyerror(char *s)
1322 {
1323    fflush(stdout);
1324
1325    if ( yylineno )
1326         fprintf(stderr,"\n%s(%d) %s: token -> '%s' ; column %d\n",
1327                 filename,yylineno,
1328                 s,yytext,column);
1329    fatalError++;
1330    return 0;
1331 }
1332