Next step in 16 bits short
[fw/sdcc] / src / SDCC.y
index 5775b3259a6ac96d5a6a1e7c8a66d479b65b1d49..7fe71788c8bb5d71c8d135bb40027c4fdace5b91 100644 (file)
@@ -31,6 +31,9 @@
 #include "SDCCval.h"
 #include "SDCCmem.h"
 #include "SDCCast.h"
+#include "port.h"
+#include "newalloc.h"
+#include "SDCCerr.h"
 
 extern int yyerror (char *);
 extern FILE    *yyin;
@@ -59,11 +62,11 @@ value *cenum = NULL  ;  /* current enumeration  type chain*/
     symbol     *sym ;      /* symbol table pointer       */
     structdef  *sdef;      /* structure definition       */
     char       yychar[SDCC_NAME_MAX+1];
-    link       *lnk ;      /* declarator  or specifier   */
+    sym_link       *lnk ;      /* declarator  or specifier   */
     int        yyint;      /* integer value returned     */
     value      *val ;      /* for integer constant       */
     initList   *ilist;     /* initial list               */
-    char       yyinline[MAX_INLINEASM]; /* inlined assembler code */
+    char       *yyinline; /* inlined assembler code */
     ast       *asts;     /* expression tree            */
 }
 
@@ -79,7 +82,8 @@ value *cenum = NULL  ;  /* current enumeration  type chain*/
 %token REENTRANT USING  XDATA DATA IDATA PDATA VAR_ARGS CRITICAL NONBANKED BANKED
 %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT
 %token STRUCT UNION ENUM ELIPSIS RANGE FAR _XDATA _CODE _GENERIC _NEAR _PDATA _IDATA _EEPROM
-%token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN 
+%token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
+%token NAKED
 %token <yyinline> INLINEASM
 %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT
 %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL  ENDFUNCTION JUMPTABLE
@@ -124,6 +128,23 @@ file
 external_definition
    : function_definition     { blockNo=0;}
    | declaration             { 
+                              if ($1 && $1->type
+                               && IS_FUNC($1->type))
+                              {
+                                  /* The only legal storage classes for 
+                                   * a function prototype (declaration)
+                                   * are extern and static. extern is the
+                                   * default. Thus, if this function isn't
+                                   * explicitly marked static, mark it
+                                   * extern.
+                                   */
+                                  if ($1->etype 
+                                   && IS_SPEC($1->etype)
+                                   && !SPEC_STAT($1->etype))
+                                  {
+                                       SPEC_EXTR($1->etype) = 1;
+                                  }
+                              }
                                addSymChain ($1);
                                allocVariables ($1) ;
                               cleanUpLevel (SymbolTab,1);
@@ -164,6 +185,10 @@ using_reentrant_interrupt
                         $$->class = SPECIFIER   ;
                         SPEC_CRTCL($$) = 1;
                      }
+   |  NAKED          {  $$ = newLink ();
+                        $$->class = SPECIFIER   ;
+                        SPEC_NAKED($$) = 1;
+                     }
    |  NONBANKED      {$$ = newLink ();
                         $$->class = SPECIFIER   ;
                         SPEC_NONBANKED($$) = 1;
@@ -200,14 +225,14 @@ function_body
    ;
 
 primary_expr
-   : identifier      {  $$ = newAst(EX_VALUE,symbolVal($1));  }
-   | CONSTANT        {  $$ = newAst(EX_VALUE,$1);  }
+   : identifier      {  $$ = newAst_VALUE(symbolVal($1));  }
+   | CONSTANT        {  $$ = newAst_VALUE($1);  }
    | string_literal  
    | '(' expr ')'    {  $$ = $2 ;                   }
    ;
          
 string_literal
-    : STRING_LITERAL                   { $$ = newAst(EX_VALUE,$1); }
+    : STRING_LITERAL                   { $$ = newAst_VALUE($1); }
     ;
 
 postfix_expr
@@ -223,14 +248,14 @@ postfix_expr
                      {    
                        $3 = newSymbol($3->name,NestLevel);
                        $3->implicit = 1;
-                       $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst(EX_VALUE,symbolVal($3)));
+                       $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($3)));
 /*                     $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ;                   */
                      }
    | postfix_expr PTR_OP identifier    
                       { 
                        $3 = newSymbol($3->name,NestLevel);
                        $3->implicit = 1;                       
-                       $$ = newNode(PTR_OP,$1,newAst(EX_VALUE,symbolVal($3)));
+                       $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($3)));
                      }
    | postfix_expr INC_OP   
                       {        $$ = newNode(INC_OP,$1,NULL);}
@@ -249,7 +274,7 @@ unary_expr
    | DEC_OP unary_expr        { $$ = newNode(DEC_OP,NULL,$2);  }
    | unary_operator cast_expr { $$ = newNode($1,$2,NULL)    ;  }
    | SIZEOF unary_expr        { $$ = newNode(SIZEOF,NULL,$2);  }
-   | SIZEOF '(' type_name ')' { $$ = newAst(EX_VALUE,sizeofOp($3)); }
+   | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); }
    ;
               
 unary_operator
@@ -263,7 +288,7 @@ unary_operator
 
 cast_expr
    : unary_expr
-   | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst(EX_LINK,$2),$4); }
+   | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); }
    ;
 
 multiplicative_expr
@@ -287,41 +312,40 @@ shift_expr
 
 relational_expr
    : shift_expr
-   | relational_expr '<' shift_expr    { $$ = newNode('<',$1,$3); }
-   | relational_expr '>' shift_expr    { $$ = newNode('>',$1,$3); }
+   | relational_expr '<' shift_expr    { 
+       $$ = (port->lt_nge ? 
+             newNode('!',newNode(GE_OP,$1,$3),NULL) :
+             newNode('<', $1,$3));
+   }
+   | relational_expr '>' shift_expr    { 
+          $$ = (port->gt_nle ? 
+                newNode('!',newNode(LE_OP,$1,$3),NULL) :
+                newNode('>',$1,$3));
+   }
    | relational_expr LE_OP shift_expr  { 
-       /* $$ = newNode(LE_OP,$1,$3); */
-       /* getting 8051 specific here : will change
-         LE_OP operation to "not greater than" i.e.
-         ( a <= b ) === ( ! ( a > b )) */
-       $$ = newNode('!', 
-                   newNode('>', $1 , $3 ),
-                   NULL);
+          $$ = (port->le_ngt ? 
+                newNode('!', newNode('>', $1 , $3 ), NULL) :
+                newNode(LE_OP,$1,$3));
    }
    | relational_expr GE_OP shift_expr  { 
-       /* $$ = newNode(GE_OP,$1,$3) ; */
-       /* getting 8051 specific here : will change
-         GE_OP operation to "not less than" i.e.
-         ( a >= b ) === ( ! ( a < b )) */
-       $$ = newNode('!',
-                   newNode('<', $1 , $3 ),
-                   NULL);
+          $$ = (port->ge_nlt ? 
+                newNode('!', newNode('<', $1 , $3 ), NULL) :
+                newNode(GE_OP,$1,$3));
    }
    ;
 
 equality_expr
    : relational_expr
-   | equality_expr EQ_OP relational_expr  { $$ = newNode(EQ_OP,$1,$3);}
-   | equality_expr NE_OP relational_expr  
-          { 
-              /* $$ = newNode(NE_OP,$1,$3); */
-             /* NE_OP changed :            
-                expr1 != expr2 is equivalent to
-                (! expr1 == expr2) */
-             $$ = newNode('!',
-                          newNode(EQ_OP,$1,$3),
-                          NULL);
-         }       
+   | equality_expr EQ_OP relational_expr  { 
+    $$ = (port->eq_nne ? 
+         newNode('!',newNode(NE_OP,$1,$3),NULL) : 
+         newNode(EQ_OP,$1,$3));
+   }
+   | equality_expr NE_OP relational_expr { 
+       $$ = (port->ne_neq ? 
+            newNode('!', newNode(EQ_OP,$1,$3), NULL) : 
+            newNode(NE_OP,$1,$3));
+   }       
    ;
 
 and_expr
@@ -437,7 +461,7 @@ declaration
          symbol *sym , *sym1;
 
          for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
-            link *lnk = copyLinkChain($1);
+            sym_link *lnk = copyLinkChain($1);
             /* do the pointer stuff */
             pointerTypes(sym->type,lnk);
             addDecl (sym,0,lnk) ;
@@ -453,7 +477,7 @@ declaration_specifiers
      /* if the decl $2 is not a specifier */
      /* find the spec and replace it      */
      if ( !IS_SPEC($2)) {
-       link *lnk = $2 ;
+       sym_link *lnk = $2 ;
        while (lnk && !IS_SPEC(lnk->next))
         lnk = lnk->next;
        lnk->next = mergeSpec($1,lnk->next);
@@ -467,7 +491,7 @@ declaration_specifiers
      /* if the decl $2 is not a specifier */
      /* find the spec and replace it      */
      if ( !IS_SPEC($2)) {
-       link *lnk = $2 ;
+       sym_link *lnk = $2 ;
        while (lnk && !IS_SPEC(lnk->next))
         lnk = lnk->next;
        lnk->next = mergeSpec($1,lnk->next);
@@ -541,8 +565,7 @@ type_specifier2
    | SHORT  {
                $$=newLink();
                $$->class = SPECIFIER   ;
-               SPEC_LONG($$) = 0      ;
-              SPEC_SHORT($$) = 1        ;
+              $$->select.s._short = 1      ;
             }
    | INT    {
                $$=newLink();
@@ -552,18 +575,17 @@ type_specifier2
    | LONG   {
                $$=newLink();
                $$->class = SPECIFIER   ;
-               SPEC_LONG($$) = 1       ;
-              SPEC_SHORT($$) = 0;
+              SPEC_LONG($$) = 1       ;
             }
    | SIGNED {
                $$=newLink();
                $$->class = SPECIFIER   ;
-               SPEC_USIGN($$) = 0       ;
+               $$->select.s._signed = 1     ;
             }
    | UNSIGNED  {
                $$=newLink();
                $$->class = SPECIFIER   ;
-               SPEC_USIGN($$) = 1       ;
+               SPEC_USIGN($$) = 1      ;
             }
    | VOID   {
                $$=newLink();
@@ -573,7 +595,7 @@ type_specifier2
    | CONST  {
                $$=newLink();
               $$->class = SPECIFIER ;
-              SPEC_SCLS($$) = S_CONSTANT ;
+              //SPEC_SCLS($$) = S_CONSTANT ;
               SPEC_CONST($$) = 1;
             }
    | VOLATILE  {
@@ -633,8 +655,7 @@ type_specifier2
    | TYPE_NAME    
          {
             symbol *sym;
-            link   *p  ;
-
+            sym_link   *p  ;
             sym = findSym(TypedefTab,NULL,$1) ;
             $$ = p = copyLinkChain(sym->type);
            SPEC_TYPEDEF(getSpec(p)) = 0;
@@ -732,10 +753,11 @@ struct_declaration
               if (!sym->type) {
                   sym->type = copyLinkChain($1);
                   sym->etype = getSpec(sym->type);
+                  /* make sure the type is complete and sane */
+                  checkTypeSanity(sym->etype, sym->name);
               }
               else
                   addDecl (sym,0,cloneSpec($1));              
-              
           }
            $$ = $2;
        }
@@ -858,7 +880,7 @@ declarator2
    | '(' declarator ')'     { $$ = $2; }
    | declarator2 '[' ']'
          {
-            link   *p;
+            sym_link   *p;
 
             p = newLink ();
             DCL_TYPE(p) = ARRAY ;
@@ -867,7 +889,7 @@ declarator2
          }
    | declarator2 '[' constant_expr ']'
          {
-            link   *p ;
+            sym_link   *p ;
                        value *tval;
                        
             p = (tval = constExprValue($3,TRUE))->etype;
@@ -899,7 +921,7 @@ declarator2
          {        
           werror(E_OLD_STYLE,$1->name) ;         
           
-          /* assume it returns an it */
+          /* assume it returns an int */
           $1->type = $1->etype = newIntLink();
           $$ = $1 ;
          }
@@ -1029,7 +1051,7 @@ type_name
    | type_specifier_list abstract_declarator 
                {
                 /* go to the end of the list */
-                link *p;
+                sym_link *p;
                 pointerTypes($2,$1);
                 for ( p = $2 ; p->next ; p=p->next);
                   p->next = $1 ;
@@ -1096,7 +1118,7 @@ statement
    | jump_statement
    | INLINEASM  ';'      {
                             ast *ex = newNode(INLINEASM,NULL,NULL);
-                           ALLOC_ATOMIC(ex->values.inlineasm,strlen($1));
+                           ex->values.inlineasm = Safe_calloc(1,strlen($1)+1);
                            strcpy(ex->values.inlineasm,$1);                        
                            $$ = ex;
                          }   
@@ -1298,7 +1320,7 @@ expr_opt
 jump_statement          
    : GOTO identifier ';'   { 
                               $2->islbl = 1;
-                              $$ = newAst(EX_VALUE,symbolVal($2)); 
+                              $$ = newAst_VALUE(symbolVal($2)); 
                               $$ = newNode(GOTO,$$,NULL);
                            }
    | CONTINUE ';'          {  
@@ -1308,7 +1330,7 @@ jump_statement
           $$ = NULL;
        }
        else {
-          $$ = newAst(EX_VALUE,symbolVal(STACK_PEEK(continueStack)));      
+          $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));      
           $$ = newNode(GOTO,$$,NULL);
           /* mark the continue label as referenced */
           STACK_PEEK(continueStack)->isref = 1;
@@ -1319,7 +1341,7 @@ jump_statement
           werror(E_BREAK_CONTEXT);
           $$ = NULL;
        } else {
-          $$ = newAst(EX_VALUE,symbolVal(STACK_PEEK(breakStack)));
+          $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
           $$ = newNode(GOTO,$$,NULL);
           STACK_PEEK(breakStack)->isref = 1;
        }