/* Set of bitmapped flags for the if descriptor */
enum {
- ifNone = 0x0000, /* No flag */
- ifCond = 0x0001, /* IF condition was true */
- ifElse = 0x0002, /* We had a .ELSE branch */
- ifNeedTerm = 0x0004 /* Need .ENDIF termination */
+ ifNone = 0x0000, /* No flag */
+ ifCond = 0x0001, /* IF condition was true */
+ ifElse = 0x0002, /* We had a .ELSE branch */
+ ifNeedTerm = 0x0004, /* Need .ENDIF termination */
};
+/* The overall .IF condition */
+int IfCond = 1;
+
/*****************************************************************************/
-/* struct IfDesc */
+/* struct IfDesc */
/*****************************************************************************/
}
/* Alloc one element */
- ID = &IfStack [IfCount++];
+ ID = &IfStack[IfCount++];
/* Initialize elements */
ID->Flags = NeedTerm? ifNeedTerm : ifNone;
if (IfCount == 0) {
return 0;
} else {
- return &IfStack [IfCount-1];
+ return &IfStack[IfCount-1];
}
}
{
int Done;
do {
- IfDesc* D = GetCurrentIf();
- if (D == 0) {
+ IfDesc* ID = GetCurrentIf();
+ if (ID == 0) {
Error (" Unexpected .ENDIF");
Done = 1;
} else {
- Done = (D->Flags & ifNeedTerm) != 0;
+ Done = (ID->Flags & ifNeedTerm) != 0;
--IfCount;
}
} while (!Done);
-static int GetCurrentIfCond (void)
-/* Return the current condition based on all conditions on the stack */
+static void CalcOverallIfCond (void)
+/* 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) {
- return 0;
+ IfCond = 0;
+ break;
}
}
- return 1;
}
-static void InvertIfCond (IfDesc* ID)
-/* Invert the current condition */
-{
- ID->Flags ^= ifCond;
-}
-
-
-
-static int GetElse (const IfDesc* ID)
-/* Return true if we had a .ELSE */
+static void ElseClause (IfDesc* ID, const char* Directive)
+/* Enter an .ELSE clause */
{
- return (ID->Flags & ifElse) != 0;
-}
-
-
+ /* Check if we have an open .IF - otherwise .ELSE is not allowed */
+ if (ID == 0) {
+ Error ("Unexpected %s", Directive);
+ return;
+ }
-static void SetElse (IfDesc* ID, int E)
-/* Set the .ELSE flag */
-{
- if (E) {
- ID->Flags |= ifElse;
- } else {
- ID->Flags &= ~ifElse;
+ /* Check for a duplicate else, then remember that we had one */
+ if (ID->Flags & ifElse) {
+ /* We already had a .ELSE ! */
+ Error ("Duplicate .ELSE");
}
+ ID->Flags |= ifElse;
+
+ /* Condition is inverted now */
+ ID->Flags ^= ifCond;
}
{
IfDesc* D;
- int IfCond = GetCurrentIfCond ();
do {
switch (CurTok.Tok) {
case TOK_ELSE:
D = GetCurrentIf ();
- if (D == 0) {
- Error ("Unexpected .ELSE");
- } else if (GetElse(D)) {
- /* We already had a .ELSE ! */
- Error ("Duplicate .ELSE");
- } else {
- /* Allow an .ELSE */
- InvertIfCond (D);
- SetElse (D, 1);
- GetFullLineInfo (&D->LineInfos, 0);
- D->Name = ".ELSE";
- IfCond = GetCurrentIfCond ();
- }
+
+ /* Allow an .ELSE */
+ ElseClause (D, ".ELSE");
+
+ /* Remember the data for the .ELSE */
+ GetFullLineInfo (&D->LineInfos, 0);
+ D->Name = ".ELSE";
+
+ /* Calculate the new overall condition */
+ CalcOverallIfCond ();
+
+ /* Skip .ELSE */
NextTok ();
- ExpectSep ();
+ ExpectSep ();
break;
case TOK_ELSEIF:
D = GetCurrentIf ();
- if (D == 0) {
- Error ("Unexpected .ELSEIF");
- } else if (GetElse(D)) {
- /* We already had a .ELSE */
- Error ("Duplicate .ELSE");
- } else {
- /* Handle as if there was an .ELSE first */
- InvertIfCond (D);
- SetElse (D, 1);
-
- /* Allocate and prepare a new descriptor */
- D = AllocIf (".ELSEIF", 0);
- NextTok ();
-
- /* Ignore the new condition if we are inside a false .ELSE
- * branch. This way we won't get any errors about undefined
- * symbols or similar...
- */
- if (IfCond == 0) {
- SetIfCond (D, ConstExpression ());
- ExpectSep ();
- }
-
- /* Get the new overall condition */
- IfCond = GetCurrentIfCond ();
- }
- break;
-
- case TOK_ENDIF:
- /* We're done with this .IF.. - remove the descriptor(s) */
- FreeIf ();
-
- /* Be sure not to read the next token until the .IF stack
- * has been cleanup up, since we may be at end of file.
- */
- NextTok ();
- ExpectSep ();
-
- /* Get the new overall condition */
- IfCond = GetCurrentIfCond ();
- break;
+ /* Handle as if there was an .ELSE first */
+ ElseClause (D, ".ELSEIF");
+
+ /* Allocate and prepare a new descriptor */
+ D = AllocIf (".ELSEIF", 0);
+ NextTok ();
+
+ /* Ignore the new condition if we are inside a false .ELSE
+ * branch. This way we won't get any errors about undefined
+ * symbols or similar...
+ */
+ if (IfCond == 0) {
+ SetIfCond (D, ConstExpression ());
+ ExpectSep ();
+ }
+
+ /* Get the new overall condition */
+ CalcOverallIfCond ();
+ break;
+
+ case TOK_ENDIF:
+ /* We're done with this .IF.. - remove the descriptor(s) */
+ FreeIf ();
+
+ /* Be sure not to read the next token until the .IF stack
+ * has been cleanup up, since we may be at end of file.
+ */
+ NextTok ();
+ ExpectSep ();
+
+ /* Get the new overall condition */
+ CalcOverallIfCond ();
+ break;
case TOK_IF:
D = AllocIf (".IF", 1);
NextTok ();
if (IfCond) {
- SetIfCond (D, ConstExpression ());
- ExpectSep ();
+ SetIfCond (D, ConstExpression ());
+ ExpectSep ();
}
- IfCond = GetCurrentIfCond ();
+ CalcOverallIfCond ();
break;
case TOK_IFBLANK:
SkipUntilSep ();
}
}
- IfCond = GetCurrentIfCond ();
+ CalcOverallIfCond ();
break;
case TOK_IFCONST:
FreeExpr (Expr);
ExpectSep ();
}
- IfCond = GetCurrentIfCond ();
+ CalcOverallIfCond ();
break;
case TOK_IFDEF:
SymEntry* Sym = ParseAnySymName (SYM_FIND_EXISTING);
SetIfCond (D, Sym != 0 && SymIsDef (Sym));
}
- IfCond = GetCurrentIfCond ();
+ CalcOverallIfCond ();
break;
case TOK_IFNBLANK:
SkipUntilSep ();
}
}
- IfCond = GetCurrentIfCond ();
+ CalcOverallIfCond ();
break;
case TOK_IFNCONST:
FreeExpr (Expr);
ExpectSep ();
}
- IfCond = GetCurrentIfCond ();
+ CalcOverallIfCond ();
break;
case TOK_IFNDEF:
SetIfCond (D, Sym == 0 || !SymIsDef (Sym));
ExpectSep ();
}
- IfCond = GetCurrentIfCond ();
+ CalcOverallIfCond ();
break;
case TOK_IFNREF:
SetIfCond (D, Sym == 0 || !SymIsRef (Sym));
ExpectSep ();
}
- IfCond = GetCurrentIfCond ();
+ CalcOverallIfCond ();
break;
case TOK_IFP02:
if (IfCond) {
SetIfCond (D, GetCPU() == CPU_6502);
}
- IfCond = GetCurrentIfCond ();
ExpectSep ();
+ CalcOverallIfCond ();
break;
case TOK_IFP816:
if (IfCond) {
SetIfCond (D, GetCPU() == CPU_65816);
}
- IfCond = GetCurrentIfCond ();
ExpectSep ();
+ CalcOverallIfCond ();
break;
case TOK_IFPC02:
if (IfCond) {
SetIfCond (D, GetCPU() == CPU_65C02);
}
- IfCond = GetCurrentIfCond ();
ExpectSep ();
+ CalcOverallIfCond ();
break;
case TOK_IFPSC02:
if (IfCond) {
SetIfCond (D, GetCPU() == CPU_65SC02);
}
- IfCond = GetCurrentIfCond ();
ExpectSep ();
+ CalcOverallIfCond ();
break;
case TOK_IFREF:
SetIfCond (D, Sym != 0 && SymIsRef (Sym));
ExpectSep ();
}
- IfCond = GetCurrentIfCond ();
+ CalcOverallIfCond ();
break;
default:
LIError (&D->LineInfos, "Conditional assembly branch was never closed");
FreeIf ();
}
+
+ /* Calculate the new overall .IF condition */
+ CalcOverallIfCond ();
}
while (IfCount > SP) {
FreeIf ();
}
+
+ /* Calculate the new overall .IF condition */
+ CalcOverallIfCond ();
}