]> git.sur5r.net Git - cc65/blobdiff - src/ca65/studyexpr.c
Finished implemenation of commands to delete macros. Added the new commands to
[cc65] / src / ca65 / studyexpr.c
index 2fafda9343840b8c5199ed6c666214f4b0cc9c6c..42a8dbbd6a748b513b53791aad8cc49a6ebc357c 100644 (file)
@@ -6,8 +6,8 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2003      Ullrich von Bassewitz                                       */
-/*               Römerstraße 52                                              */
+/* (C) 2003-2007 Ullrich von Bassewitz                                       */
+/*               Roemerstrasse 52                                            */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
@@ -487,7 +487,7 @@ static void StudyLiteral (ExprNode* Expr, ExprDesc* D)
 /* Study a literal expression node */
 {
     /* This one is easy */
-    D->Val      = Expr->V.Val;
+    D->Val      = Expr->V.IVal;
     D->AddrSize = GetConstAddrSize (D->Val);
 }
 
@@ -510,9 +510,9 @@ static void StudySymbol (ExprNode* Expr, ExprDesc* D)
             if (Verbosity > 0) {
                 DumpExpr (Expr, SymResolve);
             }
-            PError (GetSymPos (Sym),
-                    "Circular reference in definition of symbol `%s'",
-                    GetSymName (Sym));
+            LIError (&Sym->LineInfos,
+                     "Circular reference in definition of symbol `%m%p'",
+                     GetSymName (Sym));
             ED_Invalidate (D);
         } else {
 
@@ -581,7 +581,7 @@ static void StudySection (ExprNode* Expr, ExprDesc* D)
 /* Study a section expression node */
 {
     /* Get the section reference */
-    ED_SecRef* SecRef = ED_GetSecRef (D, Expr->V.SegNum);
+    ED_SecRef* SecRef = ED_GetSecRef (D, Expr->V.SecNum);
 
     /* Update the data and the address size */
     ++SecRef->Count;
@@ -598,7 +598,7 @@ static void StudyULabel (ExprNode* Expr, ExprDesc* D)
      */
     if (ULabCanResolve ()) {
         /* We can resolve the label */
-        StudyExprInternal (ULabResolve (Expr->V.Val), D);
+        StudyExprInternal (ULabResolve (Expr->V.IVal), D);
     } else {
         ED_Invalidate (D);
     }
@@ -619,7 +619,7 @@ static void StudyPlus (ExprNode* Expr, ExprDesc* D)
     StudyExprInternal (Expr->Right, &Right);
 
     /* Check if we can handle the operation */
-    if (ED_IsValid (D) || ED_IsValid (&Right)) {
+    if (ED_IsValid (D) && ED_IsValid (&Right)) {
 
         /* Add both */
         ED_Add (D, &Right);
@@ -654,7 +654,7 @@ static void StudyMinus (ExprNode* Expr, ExprDesc* D)
     StudyExprInternal (Expr->Right, &Right);
 
     /* Check if we can handle the operation */
-    if (ED_IsValid (D) || ED_IsValid (&Right)) {
+    if (ED_IsValid (D) && ED_IsValid (&Right)) {
 
         /* Subtract both */
         ED_Sub (D, &Right);
@@ -1002,6 +1002,34 @@ static void StudyBoolXor (ExprNode* Expr, ExprDesc* D)
 
 
 
+static void StudyMax (ExprNode* Expr, ExprDesc* D)
+/* Study an MAX binary expression node */
+{
+    /* Use helper function */
+    StudyBinaryExpr (Expr, D);
+
+    /* If the result is valid, apply the operation */
+    if (ED_IsValid (D)) {
+        D->Val = (D->Val > D->Right)? D->Val : D->Right;
+    }
+}
+
+
+
+static void StudyMin (ExprNode* Expr, ExprDesc* D)
+/* Study an MIN binary expression node */
+{
+    /* Use helper function */
+    StudyBinaryExpr (Expr, D);
+
+    /* If the result is valid, apply the operation */
+    if (ED_IsValid (D)) {
+        D->Val = (D->Val < D->Right)? D->Val : D->Right;
+    }
+}
+
+
+
 static void StudyUnaryMinus (ExprNode* Expr, ExprDesc* D)
 /* Study an EXPR_UNARY_MINUS expression node */
 {
@@ -1279,6 +1307,14 @@ static void StudyExprInternal (ExprNode* Expr, ExprDesc* D)
             StudyBoolXor (Expr, D);
             break;
 
+        case EXPR_MAX:
+            StudyMax (Expr, D);
+            break;
+
+        case EXPR_MIN:
+            StudyMin (Expr, D);
+            break;
+
         case EXPR_UNARY_MINUS:
             StudyUnaryMinus (Expr, D);
             break;
@@ -1378,34 +1414,30 @@ void StudyExpr (ExprNode* Expr, ExprDesc* D)
      */
     if (ED_IsValid (D)) {
         unsigned char AddrSize;
-        if (D->SymCount == 1 && D->SecCount == 0) {
-            /* Exactly one symbol. Assume that the expression has the size of
-             * the symbol, provided that this size is known.
-             */
-            const SymEntry* Sym = D->SymRef[0].Ref;
-            AddrSize = GetSymAddrSize (Sym);
-            if (AddrSize != ADDR_SIZE_DEFAULT) {
-                D->AddrSize = AddrSize;
-            } else {
-                AddrSize = GetConstAddrSize (D->Val);
+
+        /* If there are symbols or sections, use the largest one. If the
+         * expression resolves to a const, use the address size of the value.
+         */
+        if (D->SymCount > 0 || D->SecCount > 0) {
+
+            D->AddrSize = ADDR_SIZE_DEFAULT;
+
+            for (I = 0; I < D->SymCount; ++I) {
+                const SymEntry* Sym = D->SymRef[I].Ref;
+                AddrSize = GetSymAddrSize (Sym);
                 if (AddrSize > D->AddrSize) {
                     D->AddrSize = AddrSize;
                 }
             }
-        } else if (D->SymCount == 0 && D->SecCount == 1) {
-            /* Exactly one segment reference (segment+offset). In this case,
-             * the expression has the address size of the segment.
-             */
-            unsigned SegNum = D->SecRef[0].Ref;
-            AddrSize = GetSegAddrSize (SegNum);
-            if (AddrSize != ADDR_SIZE_DEFAULT) {
-                D->AddrSize = AddrSize;
-            } else {
-                AddrSize = GetConstAddrSize (D->Val);
+
+            for (I = 0; I < D->SecCount; ++I) {
+                unsigned SegNum = D->SecRef[0].Ref;
+                AddrSize = GetSegAddrSize (SegNum);
                 if (AddrSize > D->AddrSize) {
                     D->AddrSize = AddrSize;
                 }
             }
+
         } else {
             AddrSize = GetConstAddrSize (D->Val);
             if (AddrSize > D->AddrSize) {