]> git.sur5r.net Git - cc65/blobdiff - src/ca65/studyexpr.c
Normalized code.
[cc65] / src / ca65 / studyexpr.c
index b21f3b28bbc375b43a2648b14ee987eb77096295..cb2795bd3b5224012a3b5cc8188be6b3b34d4cf7 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2003-2007 Ullrich von Bassewitz                                       */
-/*               Roemerstrasse 52                                            */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 2003-2012, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -37,7 +37,7 @@
 
 /* common */
 #include "check.h"
-#include "print.h"
+#include "debugflag.h"
 #include "shift.h"
 #include "xmalloc.h"
 
@@ -61,7 +61,7 @@ ExprDesc* ED_Init (ExprDesc* ED)
 {
     ED->Flags     = ED_OK;
     ED->AddrSize  = ADDR_SIZE_DEFAULT;
-    ED->Val      = 0;
+    ED->Val       = 0;
     ED->SymCount  = 0;
     ED->SymLimit  = 0;
     ED->SymRef    = 0;
@@ -106,11 +106,19 @@ int ED_IsConst (const ExprDesc* D)
 
 
 static int ED_IsValid (const ExprDesc* D)
-/* Return true if the expression is valid, that is, the TOO_COMPLEX flag is
- * not set
+/* Return true if the expression is valid, that is, neither the ERROR nor the
+ * TOO_COMPLEX flags are set.
  */
 {
-    return ((D->Flags & ED_TOO_COMPLEX) == 0);
+    return ((D->Flags & (ED_ERROR | ED_TOO_COMPLEX)) == 0);
+}
+
+
+
+static int ED_HasError (const ExprDesc* D)
+/* Return true if the expression has an error. */
+{
+    return ((D->Flags & ED_ERROR) != 0);
 }
 
 
@@ -123,6 +131,14 @@ static void ED_Invalidate (ExprDesc* D)
 
 
 
+static void ED_SetError (ExprDesc* D)
+/* Set the TOO_COMPLEX and ERROR flags for D */
+{
+    D->Flags |= (ED_ERROR | ED_TOO_COMPLEX);
+}
+
+
+
 static void ED_UpdateAddrSize (ExprDesc* ED, unsigned char AddrSize)
 /* Update the address size of the expression */
 {
@@ -416,7 +432,7 @@ static void ED_Move (ExprDesc* From, ExprDesc* To)
 
 
 /*****************************************************************************/
-/*                                          Code                                    */
+/*                                   Code                                    */
 /*****************************************************************************/
 
 
@@ -507,13 +523,10 @@ static void StudySymbol (ExprNode* Expr, ExprDesc* D)
     if (SymHasExpr (Sym)) {
 
         if (SymHasUserMark (Sym)) {
-            if (Verbosity > 0) {
-                DumpExpr (Expr, SymResolve);
-            }
             LIError (&Sym->DefLines,
                      "Circular reference in definition of symbol `%m%p'",
                      GetSymName (Sym));
-            ED_Invalidate (D);
+            ED_SetError (D);
         } else {
 
             unsigned char AddrSize;
@@ -523,6 +536,11 @@ static void StudySymbol (ExprNode* Expr, ExprDesc* D)
             StudyExprInternal (GetSymExpr (Sym), D);
             SymUnmarkUser (Sym);
 
+            /* If requested and if the expression is valid, dump it */
+            if (Debug > 0 && !ED_HasError (D)) {
+                DumpExpr (Expr, SymResolve);
+            }
+
             /* If the symbol has an explicit address size, use it. This may
              * lead to range errors later (maybe even in the linker stage), if
              * the user lied about the address size, but for now we trust him.
@@ -733,7 +751,7 @@ static void StudyDiv (ExprNode* Expr, ExprDesc* D)
     if (ED_IsValid (D)) {
         if (D->Right == 0) {
             Error ("Division by zero");
-            ED_Invalidate (D);
+            ED_SetError (D);
         } else {
             D->Val /= D->Right;
         }
@@ -752,7 +770,7 @@ static void StudyMod (ExprNode* Expr, ExprDesc* D)
     if (ED_IsValid (D)) {
         if (D->Right == 0) {
             Error ("Modulo operation with zero");
-            ED_Invalidate (D);
+            ED_SetError (D);
         } else {
             D->Val %= D->Right;
         }
@@ -1095,6 +1113,18 @@ static void StudyBoolNot (ExprNode* Expr, ExprDesc* D)
 
 
 
+static void StudyBank (ExprNode* Expr, ExprDesc* D)
+/* Study an EXPR_BANK expression node */
+{
+    /* Study the expression extracting section references */
+    StudyExprInternal (Expr->Left, D);
+
+    /* The expression is always linker evaluated, so invalidate it */
+    ED_Invalidate (D);
+}
+
+
+
 static void StudyByte0 (ExprNode* Expr, ExprDesc* D)
 /* Study an EXPR_BYTE0 expression node */
 {
@@ -1179,7 +1209,7 @@ static void StudyWord0 (ExprNode* Expr, ExprDesc* D)
 
     /* We can handle only const expressions */
     if (ED_IsConst (D)) {
-        D->Val = (D->Val & 0xFFFFL);
+        D->Val &= 0xFFFFL;
     } else {
         ED_Invalidate (D);
     }
@@ -1209,35 +1239,73 @@ static void StudyWord1 (ExprNode* Expr, ExprDesc* D)
 
 
 
+static void StudyFarAddr (ExprNode* Expr, ExprDesc* D)
+/* Study an EXPR_FARADDR expression node */
+{
+    /* Study the expression */
+    StudyExprInternal (Expr->Left, D);
+
+    /* We can handle only const expressions */
+    if (ED_IsConst (D)) {
+        D->Val &= 0xFFFFFFL;
+    } else {
+        ED_Invalidate (D);
+    }
+
+    /* In any case, the result is a far address */
+    D->AddrSize = ADDR_SIZE_FAR;
+}
+
+
+
+static void StudyDWord (ExprNode* Expr, ExprDesc* D)
+/* Study an EXPR_DWORD expression node */
+{
+    /* Study the expression */
+    StudyExprInternal (Expr->Left, D);
+
+    /* We can handle only const expressions */
+    if (ED_IsConst (D)) {
+        D->Val &= 0xFFFFFFFFL;
+    } else {
+        ED_Invalidate (D);
+    }
+
+    /* In any case, the result is a long expression */
+    D->AddrSize = ADDR_SIZE_LONG;
+}
+
+
+
 static void StudyExprInternal (ExprNode* Expr, ExprDesc* D)
 /* Study an expression tree and place the contents into D */
 {
     /* Study this expression node */
     switch (Expr->Op) {
 
-       case EXPR_LITERAL:
+        case EXPR_LITERAL:
             StudyLiteral (Expr, D);
-           break;
+            break;
 
-       case EXPR_SYMBOL:
+        case EXPR_SYMBOL:
             StudySymbol (Expr, D);
             break;
 
-       case EXPR_SECTION:
+        case EXPR_SECTION:
             StudySection (Expr, D);
-           break;
+            break;
 
-       case EXPR_ULABEL:
+        case EXPR_ULABEL:
             StudyULabel (Expr, D);
             break;
 
-       case EXPR_PLUS:
+        case EXPR_PLUS:
             StudyPlus (Expr, D);
-           break;
+            break;
 
-       case EXPR_MINUS:
-                   StudyMinus (Expr, D);
-           break;
+        case EXPR_MINUS:
+            StudyMinus (Expr, D);
+            break;
 
         case EXPR_MUL:
             StudyMul (Expr, D);
@@ -1331,6 +1399,10 @@ static void StudyExprInternal (ExprNode* Expr, ExprDesc* D)
             StudyBoolNot (Expr, D);
             break;
 
+        case EXPR_BANK:
+            StudyBank (Expr, D);
+            break;
+
         case EXPR_BYTE0:
             StudyByte0 (Expr, D);
             break;
@@ -1355,9 +1427,17 @@ static void StudyExprInternal (ExprNode* Expr, ExprDesc* D)
             StudyWord1 (Expr, D);
             break;
 
+        case EXPR_FARADDR:
+            StudyFarAddr (Expr, D);
+            break;
+
+        case EXPR_DWORD:
+            StudyDWord (Expr, D);
+            break;
+
         default:
-           Internal ("Unknown Op type: %u", Expr->Op);
-           break;
+            Internal ("Unknown Op type: %u", Expr->Op);
+            break;
     }
 }
 
@@ -1459,6 +1539,3 @@ void StudyExpr (ExprNode* Expr, ExprDesc* D)
     printf ("%u sections:\n", D->SecCount);
 #endif
 }
-
-
-