Force function prototypes to default to extern storage class
[fw/sdcc] / src / SDCC.y
index 66140dcc5b63846ecd3ba2c6a98fcee926171b84..c4af209471e35e5ea2af3ba4a5639a3f7213197a 100644 (file)
 #include "SDCCval.h"
 #include "SDCCmem.h"
 #include "SDCCast.h"
+#include "port.h"
+
 extern int yyerror (char *);
 extern FILE    *yyin;
-extern char srcLstFname[];
 int NestLevel = 0 ;     /* current NestLevel       */
 int stackPtr  = 1 ;     /* stack pointer           */
 int xstackPtr = 0 ;     /* xstack pointer          */
@@ -76,7 +77,7 @@ value *cenum = NULL  ;  /* current enumeration  type chain*/
 %token <yyint> SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
 %token <yyint> XOR_ASSIGN OR_ASSIGN
 %token TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR AT SBIT
-%token REENTRANT USING  XDATA DATA IDATA PDATA VAR_ARGS CRITICAL
+%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 
@@ -124,6 +125,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 +182,23 @@ using_reentrant_interrupt
                         $$->class = SPECIFIER   ;
                         SPEC_CRTCL($$) = 1;
                      }
+   |  NONBANKED      {$$ = newLink ();
+                        $$->class = SPECIFIER   ;
+                        SPEC_NONBANKED($$) = 1;
+                       if (SPEC_BANKED($$)) {
+                           werror(W_BANKED_WITH_NONBANKED);
+                       }
+                     }
+   |  BANKED         {$$ = newLink ();
+                        $$->class = SPECIFIER   ;
+                        SPEC_BANKED($$) = 1;
+                       if (SPEC_NONBANKED($$)) {
+                           werror(W_BANKED_WITH_NONBANKED);
+                       }
+                       if (SPEC_STAT($$)) {
+                           werror(W_BANKED_WITH_STATIC);
+                       }
+                     }
    |  Interrupt_storage
                      {
                         $$ = newLink () ;
@@ -270,41 +305,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
@@ -358,6 +392,9 @@ assignment_expr
                             case DIV_ASSIGN:
                                     $$ = newNode('=',$1,newNode('/',copyAst($1),$3));
                                     break;
+                            case MOD_ASSIGN:
+                                    $$ = newNode('=',$1,newNode('%',copyAst($1),$3));
+                                    break;
                             case ADD_ASSIGN:
                                     $$ = newNode('=',$1,newNode('+',copyAst($1),$3));
                                     break;
@@ -503,12 +540,12 @@ Interrupt_storage
 
 type_specifier
    : type_specifier2
-   | type_specifier2 AT CONSTANT
+   | type_specifier2 AT constant_expr
         {
            /* add this to the storage class specifier  */
            SPEC_ABSA($1) = 1;   /* set the absolute addr flag */
            /* now get the abs addr from value */
-           SPEC_ADDR($1) = (int) floatFromVal ($3) ;
+           SPEC_ADDR($1) = (int) floatFromVal(constExprValue($3,TRUE)) ;
         }
    ;
 
@@ -1313,20 +1350,3 @@ identifier
    ;
 %%
 
-extern unsigned char *yytext;
-extern int column;
-extern char *filename;
-extern int fatalError;
-
-int yyerror(char *s)
-{
-   fflush(stdout);
-
-   if ( yylineno )
-       fprintf(stderr,"\n%s(%d) %s: token -> '%s' ; column %d\n",
-               filename,yylineno,
-               s,yytext,column);
-   fatalError++;
-   return 0;
-}
-