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