1
0
mirror of https://github.com/cc65/cc65.git synced 2024-07-05 21:29:03 +00:00

First implementation of .UNDEF for deleting a macro.

git-svn-id: svn://svn.cc65.org/cc65/trunk@5049 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz 2011-06-11 22:18:48 +00:00
parent 279ad05150
commit eaa45269e7
5 changed files with 163 additions and 69 deletions

View File

@ -106,9 +106,10 @@ struct Macro {
unsigned TokCount; /* Number of tokens for this macro */ unsigned TokCount; /* Number of tokens for this macro */
TokNode* TokRoot; /* Root of token list */ TokNode* TokRoot; /* Root of token list */
TokNode* TokLast; /* Pointer to last token in list */ TokNode* TokLast; /* Pointer to last token in list */
StrBuf Name; /* Macro name, dynamically allocated */
unsigned Expansions; /* Number of active macro expansions */
unsigned char Style; /* Macro style */ unsigned char Style; /* Macro style */
unsigned char Incomplete; /* Macro is currently built */ unsigned char Incomplete; /* Macro is currently built */
StrBuf Name; /* Macro name, dynamically allocated */
}; };
/* Hash table functions */ /* Hash table functions */
@ -122,9 +123,6 @@ static const HashFunctions HashFunc = {
/* Macro hash table */ /* Macro hash table */
static HashTable MacroTab = STATIC_HASHTABLE_INITIALIZER (117, &HashFunc); static HashTable MacroTab = STATIC_HASHTABLE_INITIALIZER (117, &HashFunc);
/* Global macro data */
static Macro* MacroRoot = 0; /* List of all macros */
/* Structs that holds data for a macro expansion */ /* Structs that holds data for a macro expansion */
typedef struct MacExp MacExp; typedef struct MacExp MacExp;
struct MacExp { struct MacExp {
@ -152,6 +150,9 @@ static int DoMacAbort = 0;
/* Counter to create local names for symbols */ /* Counter to create local names for symbols */
static unsigned LocalName = 0; static unsigned LocalName = 0;
/* Define style macros disabled if != 0 */
static unsigned DisableDefines = 0;
/*****************************************************************************/ /*****************************************************************************/
@ -233,14 +234,11 @@ static Macro* NewMacro (const StrBuf* Name, unsigned char Style)
M->TokCount = 0; M->TokCount = 0;
M->TokRoot = 0; M->TokRoot = 0;
M->TokLast = 0; M->TokLast = 0;
M->Style = Style;
M->Incomplete = 1;
SB_Init (&M->Name); SB_Init (&M->Name);
SB_Copy (&M->Name, Name); SB_Copy (&M->Name, Name);
M->Expansions = 0;
/* Insert the macro into the global macro list */ M->Style = Style;
M->List = MacroRoot; M->Incomplete = 1;
MacroRoot = M;
/* Insert the macro into the hash table */ /* Insert the macro into the hash table */
HT_Insert (&MacroTab, &M->Node); HT_Insert (&MacroTab, &M->Node);
@ -268,12 +266,15 @@ static MacExp* NewMacExp (Macro* M)
LocalName += M->LocalCount; LocalName += M->LocalCount;
E->ParamCount = 0; E->ParamCount = 0;
E->Params = xmalloc (M->ParamCount * sizeof (TokNode*)); E->Params = xmalloc (M->ParamCount * sizeof (TokNode*));
E->ParamExp = 0;
for (I = 0; I < M->ParamCount; ++I) { for (I = 0; I < M->ParamCount; ++I) {
E->Params[I] = 0; E->Params[I] = 0;
} }
E->ParamExp = 0;
E->LISlot = AllocLineInfoSlot (LI_TYPE_MACRO, MacExpansions); E->LISlot = AllocLineInfoSlot (LI_TYPE_MACRO, MacExpansions);
/* Mark the macro as expanding */
++M->Expansions;
/* One macro expansion more */ /* One macro expansion more */
++MacExpansions; ++MacExpansions;
@ -291,6 +292,9 @@ static void FreeMacExp (MacExp* E)
/* One macro expansion less */ /* One macro expansion less */
--MacExpansions; --MacExpansions;
/* No longer expanding this macro */
--E->M->Expansions;
/* Free the parameter lists */ /* Free the parameter lists */
for (I = 0; I < E->ParamCount; ++I) { for (I = 0; I < E->ParamCount; ++I) {
/* Free one parameter list */ /* Free one parameter list */
@ -548,6 +552,28 @@ Done:
void MacUndef (const StrBuf* Name)
/* Undefine the macro with the given name. */
{
/* Search for the macro */
Macro* M = HT_FindEntry (&MacroTab, Name);
/* Don't let the user kid with us */
if (M == 0) {
Error ("No such macro: %m%p", Name);
return;
}
if (M->Expansions > 0) {
Error ("Cannot delete a macro that is currently expanded");
return;
}
/* Remove the macro from the macro table */
HT_RemoveEntry (&MacroTab, M);
}
static int MacExpand (void* Data) static int MacExpand (void* Data)
/* If we're currently expanding a macro, set the the scanner token and /* If we're currently expanding a macro, set the the scanner token and
* attribute to the next value and return true. If we are not expanding * attribute to the next value and return true. If we are not expanding
@ -678,19 +704,11 @@ MacEnd:
static void StartExpClassic (Macro* M) static void StartExpClassic (MacExp* E)
/* Start expanding the classic macro M */ /* Start expanding a classic macro */
{ {
MacExp* E;
token_t Term; token_t Term;
/* Create a structure holding expansion data. This must be done before
* skipping the macro name, because the call to NextTok may cause a new
* expansion if the next token is actually a .define style macro.
*/
E = NewMacExp (M);
/* Skip the macro name */ /* Skip the macro name */
NextTok (); NextTok ();
@ -700,7 +718,7 @@ static void StartExpClassic (Macro* M)
TokNode* Last; TokNode* Last;
/* Check for maximum parameter count */ /* Check for maximum parameter count */
if (E->ParamCount >= M->ParamCount) { if (E->ParamCount >= E->M->ParamCount) {
ErrorSkip ("Too many macro parameters"); ErrorSkip ("Too many macro parameters");
break; break;
} }
@ -767,16 +785,13 @@ static void StartExpClassic (Macro* M)
static void StartExpDefine (Macro* M) static void StartExpDefine (MacExp* E)
/* Start expanding a DEFINE style macro */ /* Start expanding a DEFINE style macro */
{ {
/* Create a structure holding expansion data */
MacExp* E = NewMacExp (M);
/* A define style macro must be called with as many actual parameters /* A define style macro must be called with as many actual parameters
* as there are formal ones. Get the parameter count. * as there are formal ones. Get the parameter count.
*/ */
unsigned Count = M->ParamCount; unsigned Count = E->M->ParamCount;
/* Skip the current token */ /* Skip the current token */
NextTok (); NextTok ();
@ -858,9 +873,11 @@ static void StartExpDefine (Macro* M)
void MacExpandStart (void) void MacExpandStart (void)
/* Start expanding the macro in SVal */ /* Start expanding the macro in SVal */
{ {
MacExp* E;
/* Search for the macro */ /* Search for the macro */
Macro* M = HT_FindEntry (&MacroTab, &CurTok.SVal); Macro* M = HT_FindEntry (&MacroTab, &CurTok.SVal);
CHECK (M != 0); CHECK (M != 0 && (M->Style != MAC_STYLE_DEFINE || DisableDefines == 0));
/* We cannot expand an incomplete macro */ /* We cannot expand an incomplete macro */
if (M->Incomplete) { if (M->Incomplete) {
@ -876,10 +893,13 @@ void MacExpandStart (void)
return; return;
} }
/* Create a structure holding expansion data */
E = NewMacExp (M);
/* Call the apropriate subroutine */ /* Call the apropriate subroutine */
switch (M->Style) { switch (M->Style) {
case MAC_STYLE_CLASSIC: StartExpClassic (M); break; case MAC_STYLE_CLASSIC: StartExpClassic (E); break;
case MAC_STYLE_DEFINE: StartExpDefine (M); break; case MAC_STYLE_DEFINE: StartExpDefine (E); break;
default: Internal ("Invalid macro style: %d", M->Style); default: Internal ("Invalid macro style: %d", M->Style);
} }
} }
@ -909,7 +929,15 @@ int IsMacro (const StrBuf* Name)
int IsDefine (const StrBuf* Name) int IsDefine (const StrBuf* Name)
/* Return true if the given name is the name of a define style macro */ /* Return true if the given name is the name of a define style macro */
{ {
Macro* M = HT_FindEntry (&MacroTab, Name); Macro* M;
/* Never if disabled */
if (DisableDefines) {
return 0;
}
/* Check if we have such a macro */
M = HT_FindEntry (&MacroTab, Name);
return (M != 0 && M->Style == MAC_STYLE_DEFINE); return (M != 0 && M->Style == MAC_STYLE_DEFINE);
} }
@ -923,4 +951,22 @@ int InMacExpansion (void)
void DisableDefineStyleMacros (void)
/* Disable define style macros until EnableDefineStyleMacros is called */
{
++DisableDefines;
}
void EnableDefineStyleMacros (void)
/* Re-enable define style macros previously disabled with
* DisableDefineStyleMacros.
*/
{
PRECONDITION (DisableDefines > 0);
--DisableDefines;
}

View File

@ -6,7 +6,7 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2008 Ullrich von Bassewitz */ /* (C) 1998-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
@ -38,6 +38,16 @@
/*****************************************************************************/
/* Forwards */
/*****************************************************************************/
struct StrBuf;
/*****************************************************************************/ /*****************************************************************************/
/* Data */ /* Data */
/*****************************************************************************/ /*****************************************************************************/
@ -59,6 +69,9 @@
void MacDef (unsigned Style); void MacDef (unsigned Style);
/* Parse a macro definition */ /* Parse a macro definition */
void MacUndef (const struct StrBuf* Name);
/* Undefine the macro with the given name. */
void MacExpandStart (void); void MacExpandStart (void);
/* Start expanding the macro in SVal */ /* Start expanding the macro in SVal */
@ -74,6 +87,14 @@ int IsDefine (const StrBuf* Name);
int InMacExpansion (void); int InMacExpansion (void);
/* Return true if we're currently expanding a macro */ /* Return true if we're currently expanding a macro */
void DisableDefineStyleMacros (void);
/* Disable define style macros until EnableDefineStyleMacros is called */
void EnableDefineStyleMacros (void);
/* Re-enable define style macros previously disabled with
* DisableDefineStyleMacros.
*/
/* End of macro.h */ /* End of macro.h */

View File

@ -1778,6 +1778,29 @@ static void DoTag (void)
static void DoUnDef (void)
/* Undefine a macro */
{
/* The function is called with the .UNDEF token in place, because we need
* to disable .define macro expansions before reading the next token.
* Otherwise the name of the macro would be expanded, so we would never
* see it.
*/
DisableDefineStyleMacros ();
NextTok ();
EnableDefineStyleMacros ();
/* We expect an identifier */
if (CurTok.Tok != TOK_IDENT) {
ErrorSkip ("Identifier expected");
} else {
MacUndef (&CurTok.SVal);
NextTok ();
}
}
static void DoUnexpected (void) static void DoUnexpected (void)
/* Got an unexpected keyword */ /* Got an unexpected keyword */
{ {
@ -1970,6 +1993,7 @@ static CtrlDesc CtrlCmdTab [] = {
{ ccNone, DoTag }, { ccNone, DoTag },
{ ccNone, DoUnexpected }, /* .TCOUNT */ { ccNone, DoUnexpected }, /* .TCOUNT */
{ ccNone, DoUnexpected }, /* .TIME */ { ccNone, DoUnexpected }, /* .TIME */
{ ccKeepToken, DoUnDef },
{ ccNone, DoUnion }, { ccNone, DoUnion },
{ ccNone, DoUnexpected }, /* .VERSION */ { ccNone, DoUnexpected }, /* .VERSION */
{ ccNone, DoWarning }, { ccNone, DoWarning },

View File

@ -278,6 +278,8 @@ struct DotKeyword {
{ ".TAG", TOK_TAG }, { ".TAG", TOK_TAG },
{ ".TCOUNT", TOK_TCOUNT }, { ".TCOUNT", TOK_TCOUNT },
{ ".TIME", TOK_TIME }, { ".TIME", TOK_TIME },
{ ".UNDEF", TOK_UNDEF },
{ ".UNDEFINE", TOK_UNDEF },
{ ".UNION", TOK_UNION }, { ".UNION", TOK_UNION },
{ ".VERSION", TOK_VERSION }, { ".VERSION", TOK_VERSION },
{ ".WARNING", TOK_WARNING }, { ".WARNING", TOK_WARNING },

View File

@ -247,6 +247,7 @@ typedef enum token_t {
TOK_TAG, TOK_TAG,
TOK_TCOUNT, TOK_TCOUNT,
TOK_TIME, TOK_TIME,
TOK_UNDEF,
TOK_UNION, TOK_UNION,
TOK_VERSION, TOK_VERSION,
TOK_WARNING, TOK_WARNING,