* support/Util/NewAlloc.c (freeTrace): Changed free for the gc case to not free...
[fw/sdcc] / src / SDCC.y
index ed7e2a2a171178d0f91906a665c2461c85b9e057..954010939580ec2aaf9efb5c8d1a4e636cd3cfa4 100644 (file)
 #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;
-extern char srcLstFname[];
 int NestLevel = 0 ;     /* current NestLevel       */
 int stackPtr  = 1 ;     /* stack pointer           */
 int xstackPtr = 0 ;     /* xstack pointer          */
@@ -55,15 +58,17 @@ STACK_DCL(blockNum,int,MAX_NEST_LEVEL*3)
 value *cenum = NULL  ;  /* current enumeration  type chain*/
 
 %}
+%expect 6
+
 %union {
     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            */
 }
 
@@ -76,15 +81,16 @@ 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 
+%token STRUCT UNION ENUM ELIPSIS RANGE FAR
+%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
 %token RRC RLC 
-%token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND
+%token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND ARRAYINIT
 
 %type <yyint>  Interrupt_storage
 %type <sym> identifier  declarator  declarator2 enumerator_list enumerator
@@ -97,7 +103,7 @@ value *cenum = NULL  ;  /* current enumeration  type chain*/
 %type <lnk> storage_class_specifier struct_or_union_specifier
 %type <lnk> declaration_specifiers  sfr_reg_bit type_specifier2
 %type <lnk> using_reentrant using_reentrant_interrupt enum_specifier
-%type <lnk> abstract_declarator abstract_declarator2 far_near_pointer far_near
+%type <lnk> abstract_declarator abstract_declarator2 unqualified_pointer
 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
 %type <sdef> stag opt_stag
 %type <asts> primary_expr
@@ -124,6 +130,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);
@@ -146,7 +169,7 @@ function_definition
 
 using_reentrant
    : using_reentrant_interrupt
-   | using_reentrant_interrupt using_reentrant { $$ = mergeSpec($1,$2); }
+   | using_reentrant_interrupt using_reentrant { $$ = mergeSpec($1,$2,"using_reentrant"); }
    ;
 
 using_reentrant_interrupt
@@ -164,6 +187,27 @@ using_reentrant_interrupt
                         $$->class = SPECIFIER   ;
                         SPEC_CRTCL($$) = 1;
                      }
+   |  NAKED          {  $$ = newLink ();
+                        $$->class = SPECIFIER   ;
+                        SPEC_NAKED($$) = 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 () ;
@@ -183,14 +227,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
@@ -206,14 +250,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);}
@@ -232,7 +276,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
@@ -246,7 +290,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
@@ -270,41 +314,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 +401,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;
@@ -417,7 +463,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) ;
@@ -433,28 +479,28 @@ 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);
+       lnk->next = mergeSpec($1,lnk->next, yytext);
        $$ = $2 ;
      }
      else
-       $$ = mergeSpec($1,$2); 
+       $$ = mergeSpec($1,$2, yytext);
    }
    | type_specifier                                { $$ = $1; }
    | type_specifier 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);
+       lnk->next = mergeSpec($1,lnk->next, yytext);
        $$ = $2 ;
      }
      else
-       $$ = mergeSpec($1,$2); 
+       $$ = mergeSpec($1,$2, yytext);
    }
    ;
 
@@ -503,12 +549,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)) ;
         }
    ;
 
@@ -521,8 +567,7 @@ type_specifier2
    | SHORT  {
                $$=newLink();
                $$->class = SPECIFIER   ;
-               SPEC_LONG($$) = 0      ;
-              SPEC_SHORT($$) = 1        ;
+              $$->select.s._short = 1 ;
             }
    | INT    {
                $$=newLink();
@@ -532,18 +577,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();
@@ -553,7 +597,6 @@ type_specifier2
    | CONST  {
                $$=newLink();
               $$->class = SPECIFIER ;
-              SPEC_SCLS($$) = S_CONSTANT ;
               SPEC_CONST($$) = 1;
             }
    | VOLATILE  {
@@ -613,8 +656,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;
@@ -669,24 +711,23 @@ struct_or_union
    ;
 
 opt_stag
-   : stag
-   |  {  /* synthesize a name add to structtable */
-         $$ = newStruct(genSymName(NestLevel)) ;
-         $$->level = NestLevel ;
-         addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ;
-      }
-   ;
+: stag
+|  {  /* synthesize a name add to structtable */
+     $$ = newStruct(genSymName(NestLevel)) ;
+     $$->level = NestLevel ;
+     addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
+};
 
 stag
-   :  identifier  {  /* add name to structure table */
-                     $$ = findSymWithBlock (StructTab,$1,currBlockno);
-                     if (! $$ ) {
-                        $$ = newStruct($1->name) ;
-                        $$->level = NestLevel ;
-                        addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ;                         
-                     }
-                  }
-   ;
+:  identifier  {  /* add name to structure table */
+     $$ = findSymWithBlock (StructTab,$1,currBlockno);
+     if (! $$ ) {
+       $$ = newStruct($1->name) ;
+       $$->level = NestLevel ;
+       addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
+     }
+};
+
 
 struct_declaration_list
    : struct_declaration
@@ -708,14 +749,18 @@ struct_declaration
            symbol *sym ;
            for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
               
+              /* make the symbol one level up */
+              sym->level-- ;
+
               pointerTypes(sym->type,copyLinkChain($1));
               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;
        }
@@ -731,7 +776,7 @@ struct_declarator_list
    ;
 
 struct_declarator
-   : declarator
+   : declarator 
    | ':' constant_expr  {  
                            $$ = newSymbol (genSymName(NestLevel),NestLevel) ; 
                            $$->bitVar = (int) floatFromVal(constExprValue($2,TRUE));
@@ -758,7 +803,7 @@ enum_specifier
                                                    (csym && csym->level == $2->level))
                                                    werror(E_DUPLICATE_TYPEDEF,csym->name);
 
-                                                addSym ( enumTab,$2,$2->name,$2->level,$2->block);
+                                                addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
                                                addSymChain ($4);
                                                 allocVariables (reverseSyms($4));
                                                 $$ = copyLinkChain(cenum->type);
@@ -782,6 +827,8 @@ enum_specifier
 
 enumerator_list
    : enumerator
+   | enumerator_list ',' {
+                         }
    | enumerator_list ',' enumerator {
                                        $3->next = $1 ;
                                        $$ = $3  ;
@@ -838,7 +885,7 @@ declarator2
    | '(' declarator ')'     { $$ = $2; }
    | declarator2 '[' ']'
          {
-            link   *p;
+            sym_link   *p;
 
             p = newLink ();
             DCL_TYPE(p) = ARRAY ;
@@ -847,7 +894,7 @@ declarator2
          }
    | declarator2 '[' constant_expr ']'
          {
-            link   *p ;
+            sym_link   *p ;
                        value *tval;
                        
             p = (tval = constExprValue($3,TRUE))->etype;
@@ -870,34 +917,45 @@ declarator2
             $1->hasVargs = IS_VARG($4);
             $1->args = reverseVal($4)  ;
             
+            
             /* nest level was incremented to take care of the parms  */
             NestLevel-- ;
             currBlockno--;
+
+            // if this was a pointer to a function, remove the symbol args
+            // (if any)
+            if (IS_PTR($1->type) && IS_FUNC($1->etype)) {
+              cleanUpLevel(SymbolTab,NestLevel+1);
+              /* fprintf (stderr, "Removed parm symbols of %s in line %d\n", 
+                 $1->name, yylineno); */
+            }
+            
             $$ = $1;
          }
    | declarator2 '(' parameter_identifier_list ')'
          {        
           werror(E_OLD_STYLE,$1->name) ;         
           
-          /* assume it returns an it */
+          /* assume it returns an int */
           $1->type = $1->etype = newIntLink();
           $$ = $1 ;
          }
    ;
 
 pointer
-   : far_near_pointer { $$ = $1 ;}
-   | far_near_pointer type_specifier_list   
+   : unqualified_pointer { $$ = $1 ;}
+   | unqualified_pointer type_specifier_list   
          {
             $$ = $1  ;         
             DCL_TSPEC($1) = $2;
         }
-   | far_near_pointer pointer         
+   | unqualified_pointer pointer         
          {
             $$ = $1 ;          
             $$->next = $2 ;
+            DCL_TYPE($2)=GPOINTER;
         }
-   | far_near_pointer type_specifier_list pointer
+   | unqualified_pointer type_specifier_list pointer
          {
             $$ = $1 ;               
             if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
@@ -919,9 +977,12 @@ pointer
                 case S_CODE:
                     DCL_PTR_CONST($3) = 1;
                     DCL_TYPE($3) = CPOINTER ;
+                    break;
                 case S_EEPROM:
                     DCL_TYPE($3) = EEPPOINTER;
                     break;
+                default:
+                    werror(W_PTR_TYPE_INVALID);
                 }
             }
             else 
@@ -930,31 +991,17 @@ pointer
         }
    ;
 
-far_near_pointer
-   :  far_near '*'   {
-                        if ($1 == NULL) {
-                           $$ = newLink();
-                           DCL_TYPE($$) = POINTER ;
-                        }
-                        else
-                           $$ = $1 ;
+unqualified_pointer
+   :  '*'   
+      {
+       $$ = newLink();
+       DCL_TYPE($$)=UPOINTER;
       }
    ;
 
-far_near
-   : _XDATA    { $$ = newLink() ; DCL_TYPE($$) = FPOINTER ; }
-   | _CODE     { $$ = newLink() ; DCL_TYPE($$) = CPOINTER ;  DCL_PTR_CONST($$) = 1;}
-   | _PDATA    { $$ = newLink() ; DCL_TYPE($$) = PPOINTER ; } 
-   | _IDATA    { $$ = newLink() ; DCL_TYPE($$) = IPOINTER ; }
-   | _NEAR     { $$ = NULL ; }
-   | _GENERIC  { $$ = newLink() ; DCL_TYPE($$) = GPOINTER ; } 
-   | _EEPROM   { $$ = newLink() ; DCL_TYPE($$) = EEPPOINTER ;} 
-   |           { $$ = newLink() ; DCL_TYPE($$) = UPOINTER ; }
-   ;
-
 type_specifier_list
    : type_specifier
-   | type_specifier_list type_specifier         {  $$ = mergeSpec ($1,$2); }
+   | type_specifier_list type_specifier         {  $$ = mergeSpec ($1,$2, "type_specifier_list"); }
    ;
 
 parameter_identifier_list
@@ -1007,7 +1054,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 ;
@@ -1050,9 +1097,23 @@ abstract_declarator2
                                     }
    | '(' ')'                        { $$ = NULL;}
    | '(' parameter_type_list ')'    { $$ = NULL;}   
-   | abstract_declarator2 '(' ')'
-   | abstract_declarator2 '(' parameter_type_list ')'
-   ;
+   | abstract_declarator2 '(' ')' {
+     // $1 must be a pointer to a function
+     sym_link *p=newLink();
+     DCL_TYPE(p) = FUNCTION;
+     $1->next=p;
+   }
+   | abstract_declarator2 '(' parameter_type_list ')' {
+     if (!IS_VOID($3->type)) {
+       // this is nonsense, so let's just burp something
+       werror(E_TOO_FEW_PARMS);
+     } else {
+       // $1 must be a pointer to a function
+       sym_link *p=newLink();
+       DCL_TYPE(p) = FUNCTION;
+       $1->next=p;
+     }
+   }
 
 initializer
    : assignment_expr                { $$ = newiList(INIT_NODE,$1); }
@@ -1074,7 +1135,7 @@ statement
    | jump_statement
    | INLINEASM  ';'      {
                             ast *ex = newNode(INLINEASM,NULL,NULL);
-                           ALLOC_ATOMIC(ex->values.inlineasm,strlen($1));
+                           ex->values.inlineasm = malloc(strlen($1)+1);
                            strcpy(ex->values.inlineasm,$1);                        
                            $$ = ex;
                          }   
@@ -1276,7 +1337,7 @@ expr_opt
 jump_statement          
    : GOTO identifier ';'   { 
                               $2->islbl = 1;
-                              $$ = newAst(EX_VALUE,symbolVal($2)); 
+                              $$ = newAst_VALUE(symbolVal($2)); 
                               $$ = newNode(GOTO,$$,NULL);
                            }
    | CONTINUE ';'          {  
@@ -1286,7 +1347,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;
@@ -1297,7 +1358,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;
        }
@@ -1311,20 +1372,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;
-}
-