]> git.sur5r.net Git - cc65/blobdiff - src/ca65/condasm.c
Finished implemenation of commands to delete macros. Added the new commands to
[cc65] / src / ca65 / condasm.c
index bbf1089ccc380ceea36f5fd962d30057fa5afa7e..49ad252fba25c9de28c1f3e564e6712ec2ab1cce 100644 (file)
@@ -58,8 +58,9 @@
 enum {
     ifNone     = 0x0000,               /* No flag */
     ifCond     = 0x0001,               /* IF condition was true */
-    ifElse     = 0x0002,               /* We had a .ELSE branch */
-    ifNeedTerm         = 0x0004,               /* Need .ENDIF termination */
+    ifParentCond= 0x0002,               /* IF condition of parent */
+    ifElse             = 0x0004,               /* We had a .ELSE branch */
+    ifNeedTerm         = 0x0008,               /* Need .ENDIF termination */
 };
 
 /* The overall .IF condition */
@@ -87,31 +88,6 @@ static unsigned IfCount = 0;
 
 
 
-static IfDesc* AllocIf (const char* Directive, int NeedTerm)
-/* Alloc a new element from the .IF stack */
-{
-    IfDesc* ID;
-
-    /* Check for stack overflow */
-    if (IfCount >= MAX_IFS) {
-               Fatal ("Too many nested .IFs");
-    }
-
-    /* Alloc one element */
-    ID = &IfStack[IfCount++];
-
-    /* Initialize elements */
-    ID->Flags     = NeedTerm? ifNeedTerm : ifNone;
-    ID->LineInfos = EmptyCollection;
-    GetFullLineInfo (&ID->LineInfos, 0);
-    ID->Name      = Directive;
-
-    /* Return the result */
-    return ID;
-}
-
-
-
 static IfDesc* GetCurrentIf (void)
 /* Return the current .IF descriptor */
 {
@@ -124,35 +100,23 @@ static IfDesc* GetCurrentIf (void)
 
 
 
-static void FreeIf (void)
-/* Free all .IF descriptors until we reach one with the NeedTerm bit set */
+static int GetOverallIfCond (void)
+/* Get the overall condition based on all conditions on the stack. */
 {
-    int Done;
-    do {
-               IfDesc* ID = GetCurrentIf();
-               if (ID == 0) {
-                   Error (" Unexpected .ENDIF");
-           Done = 1;
-               } else {
-                   Done = (ID->Flags & ifNeedTerm) != 0;
-            --IfCount;
-               }
-    } while (!Done);
+    /* Since the last entry contains the overall condition of the parent, we
+     * must check it in combination of the current condition. If there is no
+     * last entry, the overall condition is true.
+     */
+    return (IfCount == 0) ||
+           ((IfStack[IfCount-1].Flags & (ifCond | ifParentCond)) == (ifCond | ifParentCond));
 }
 
 
 
 static void CalcOverallIfCond (void)
-/* Caclulate the overall condition based on all conditions on the stack */
+/* Caclulate the overall condition based on all conditions on the stack. */
 {
-    unsigned Count;
-    IfCond = 1;
-    for (Count = 0; Count < IfCount; ++Count) {
-               if ((IfStack[Count].Flags & ifCond) == 0) {
-            IfCond = 0;
-                   break;
-               }
-    }
+    IfCond = GetOverallIfCond ();
 }
 
 
@@ -191,6 +155,56 @@ static void ElseClause (IfDesc* ID, const char* Directive)
 
 
 
+static IfDesc* AllocIf (const char* Directive, int NeedTerm)
+/* Alloc a new element from the .IF stack */
+{
+    IfDesc* ID;
+
+    /* Check for stack overflow */
+    if (IfCount >= MAX_IFS) {
+               Fatal ("Too many nested .IFs");
+    }
+
+    /* Get the next element */
+    ID = &IfStack[IfCount];
+
+    /* Initialize elements */
+    ID->Flags = NeedTerm? ifNeedTerm : ifNone;
+    if (GetOverallIfCond ()) {
+        /* The parents .IF condition is true */
+        ID->Flags |= ifParentCond;
+    }
+    ID->LineInfos = EmptyCollection;
+    GetFullLineInfo (&ID->LineInfos, 0);
+    ID->Name = Directive;
+
+    /* One more slot allocated */
+    ++IfCount;
+
+    /* Return the result */
+    return ID;
+}
+
+
+
+static void FreeIf (void)
+/* Free all .IF descriptors until we reach one with the NeedTerm bit set */
+{
+    int Done;
+    do {
+               IfDesc* ID = GetCurrentIf();
+               if (ID == 0) {
+                   Error (" Unexpected .ENDIF");
+           Done = 1;
+               } else {
+                   Done = (ID->Flags & ifNeedTerm) != 0;
+            --IfCount;
+               }
+    } while (!Done);
+}
+
+
+
 /*****************************************************************************/
 /*                                          Code                                    */
 /*****************************************************************************/
@@ -213,8 +227,10 @@ void DoConditionals (void)
                 ElseClause (D, ".ELSE");
 
                 /* Remember the data for the .ELSE */
-                GetFullLineInfo (&D->LineInfos, 0);
-                D->Name = ".ELSE";
+                if (D) {
+                    GetFullLineInfo (&D->LineInfos, 0);
+                    D->Name = ".ELSE";
+                }
 
                 /* Calculate the new overall condition */
                 CalcOverallIfCond ();
@@ -229,6 +245,9 @@ void DoConditionals (void)
                 /* Handle as if there was an .ELSE first */
                 ElseClause (D, ".ELSEIF");
 
+                /* Calculate the new overall if condition */
+                CalcOverallIfCond ();
+
                 /* Allocate and prepare a new descriptor */
                 D = AllocIf (".ELSEIF", 0);
                 NextTok ();
@@ -237,7 +256,7 @@ void DoConditionals (void)
                  * branch. This way we won't get any errors about undefined
                  * symbols or similar...
                  */
-                if (IfCond == 0) {
+                if (IfCond) {
                     SetIfCond (D, ConstExpression ());
                     ExpectSep ();
                 }