mirror of
https://github.com/cc65/cc65.git
synced 2024-12-26 08:32:00 +00:00
Fix a problem with conditional assembly: The scanner has to be switched into
raw token mode when skipping a section of input because otherwise pseudo functions may trigger errors. git-svn-id: svn://svn.cc65.org/cc65/trunk@5033 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
6a56201046
commit
6a48359d23
@ -56,16 +56,19 @@
|
|||||||
|
|
||||||
/* Set of bitmapped flags for the if descriptor */
|
/* Set of bitmapped flags for the if descriptor */
|
||||||
enum {
|
enum {
|
||||||
ifNone = 0x0000, /* No flag */
|
ifNone = 0x0000, /* No flag */
|
||||||
ifCond = 0x0001, /* IF condition was true */
|
ifCond = 0x0001, /* IF condition was true */
|
||||||
ifElse = 0x0002, /* We had a .ELSE branch */
|
ifElse = 0x0002, /* We had a .ELSE branch */
|
||||||
ifNeedTerm = 0x0004 /* Need .ENDIF termination */
|
ifNeedTerm = 0x0004, /* Need .ENDIF termination */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* The overall .IF condition */
|
||||||
|
int IfCond = 1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* struct IfDesc */
|
/* struct IfDesc */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
@ -95,7 +98,7 @@ static IfDesc* AllocIf (const char* Directive, int NeedTerm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Alloc one element */
|
/* Alloc one element */
|
||||||
ID = &IfStack [IfCount++];
|
ID = &IfStack[IfCount++];
|
||||||
|
|
||||||
/* Initialize elements */
|
/* Initialize elements */
|
||||||
ID->Flags = NeedTerm? ifNeedTerm : ifNone;
|
ID->Flags = NeedTerm? ifNeedTerm : ifNone;
|
||||||
@ -115,7 +118,7 @@ static IfDesc* GetCurrentIf (void)
|
|||||||
if (IfCount == 0) {
|
if (IfCount == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return &IfStack [IfCount-1];
|
return &IfStack[IfCount-1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,12 +129,12 @@ static void FreeIf (void)
|
|||||||
{
|
{
|
||||||
int Done;
|
int Done;
|
||||||
do {
|
do {
|
||||||
IfDesc* D = GetCurrentIf();
|
IfDesc* ID = GetCurrentIf();
|
||||||
if (D == 0) {
|
if (ID == 0) {
|
||||||
Error (" Unexpected .ENDIF");
|
Error (" Unexpected .ENDIF");
|
||||||
Done = 1;
|
Done = 1;
|
||||||
} else {
|
} else {
|
||||||
Done = (D->Flags & ifNeedTerm) != 0;
|
Done = (ID->Flags & ifNeedTerm) != 0;
|
||||||
--IfCount;
|
--IfCount;
|
||||||
}
|
}
|
||||||
} while (!Done);
|
} while (!Done);
|
||||||
@ -139,16 +142,17 @@ static void FreeIf (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int GetCurrentIfCond (void)
|
static void CalcOverallIfCond (void)
|
||||||
/* Return the current condition based on all conditions on the stack */
|
/* Caclulate the overall condition based on all conditions on the stack */
|
||||||
{
|
{
|
||||||
unsigned Count;
|
unsigned Count;
|
||||||
|
IfCond = 1;
|
||||||
for (Count = 0; Count < IfCount; ++Count) {
|
for (Count = 0; Count < IfCount; ++Count) {
|
||||||
if ((IfStack[Count].Flags & ifCond) == 0) {
|
if ((IfStack[Count].Flags & ifCond) == 0) {
|
||||||
return 0;
|
IfCond = 0;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -165,30 +169,24 @@ static void SetIfCond (IfDesc* ID, int C)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void InvertIfCond (IfDesc* ID)
|
static void ElseClause (IfDesc* ID, const char* Directive)
|
||||||
/* Invert the current condition */
|
/* Enter an .ELSE clause */
|
||||||
{
|
{
|
||||||
ID->Flags ^= ifCond;
|
/* Check if we have an open .IF - otherwise .ELSE is not allowed */
|
||||||
}
|
if (ID == 0) {
|
||||||
|
Error ("Unexpected %s", Directive);
|
||||||
|
return;
|
||||||
|
|
||||||
static int GetElse (const IfDesc* ID)
|
|
||||||
/* Return true if we had a .ELSE */
|
|
||||||
{
|
|
||||||
return (ID->Flags & ifElse) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -204,82 +202,72 @@ void DoConditionals (void)
|
|||||||
{
|
{
|
||||||
IfDesc* D;
|
IfDesc* D;
|
||||||
|
|
||||||
int IfCond = GetCurrentIfCond ();
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
switch (CurTok.Tok) {
|
switch (CurTok.Tok) {
|
||||||
|
|
||||||
case TOK_ELSE:
|
case TOK_ELSE:
|
||||||
D = GetCurrentIf ();
|
D = GetCurrentIf ();
|
||||||
if (D == 0) {
|
|
||||||
Error ("Unexpected .ELSE");
|
/* Allow an .ELSE */
|
||||||
} else if (GetElse(D)) {
|
ElseClause (D, ".ELSE");
|
||||||
/* We already had a .ELSE ! */
|
|
||||||
Error ("Duplicate .ELSE");
|
/* Remember the data for the .ELSE */
|
||||||
} else {
|
GetFullLineInfo (&D->LineInfos, 0);
|
||||||
/* Allow an .ELSE */
|
D->Name = ".ELSE";
|
||||||
InvertIfCond (D);
|
|
||||||
SetElse (D, 1);
|
/* Calculate the new overall condition */
|
||||||
GetFullLineInfo (&D->LineInfos, 0);
|
CalcOverallIfCond ();
|
||||||
D->Name = ".ELSE";
|
|
||||||
IfCond = GetCurrentIfCond ();
|
/* Skip .ELSE */
|
||||||
}
|
|
||||||
NextTok ();
|
NextTok ();
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_ELSEIF:
|
case TOK_ELSEIF:
|
||||||
D = GetCurrentIf ();
|
D = GetCurrentIf ();
|
||||||
if (D == 0) {
|
/* Handle as if there was an .ELSE first */
|
||||||
Error ("Unexpected .ELSEIF");
|
ElseClause (D, ".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 */
|
/* Allocate and prepare a new descriptor */
|
||||||
D = AllocIf (".ELSEIF", 0);
|
D = AllocIf (".ELSEIF", 0);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
|
|
||||||
/* Ignore the new condition if we are inside a false .ELSE
|
/* Ignore the new condition if we are inside a false .ELSE
|
||||||
* branch. This way we won't get any errors about undefined
|
* branch. This way we won't get any errors about undefined
|
||||||
* symbols or similar...
|
* symbols or similar...
|
||||||
*/
|
*/
|
||||||
if (IfCond == 0) {
|
if (IfCond == 0) {
|
||||||
SetIfCond (D, ConstExpression ());
|
SetIfCond (D, ConstExpression ());
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the new overall condition */
|
/* Get the new overall condition */
|
||||||
IfCond = GetCurrentIfCond ();
|
CalcOverallIfCond ();
|
||||||
}
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case TOK_ENDIF:
|
case TOK_ENDIF:
|
||||||
/* We're done with this .IF.. - remove the descriptor(s) */
|
/* We're done with this .IF.. - remove the descriptor(s) */
|
||||||
FreeIf ();
|
FreeIf ();
|
||||||
|
|
||||||
/* Be sure not to read the next token until the .IF stack
|
/* Be sure not to read the next token until the .IF stack
|
||||||
* has been cleanup up, since we may be at end of file.
|
* has been cleanup up, since we may be at end of file.
|
||||||
*/
|
*/
|
||||||
NextTok ();
|
NextTok ();
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
|
|
||||||
/* Get the new overall condition */
|
/* Get the new overall condition */
|
||||||
IfCond = GetCurrentIfCond ();
|
CalcOverallIfCond ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_IF:
|
case TOK_IF:
|
||||||
D = AllocIf (".IF", 1);
|
D = AllocIf (".IF", 1);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
if (IfCond) {
|
if (IfCond) {
|
||||||
SetIfCond (D, ConstExpression ());
|
SetIfCond (D, ConstExpression ());
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
}
|
}
|
||||||
IfCond = GetCurrentIfCond ();
|
CalcOverallIfCond ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_IFBLANK:
|
case TOK_IFBLANK:
|
||||||
@ -293,7 +281,7 @@ void DoConditionals (void)
|
|||||||
SkipUntilSep ();
|
SkipUntilSep ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IfCond = GetCurrentIfCond ();
|
CalcOverallIfCond ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_IFCONST:
|
case TOK_IFCONST:
|
||||||
@ -305,7 +293,7 @@ void DoConditionals (void)
|
|||||||
FreeExpr (Expr);
|
FreeExpr (Expr);
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
}
|
}
|
||||||
IfCond = GetCurrentIfCond ();
|
CalcOverallIfCond ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_IFDEF:
|
case TOK_IFDEF:
|
||||||
@ -315,7 +303,7 @@ void DoConditionals (void)
|
|||||||
SymEntry* Sym = ParseAnySymName (SYM_FIND_EXISTING);
|
SymEntry* Sym = ParseAnySymName (SYM_FIND_EXISTING);
|
||||||
SetIfCond (D, Sym != 0 && SymIsDef (Sym));
|
SetIfCond (D, Sym != 0 && SymIsDef (Sym));
|
||||||
}
|
}
|
||||||
IfCond = GetCurrentIfCond ();
|
CalcOverallIfCond ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_IFNBLANK:
|
case TOK_IFNBLANK:
|
||||||
@ -329,7 +317,7 @@ void DoConditionals (void)
|
|||||||
SkipUntilSep ();
|
SkipUntilSep ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IfCond = GetCurrentIfCond ();
|
CalcOverallIfCond ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_IFNCONST:
|
case TOK_IFNCONST:
|
||||||
@ -341,7 +329,7 @@ void DoConditionals (void)
|
|||||||
FreeExpr (Expr);
|
FreeExpr (Expr);
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
}
|
}
|
||||||
IfCond = GetCurrentIfCond ();
|
CalcOverallIfCond ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_IFNDEF:
|
case TOK_IFNDEF:
|
||||||
@ -352,7 +340,7 @@ void DoConditionals (void)
|
|||||||
SetIfCond (D, Sym == 0 || !SymIsDef (Sym));
|
SetIfCond (D, Sym == 0 || !SymIsDef (Sym));
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
}
|
}
|
||||||
IfCond = GetCurrentIfCond ();
|
CalcOverallIfCond ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_IFNREF:
|
case TOK_IFNREF:
|
||||||
@ -363,7 +351,7 @@ void DoConditionals (void)
|
|||||||
SetIfCond (D, Sym == 0 || !SymIsRef (Sym));
|
SetIfCond (D, Sym == 0 || !SymIsRef (Sym));
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
}
|
}
|
||||||
IfCond = GetCurrentIfCond ();
|
CalcOverallIfCond ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_IFP02:
|
case TOK_IFP02:
|
||||||
@ -372,8 +360,8 @@ void DoConditionals (void)
|
|||||||
if (IfCond) {
|
if (IfCond) {
|
||||||
SetIfCond (D, GetCPU() == CPU_6502);
|
SetIfCond (D, GetCPU() == CPU_6502);
|
||||||
}
|
}
|
||||||
IfCond = GetCurrentIfCond ();
|
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
|
CalcOverallIfCond ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_IFP816:
|
case TOK_IFP816:
|
||||||
@ -382,8 +370,8 @@ void DoConditionals (void)
|
|||||||
if (IfCond) {
|
if (IfCond) {
|
||||||
SetIfCond (D, GetCPU() == CPU_65816);
|
SetIfCond (D, GetCPU() == CPU_65816);
|
||||||
}
|
}
|
||||||
IfCond = GetCurrentIfCond ();
|
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
|
CalcOverallIfCond ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_IFPC02:
|
case TOK_IFPC02:
|
||||||
@ -392,8 +380,8 @@ void DoConditionals (void)
|
|||||||
if (IfCond) {
|
if (IfCond) {
|
||||||
SetIfCond (D, GetCPU() == CPU_65C02);
|
SetIfCond (D, GetCPU() == CPU_65C02);
|
||||||
}
|
}
|
||||||
IfCond = GetCurrentIfCond ();
|
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
|
CalcOverallIfCond ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_IFPSC02:
|
case TOK_IFPSC02:
|
||||||
@ -402,8 +390,8 @@ void DoConditionals (void)
|
|||||||
if (IfCond) {
|
if (IfCond) {
|
||||||
SetIfCond (D, GetCPU() == CPU_65SC02);
|
SetIfCond (D, GetCPU() == CPU_65SC02);
|
||||||
}
|
}
|
||||||
IfCond = GetCurrentIfCond ();
|
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
|
CalcOverallIfCond ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_IFREF:
|
case TOK_IFREF:
|
||||||
@ -414,7 +402,7 @@ void DoConditionals (void)
|
|||||||
SetIfCond (D, Sym != 0 && SymIsRef (Sym));
|
SetIfCond (D, Sym != 0 && SymIsRef (Sym));
|
||||||
ExpectSep ();
|
ExpectSep ();
|
||||||
}
|
}
|
||||||
IfCond = GetCurrentIfCond ();
|
CalcOverallIfCond ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -488,6 +476,9 @@ void CheckOpenIfs (void)
|
|||||||
LIError (&D->LineInfos, "Conditional assembly branch was never closed");
|
LIError (&D->LineInfos, "Conditional assembly branch was never closed");
|
||||||
FreeIf ();
|
FreeIf ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Calculate the new overall .IF condition */
|
||||||
|
CalcOverallIfCond ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -506,6 +497,9 @@ void CleanupIfStack (unsigned SP)
|
|||||||
while (IfCount > SP) {
|
while (IfCount > SP) {
|
||||||
FreeIf ();
|
FreeIf ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Calculate the new overall .IF condition */
|
||||||
|
CalcOverallIfCond ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,10 +6,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2003 Ullrich von Bassewitz */
|
/* (C) 2000-2011, Ullrich von Bassewitz */
|
||||||
/* Römerstraße 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@ -38,6 +38,17 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Data */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* The overall .IF condition */
|
||||||
|
extern int IfCond;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
#include "strbuf.h"
|
#include "strbuf.h"
|
||||||
|
|
||||||
/* ca65 */
|
/* ca65 */
|
||||||
|
#include "condasm.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
@ -661,8 +662,10 @@ void NextTok (void)
|
|||||||
/* Get the next raw token */
|
/* Get the next raw token */
|
||||||
NextRawTok ();
|
NextRawTok ();
|
||||||
|
|
||||||
/* In raw mode, pass the token unchanged */
|
/* In raw mode, or when output is suppressed via conditional assembly,
|
||||||
if (RawMode == 0) {
|
* pass the token unchanged.
|
||||||
|
*/
|
||||||
|
if (RawMode == 0 && IfCond) {
|
||||||
|
|
||||||
/* Execute token handling functions */
|
/* Execute token handling functions */
|
||||||
switch (CurTok.Tok) {
|
switch (CurTok.Tok) {
|
||||||
|
Loading…
Reference in New Issue
Block a user