fixed bug #460198
[fw/sdcc] / src / SDCCast.c
index 7c8885be1742d683dd440b7343d008c9ecb8dca7..b5f72afdc2df0409627387daba8c2f56cfe44fb7 100644 (file)
@@ -180,7 +180,6 @@ newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
   /* if this is a literal then we already know the result */
   if (condAst->etype && IS_LITERAL (condAst->etype))
     {
-
       /* then depending on the expression value */
       if (floatFromVal (condAst->opval.val))
        ifxNode = newNode (GOTO,
@@ -225,7 +224,12 @@ copyAstValues (ast * dest, ast * src)
     case INLINEASM:
       dest->values.inlineasm = Safe_calloc (1, strlen (src->values.inlineasm) + 1);
       strcpy (dest->values.inlineasm, src->values.inlineasm);
+      break;
 
+    case ARRAYINIT:
+       dest->values.constlist = copyLiteralList(src->values.constlist);
+       break;
+       
     case FOR:
       AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
       AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
@@ -462,6 +466,7 @@ resolveSymbols (ast * tree)
              tree->opval.val->etype = tree->opval.val->etype;
              tree->opval.val->type = tree->opval.val->sym->type;
              werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
+             allocVariables (tree->opval.val->sym);
            }
          else
            {
@@ -536,7 +541,6 @@ funcOfType (char *name, sym_link * type, sym_link * argType,
            int nArgs, int rent)
 {
   symbol *sym;
-  int argStack = 0;
   /* create the symbol */
   sym = newSymbol (name, 0);
 
@@ -549,7 +553,6 @@ funcOfType (char *name, sym_link * type, sym_link * argType,
 
       while (nArgs--)
        {
-         argStack += getSize (type);
          args->type = copyLinkChain (argType);
          args->etype = getSpec (args->type);
          if (!nArgs)
@@ -568,7 +571,6 @@ funcOfType (char *name, sym_link * type, sym_link * argType,
   /* save it */
   addSymChain (sym);
   sym->cdef = 1;
-  sym->argStack = (rent ? argStack : 0);
   allocVariables (sym);
   return sym;
 
@@ -614,6 +616,14 @@ processParms (ast * func,
   if (!defParm && !actParm)
     return 0;
 
+  if (defParm) {
+    if (getenv("DEBUG_SANITY")) {
+      fprintf (stderr, "addSym: %s ", defParm->name);
+    }
+    /* make sure the type is complete and sane */
+    checkTypeSanity(defParm->etype, defParm->name);
+  }
+
   /* if the function is being called via a pointer &   */
   /* it has not been defined a reentrant then we cannot */
   /* have parameters                                   */
@@ -644,6 +654,7 @@ processParms (ast * func,
   if (!defParm && actParm && func->hasVargs)
     {
       ast *newType = NULL;
+      sym_link *ftype;
 
       if (IS_CAST_OP (actParm)
          || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
@@ -652,25 +663,39 @@ processParms (ast * func,
          return 0;
        }
 
+      /* The ternary ('?') operator is weird: the ftype of the 
+       * operator is the type of the condition, but it will return a 
+       * (possibly) different type. 
+       */
+      if (IS_TERNARY_OP(actParm))
+      {
+          assert(IS_COLON_OP(actParm->right));
+          assert(actParm->right->left);
+          ftype = actParm->right->left->ftype;
+      }
+      else
+      {
+          ftype = actParm->ftype;
+      }
+          
       /* If it's a small integer, upcast to int. */
-      if (IS_INTEGRAL (actParm->ftype)
-         && getSize (actParm->ftype) < (unsigned) INTSIZE)
+      if (IS_INTEGRAL (ftype)
+         && (getSize (ftype) < (unsigned) INTSIZE))
        {
-         newType = newAst_LINK (INTTYPE);
+         newType = newAst_LINK(INTTYPE);
        }
 
-      if (IS_PTR (actParm->ftype) && !IS_GENPTR (actParm->ftype))
+      if (IS_PTR(ftype) && !IS_GENPTR(ftype))
        {
-         newType = newAst_LINK (copyLinkChain (actParm->ftype));
+         newType = newAst_LINK (copyLinkChain(ftype));
          DCL_TYPE (newType->opval.lnk) = GPOINTER;
        }
 
-      if (IS_AGGREGATE (actParm->ftype))
+      if (IS_AGGREGATE (ftype))
        {
-         newType = newAst_LINK (copyLinkChain (actParm->ftype));
+         newType = newAst_LINK (copyLinkChain (ftype));
          DCL_TYPE (newType->opval.lnk) = GPOINTER;
        }
-
       if (newType)
        {
          /* cast required; change this op to a cast. */
@@ -719,7 +744,7 @@ processParms (ast * func,
     }
 
   /* the parameter type must be at least castable */
-  if (checkType (defParm->type, actParm->ftype) == 0)
+  if (compareType (defParm->type, actParm->ftype) == 0)
     {
       werror (E_TYPE_MISMATCH_PARM, *parmNumber);
       werror (E_CONTINUE, "defined type ");
@@ -731,7 +756,7 @@ processParms (ast * func,
     }
 
   /* if the parameter is castable then add the cast */
-  if (checkType (defParm->type, actParm->ftype) < 0)
+  if (compareType (defParm->type, actParm->ftype) < 0)
     {
       ast *pTree = resolveSymbols (copyAst (actParm));
 
@@ -813,6 +838,7 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist)
   ast *rast = NULL;
   initList *iloop;
   int lcnt = 0, size = 0;
+  literalList *literalL;
 
   /* take care of the special   case  */
   /* array of characters can be init  */
@@ -824,43 +850,77 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist)
 
       return decorateType (resolveSymbols (rast));
 
-  /* not the special case             */
-  if (ilist->type != INIT_DEEP)
+    /* not the special case             */
+    if (ilist->type != INIT_DEEP)
     {
-      werror (E_INIT_STRUCT, "");
-      return NULL;
+       werror (E_INIT_STRUCT, "");
+       return NULL;
     }
 
-  iloop = ilist->init.deep;
-  lcnt = DCL_ELEM (type);
+    iloop = ilist->init.deep;
+    lcnt = DCL_ELEM (type);
 
-  for (;;)
+    if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
     {
-      ast *aSym;
-      size++;
-
-      aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size - 1))));
-      aSym = decorateType (resolveSymbols (aSym));
-      rast = createIval (aSym, type->next, iloop, rast);
-      iloop = (iloop ? iloop->next : NULL);
-      if (!iloop)
-       break;
-      /* if not array limits given & we */
-      /* are out of initialisers then   */
-      if (!DCL_ELEM (type) && !iloop)
-       break;
-
-      /* no of elements given and we    */
-      /* have generated for all of them */
-      if (!--lcnt)
-       break;
+       ast *aSym;
+
+       aSym = decorateType (resolveSymbols(sym));
+       
+       rast = newNode(ARRAYINIT, aSym, NULL);
+       rast->values.constlist = literalL;
+       
+       // Make sure size is set to length of initializer list.
+       while (iloop)
+       {
+           size++;
+           iloop = iloop->next;
+       }
+       
+       if (lcnt && size > lcnt)
+       {
+           // Array size was specified, and we have more initializers than needed.
+           char *name=sym->opval.val->sym->name;
+           int lineno=sym->opval.val->sym->lineDef;
+           
+           werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
+       }
+    }
+    else
+    {
+       for (;;)
+       {
+           ast *aSym;
+           
+           aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
+           aSym = decorateType (resolveSymbols (aSym));
+           rast = createIval (aSym, type->next, iloop, rast);
+           iloop = (iloop ? iloop->next : NULL);
+           if (!iloop)
+           {
+               break;
+           }
+           
+           /* no of elements given and we    */
+           /* have generated for all of them */
+           if (!--lcnt) 
+           {
+               // there has to be a better way
+               char *name=sym->opval.val->sym->name;
+               int lineno=sym->opval.val->sym->lineDef;
+               werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
+               
+               break;
+           }
+       }
     }
 
-  /* if we have not been given a size  */
-  if (!DCL_ELEM (type))
-    DCL_ELEM (type) = size;
+    /* if we have not been given a size  */
+    if (!DCL_ELEM (type))
+    {
+       DCL_ELEM (type) = size;
+    }
 
-  return decorateType (resolveSymbols (rast));
+    return decorateType (resolveSymbols (rast));
 }
 
 
@@ -885,7 +945,6 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
        SPEC_SCLS (iexpr->etype) == S_CODE)
       && IS_ARRAY (iexpr->ftype))
     {
-
       /* for each character generate an assignment */
       /* to the array element */
       char *s = SPEC_CVAL (iexpr->etype).v_char;
@@ -1005,11 +1064,16 @@ gatherAutoInit (symbol * autoChain)
          SPEC_SCLS (sym->etype) != S_CODE)
        {
          symbol *newSym;
+         
+         // this can only be a constant
+         if (!inInitMode && !IS_LITERAL(sym->ival->init.node->etype)) {
+           werror (E_CONST_EXPECTED);
+         }
 
          /* insert the symbol into the symbol table */
          /* with level = 0 & name = rname       */
          newSym = copySymbol (sym);
-         addSym (SymbolTab, newSym, newSym->name, 0, 0);
+         addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
 
          /* now lift the code to main */
          if (IS_AGGREGATE (sym->type))
@@ -1359,11 +1423,25 @@ astHasSymbol (ast * tree, symbol * sym)
       else
        return FALSE;
     }
-
+  
   return astHasSymbol (tree->left, sym) ||
     astHasSymbol (tree->right, sym);
 }
 
+/*-----------------------------------------------------------------*/
+/* astHasDeref - return true if the ast has an indirect access     */
+/*-----------------------------------------------------------------*/
+static bool 
+astHasDeref (ast * tree)
+{
+  if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
+    return FALSE;
+
+  if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
+  
+  return astHasDeref (tree->left) || astHasDeref (tree->right);
+}
+
 /*-----------------------------------------------------------------*/
 /* isConformingBody - the loop body has to conform to a set of rules */
 /* for the loop to be considered reversible read on for rules      */
@@ -1514,6 +1592,8 @@ isConformingBody (ast * pbody, symbol * sym, ast * body)
 
       if (astHasVolatile (pbody->left))
        return FALSE;
+      
+      if (astHasDeref(pbody->right)) return FALSE;
 
       return isConformingBody (pbody->left, sym, body) &&
        isConformingBody (pbody->right, sym, body);
@@ -1680,7 +1760,7 @@ reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
 
 }
 
-#define DEMAND_INTEGER_PROMOTION
+//#define DEMAND_INTEGER_PROMOTION
 
 #ifdef DEMAND_INTEGER_PROMOTION
 
@@ -1691,7 +1771,7 @@ reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
 void 
 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
 {
-  if (!node)
+  if (!node || IS_CALLOP(node))
     {
       /* WTF? We should never get here. */
       return;
@@ -2020,6 +2100,9 @@ decorateType (ast * tree)
              return decorateType (otree);
          }
 
+#if 0 
+         // we can't do this because of "(int & 0xff) << 3"
+
          /* if right or left is literal then result of that type */
          if (IS_LITERAL (RTYPE (tree)))
            {
@@ -2044,6 +2127,11 @@ decorateType (ast * tree)
                  TETYPE (tree) = getSpec (TTYPE (tree));
                }
            }
+#else
+         TTYPE (tree) =
+           computeType (LTYPE (tree), RTYPE (tree));
+         TETYPE (tree) = getSpec (TTYPE (tree));
+#endif
          LRVAL (tree) = RRVAL (tree) = 1;
          return tree;
        }
@@ -2274,19 +2362,17 @@ decorateType (ast * tree)
        }
 
       LRVAL (tree) = RRVAL (tree) = 1;
-      /* promote result to int if left & right are char / short 
+      /* promote result to int if left & right are char
         this will facilitate hardware multiplies 8bit x 8bit = 16bit */
-      if ((IS_CHAR(LETYPE(tree)) || IS_SHORT(LETYPE(tree))) && 
-          (IS_CHAR(RETYPE(tree)) || IS_SHORT(RETYPE(tree)))) {
-             TETYPE (tree) = getSpec (TTYPE (tree) =
-                                      computeType (LTYPE (tree),
-                                                   RTYPE (tree)));
-             SPEC_NOUN(TETYPE(tree)) = V_INT;
-             SPEC_SHORT(TETYPE(tree))=0;
+      if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
+       TETYPE (tree) = getSpec (TTYPE (tree) =
+                                computeType (LTYPE (tree),
+                                             RTYPE (tree)));
+       SPEC_NOUN(TETYPE(tree)) = V_INT;
       } else {
-             TETYPE (tree) = getSpec (TTYPE (tree) =
-                                      computeType (LTYPE (tree),
-                                                   RTYPE (tree)));
+       TETYPE (tree) = getSpec (TTYPE (tree) =
+                                computeType (LTYPE (tree),
+                                             RTYPE (tree)));
       }
       return tree;
 
@@ -2608,6 +2694,9 @@ decorateType (ast * tree)
          werror (E_CAST_ILLEGAL);
          goto errorTreeReturn;
        }
+      
+      /* make sure the type is complete and sane */
+      checkTypeSanity(LETYPE(tree), "(cast)");
 
       /* if the right is a literal replace the tree */
       if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree)))
@@ -2691,7 +2780,7 @@ decorateType (ast * tree)
       /* if they are pointers they must be castable */
       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
        {
-         if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
+         if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
            {
              werror (E_COMPARE_OP);
              fprintf (stderr, "comparing type ");
@@ -2708,7 +2797,7 @@ decorateType (ast * tree)
          if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
                (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
 
-           if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
+           if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
              {
                werror (E_COMPARE_OP);
                fprintf (stderr, "comparing type ");
@@ -2757,14 +2846,15 @@ decorateType (ast * tree)
       /* conditional operator  '?'  */
 /*----------------------------*/
     case '?':
-      /* the type is one on the left */
-      TTYPE (tree) = LTYPE (tree);
+      /* the type is value of the colon operator (on the right) */
+      assert(IS_COLON_OP(tree->right));
+      TTYPE (tree) = RTYPE(tree); // #HACK LTYPE(tree).
       TETYPE (tree) = getSpec (TTYPE (tree));
       return tree;
 
     case ':':
       /* if they don't match we have a problem */
-      if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
+      if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
        {
          werror (E_TYPE_MISMATCH, "conditional operator", " ");
          goto errorTreeReturn;
@@ -2929,7 +3019,7 @@ decorateType (ast * tree)
        }
 
       /* they should either match or be castable */
-      if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
+      if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
        {
          werror (E_TYPE_MISMATCH, "assignment", " ");
          fprintf (stderr, "type --> '");
@@ -3019,7 +3109,7 @@ decorateType (ast * tree)
       if (!tree->right)
        goto voidcheck;
 
-      if (checkType (currFunc->type->next, RTYPE (tree)) == 0)
+      if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
        {
          werror (E_RETURN_MISMATCH);
          goto errorTreeReturn;
@@ -3034,7 +3124,7 @@ decorateType (ast * tree)
        }
 
       /* if there is going to be a casing required then add it */
-      if (checkType (currFunc->type->next, RTYPE (tree)) < 0)
+      if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
        {
 #if 0 && defined DEMAND_INTEGER_PROMOTION
          if (IS_INTEGRAL (currFunc->type->next))
@@ -3142,6 +3232,9 @@ sizeofOp (sym_link * type)
 {
   char buff[10];
 
+  /* make sure the type is complete and sane */
+  checkTypeSanity(type, "(sizeof)");
+
   /* get the size and convert it to character  */
   sprintf (buff, "%d", getSize (type));
 
@@ -3303,7 +3396,7 @@ createLabel (symbol * label, ast * stmnt)
   if ((csym = findSym (LabelTab, NULL, name)))
     werror (E_DUPLICATE_LABEL, label->name);
   else
-    addSym (LabelTab, label, name, label->level, 0);
+    addSym (LabelTab, label, name, label->level, 0, 0);
 
   label->islbl = 1;
   label->key = labelKey++;
@@ -4127,7 +4220,7 @@ skipall:
   addSet (&operKeyReset, name);
   applyToSet (operKeyReset, resetParmKey);
 
-  if (options.debug && !options.nodebug)
+  if (options.debug)
     cdbStructBlock (1, cdbFile);
 
   cleanUpLevel (LabelTab, 0);
@@ -4138,3 +4231,658 @@ skipall:
   istack->syms = NULL;
   return NULL;
 }
+
+
+#define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
+/*-----------------------------------------------------------------*/
+/* ast_print : prints the ast (for debugging purposes)             */
+/*-----------------------------------------------------------------*/
+
+void ast_print (ast * tree, FILE *outfile, int indent)
+{
+       
+       if (!tree) return ;
+
+       /* can print only decorated trees */
+       if (!tree->decorated) return;
+
+       /* if any child is an error | this one is an error do nothing */
+       if (tree->isError ||
+           (tree->left && tree->left->isError) ||
+           (tree->right && tree->right->isError)) {
+               fprintf(outfile,"ERROR_NODE(%p)\n",tree);
+       }
+
+       
+       /* print the line          */
+       /* if not block & function */
+       if (tree->type == EX_OP &&
+           (tree->opval.op != FUNCTION &&
+            tree->opval.op != BLOCK &&
+            tree->opval.op != NULLOP)) {
+       }
+       
+       if (tree->opval.op == FUNCTION) {
+               fprintf(outfile,"FUNCTION (%p) type (",tree);
+               printTypeChain (tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return ;
+       }
+       if (tree->opval.op == BLOCK) {
+               symbol *decls = tree->values.sym;
+               fprintf(outfile,"{\n");
+               while (decls) {
+                       INDENT(indent+4,outfile);
+                       fprintf(outfile,"DECLARE SYMBOL %s, type(",decls->name);
+                       printTypeChain(decls->type,outfile);
+                       fprintf(outfile,")\n");
+                       
+                       decls = decls->next;                    
+               }
+               ast_print(tree->right,outfile,indent+4);
+               fprintf(outfile,"}\n");
+               return;
+       }
+       if (tree->opval.op == NULLOP) {
+               fprintf(outfile,"\n");
+               ast_print(tree->left,outfile,indent);
+               fprintf(outfile,"\n");
+               ast_print(tree->right,outfile,indent);
+               return ;
+       }
+       INDENT(indent,outfile);
+
+       /*------------------------------------------------------------------*/
+       /*----------------------------*/
+       /*   leaf has been reached    */
+       /*----------------------------*/
+       /* if this is of type value */
+       /* just get the type        */
+       if (tree->type == EX_VALUE) {
+
+               if (IS_LITERAL (tree->opval.val->etype)) {                      
+                       fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
+                               (int) floatFromVal(tree->opval.val),
+                               (int) floatFromVal(tree->opval.val),
+                               floatFromVal(tree->opval.val));
+               } else if (tree->opval.val->sym) {
+                       /* if the undefined flag is set then give error message */
+                       if (tree->opval.val->sym->undefined) {
+                               fprintf(outfile,"UNDEFINED SYMBOL ");
+                       } else {
+                               fprintf(outfile,"SYMBOL ");
+                       }
+                       fprintf(outfile,"(%p) name= %s ",tree,tree->opval.val->sym->name);
+               }
+               if (tree->ftype) {
+                       fprintf(outfile," type (");
+                       printTypeChain(tree->ftype,outfile);
+                       fprintf(outfile,")\n");
+               } else {
+                       fprintf(outfile,"\n");
+               }
+               return ;
+       }
+
+       /* if type link for the case of cast */
+       if (tree->type == EX_LINK) {
+               fprintf(outfile,"TYPENODE (%p) type = (",tree);
+               printTypeChain(tree->opval.lnk,outfile);
+               fprintf(outfile,")\n");
+               return ;
+       }
+
+
+       /* depending on type of operator do */
+       
+       switch (tree->opval.op) {
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /*        array node          */
+               /*----------------------------*/
+       case '[':
+               fprintf(outfile,"ARRAY_OP (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return;
+
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /*      struct/union          */
+               /*----------------------------*/
+       case '.':
+               fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return ;
+
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /*    struct/union pointer    */
+               /*----------------------------*/
+       case PTR_OP:
+               fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return ;
+
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /*  ++/-- operation           */
+               /*----------------------------*/
+       case INC_OP:            /* incerement operator unary so left only */
+               fprintf(outfile,"INC_OP (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               return ;
+
+       case DEC_OP:
+               fprintf(outfile,"DEC_OP (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               return ;
+
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /*  bitwise and               */
+               /*----------------------------*/
+       case '&':                       
+               if (tree->right) {
+                       fprintf(outfile,"& (%p) type (",tree);
+                       printTypeChain(tree->ftype,outfile);
+                       fprintf(outfile,")\n");
+                       ast_print(tree->left,outfile,indent+4);
+                       ast_print(tree->right,outfile,indent+4);
+               } else {
+                       fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
+                       printTypeChain(tree->ftype,outfile);
+                       fprintf(outfile,")\n");
+                       ast_print(tree->left,outfile,indent+4);
+                       ast_print(tree->right,outfile,indent+4);
+               }
+               return ;
+               /*----------------------------*/
+               /*  bitwise or                */
+               /*----------------------------*/
+       case '|':
+               fprintf(outfile,"OR (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return ;
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /*  bitwise xor               */
+               /*----------------------------*/
+       case '^':
+               fprintf(outfile,"XOR (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return ;
+               
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /*  division                  */
+               /*----------------------------*/
+       case '/':
+               fprintf(outfile,"DIV (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return ;
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /*            modulus         */
+               /*----------------------------*/
+       case '%':
+               fprintf(outfile,"MOD (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return ;
+
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /*  address dereference       */
+               /*----------------------------*/
+       case '*':                       /* can be unary  : if right is null then unary operation */
+               if (!tree->right) {
+                       fprintf(outfile,"DEREF (%p) type (",tree);
+                       printTypeChain(tree->ftype,outfile);
+                       fprintf(outfile,")\n");
+                       ast_print(tree->left,outfile,indent+4);
+                       return ;
+               }                       
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /*      multiplication        */
+               /*----------------------------*/                
+               fprintf(outfile,"MULT (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return ;
+
+
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /*    unary '+' operator      */
+               /*----------------------------*/
+       case '+':
+               /* if unary plus */
+               if (!tree->right) {
+                       fprintf(outfile,"UPLUS (%p) type (",tree);
+                       printTypeChain(tree->ftype,outfile);
+                       fprintf(outfile,")\n");
+                       ast_print(tree->left,outfile,indent+4);
+               } else {
+                       /*------------------------------------------------------------------*/
+                       /*----------------------------*/
+                       /*      addition              */
+                       /*----------------------------*/
+                       fprintf(outfile,"ADD (%p) type (",tree);
+                       printTypeChain(tree->ftype,outfile);
+                       fprintf(outfile,")\n");
+                       ast_print(tree->left,outfile,indent+4);
+                       ast_print(tree->right,outfile,indent+4);
+               }
+               return;
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /*      unary '-'             */
+               /*----------------------------*/
+       case '-':                       /* can be unary   */
+               if (!tree->right) {
+                       fprintf(outfile,"UMINUS (%p) type (",tree);
+                       printTypeChain(tree->ftype,outfile);
+                       fprintf(outfile,")\n");
+                       ast_print(tree->left,outfile,indent+4);
+               } else {
+                       /*------------------------------------------------------------------*/
+                       /*----------------------------*/
+                       /*      subtraction           */
+                       /*----------------------------*/
+                       fprintf(outfile,"SUB (%p) type (",tree);
+                       printTypeChain(tree->ftype,outfile);
+                       fprintf(outfile,")\n");
+                       ast_print(tree->left,outfile,indent+4);
+                       ast_print(tree->right,outfile,indent+4);
+               }
+               return;
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /*    compliment              */
+               /*----------------------------*/
+       case '~':
+               fprintf(outfile,"COMPL (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               return ;
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /*           not              */
+               /*----------------------------*/
+       case '!':
+               fprintf(outfile,"NOT (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               return ;
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /*           shift            */
+               /*----------------------------*/
+       case RRC:
+               fprintf(outfile,"RRC (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               return ;
+
+       case RLC:
+               fprintf(outfile,"RLC (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               return ;
+       case GETHBIT:
+               fprintf(outfile,"GETHBIT (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               return ;
+       case LEFT_OP:
+               fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return ;
+       case RIGHT_OP:
+               fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return ;
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /*         casting            */
+               /*----------------------------*/
+       case CAST:                      /* change the type   */
+               fprintf(outfile,"CAST (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->right,outfile,indent+4);
+               return ;
+               
+       case AND_OP:
+               fprintf(outfile,"ANDAND (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return ;
+       case OR_OP:
+               fprintf(outfile,"OROR (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return ;
+               
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /*     comparison operators   */
+               /*----------------------------*/
+       case '>':
+               fprintf(outfile,"GT(>) (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return ;
+       case '<':
+               fprintf(outfile,"LT(<) (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return ;
+       case LE_OP:
+               fprintf(outfile,"LE(<=) (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return ;
+       case GE_OP:
+               fprintf(outfile,"GE(>=) (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return ;
+       case EQ_OP:
+               fprintf(outfile,"EQ(==) (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return ;
+       case NE_OP:
+               fprintf(outfile,"NE(!=) (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /*             sizeof         */
+               /*----------------------------*/
+       case SIZEOF:            /* evaluate wihout code generation */
+               fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
+               return ;
+
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /* conditional operator  '?'  */
+               /*----------------------------*/
+       case '?':
+               fprintf(outfile,"QUEST(?) (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+
+       case ':':
+               fprintf(outfile,"COLON(:) (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return ;
+               
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /*    assignment operators    */
+               /*----------------------------*/
+       case MUL_ASSIGN:
+               fprintf(outfile,"MULASS(*=) (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return;
+       case DIV_ASSIGN:
+               fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return;
+       case AND_ASSIGN:
+               fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return;
+       case OR_ASSIGN:
+               fprintf(outfile,"ORASS(*=) (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return;
+       case XOR_ASSIGN:
+               fprintf(outfile,"XORASS(*=) (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return;
+       case RIGHT_ASSIGN:
+               fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return;
+       case LEFT_ASSIGN:
+               fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return;
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /*    -= operator             */
+               /*----------------------------*/
+       case SUB_ASSIGN:
+               fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return;
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /*          += operator       */
+               /*----------------------------*/
+       case ADD_ASSIGN:
+               fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return;
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /*      straight assignemnt   */
+               /*----------------------------*/
+       case '=':
+               fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return;     
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /*      comma operator        */
+               /*----------------------------*/
+       case ',':
+               fprintf(outfile,"COMMA(,) (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return;
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /*       function call        */
+               /*----------------------------*/
+       case CALL:
+       case PCALL:
+               fprintf(outfile,"CALL (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent+4);
+               return;
+       case PARAM:
+               fprintf(outfile,"PARM ");
+               ast_print(tree->left,outfile,indent+4);
+               if (tree->right && !IS_AST_PARAM(tree->right)) {
+                       fprintf(outfile,"PARM ");
+                       ast_print(tree->right,outfile,indent+4);
+               }
+               return ;
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /*     return statement       */
+               /*----------------------------*/
+       case RETURN:
+               fprintf(outfile,"RETURN (%p) type (",tree);
+               printTypeChain(tree->right->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->right,outfile,indent+4);
+               return ;
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /*     label statement        */
+               /*----------------------------*/
+       case LABEL :
+               fprintf(outfile,"LABEL (%p)",tree);
+               ast_print(tree->left,outfile,indent+4);
+               ast_print(tree->right,outfile,indent);
+               return;
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /*     switch statement       */
+               /*----------------------------*/
+       case SWITCH:
+               {
+                       value *val;
+                       fprintf(outfile,"SWITCH (%p) ",tree);
+                       ast_print(tree->left,outfile,0);
+                       for (val = tree->values.switchVals.swVals; val ; val = val->next) {
+                               INDENT(indent+4,outfile);
+                               fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
+                                       (int) floatFromVal(val),
+                                       tree->values.switchVals.swNum,
+                                       (int) floatFromVal(val));
+                       }
+                       ast_print(tree->right,outfile,indent);
+               }
+               return ;
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /* ifx Statement              */
+               /*----------------------------*/
+       case IFX:
+               ast_print(tree->left,outfile,indent);
+               INDENT(indent,outfile);
+               fprintf(outfile,"IF (%p) \n",tree);
+               if (tree->trueLabel) {
+                       INDENT(indent,outfile);
+                       fprintf(outfile,"NE(==) 0 goto %s\n",tree->trueLabel->name);
+               }
+               if (tree->falseLabel) {
+                       INDENT(indent,outfile);
+                       fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
+               }
+               ast_print(tree->right,outfile,indent);
+               return ;
+               /*------------------------------------------------------------------*/
+               /*----------------------------*/
+               /* for Statement              */
+               /*----------------------------*/
+       case FOR:
+               fprintf(outfile,"FOR (%p) \n",tree);
+               if (AST_FOR( tree, initExpr)) {
+                       INDENT(indent+4,outfile);
+                       fprintf(outfile,"INIT EXPR ");
+                       ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
+               }
+               if (AST_FOR( tree, condExpr)) {
+                       INDENT(indent+4,outfile);
+                       fprintf(outfile,"COND EXPR ");
+                       ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
+               }
+               if (AST_FOR( tree, loopExpr)) {
+                       INDENT(indent+4,outfile);
+                       fprintf(outfile,"LOOP EXPR ");
+                       ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
+               }
+               fprintf(outfile,"FOR LOOP BODY \n");
+               ast_print(tree->left,outfile,indent+4);
+               return ;
+       default:
+           return ;
+       }
+}
+
+void PA(ast *t)
+{
+       ast_print(t,stdout,1);
+}