1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-29 10:29:30 +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 */
TokNode* TokRoot; /* Root of token 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 Incomplete; /* Macro is currently built */
StrBuf Name; /* Macro name, dynamically allocated */
};
/* Hash table functions */
@ -122,9 +123,6 @@ static const HashFunctions HashFunc = {
/* Macro hash table */
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 */
typedef struct MacExp MacExp;
struct MacExp {
@ -152,6 +150,9 @@ static int DoMacAbort = 0;
/* Counter to create local names for symbols */
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->TokRoot = 0;
M->TokLast = 0;
M->Style = Style;
M->Incomplete = 1;
SB_Init (&M->Name);
SB_Copy (&M->Name, Name);
/* Insert the macro into the global macro list */
M->List = MacroRoot;
MacroRoot = M;
M->Expansions = 0;
M->Style = Style;
M->Incomplete = 1;
/* Insert the macro into the hash table */
HT_Insert (&MacroTab, &M->Node);
@ -268,12 +266,15 @@ static MacExp* NewMacExp (Macro* M)
LocalName += M->LocalCount;
E->ParamCount = 0;
E->Params = xmalloc (M->ParamCount * sizeof (TokNode*));
E->ParamExp = 0;
for (I = 0; I < M->ParamCount; ++I) {
E->Params[I] = 0;
}
E->ParamExp = 0;
E->LISlot = AllocLineInfoSlot (LI_TYPE_MACRO, MacExpansions);
/* Mark the macro as expanding */
++M->Expansions;
/* One macro expansion more */
++MacExpansions;
@ -291,6 +292,9 @@ static void FreeMacExp (MacExp* E)
/* One macro expansion less */
--MacExpansions;
/* No longer expanding this macro */
--E->M->Expansions;
/* Free the parameter lists */
for (I = 0; I < E->ParamCount; ++I) {
/* Free one parameter list */
@ -321,18 +325,18 @@ static void MacSkipDef (unsigned Style)
/* Skip a macro definition */
{
if (Style == MAC_STYLE_CLASSIC) {
/* Skip tokens until we reach the final .endmacro */
while (CurTok.Tok != TOK_ENDMACRO && CurTok.Tok != TOK_EOF) {
NextTok ();
}
if (CurTok.Tok != TOK_EOF) {
SkipUntilSep ();
} else {
Error ("`.ENDMACRO' expected");
}
/* Skip tokens until we reach the final .endmacro */
while (CurTok.Tok != TOK_ENDMACRO && CurTok.Tok != TOK_EOF) {
NextTok ();
}
if (CurTok.Tok != TOK_EOF) {
SkipUntilSep ();
} else {
Error ("`.ENDMACRO' expected");
}
} else {
/* Skip until end of line */
SkipUntilSep ();
/* Skip until end of line */
SkipUntilSep ();
}
}
@ -451,7 +455,7 @@ void MacDef (unsigned Style)
/* Done */
break;
}
/* May not have end of file in a macro definition */
/* May not have end of file in a macro definition */
if (CurTok.Tok == TOK_EOF) {
Error ("`.ENDMACRO' expected");
goto Done;
@ -485,7 +489,7 @@ void MacDef (unsigned Style)
I->Next = M->Locals;
M->Locals = I;
++M->LocalCount;
NextTok ();
NextTok ();
/* Check for end of list */
if (CurTok.Tok != TOK_COMMA) {
@ -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)
/* 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
@ -678,19 +704,11 @@ MacEnd:
static void StartExpClassic (Macro* M)
/* Start expanding the classic macro M */
static void StartExpClassic (MacExp* E)
/* Start expanding a classic macro */
{
MacExp* E;
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 */
NextTok ();
@ -700,10 +718,10 @@ static void StartExpClassic (Macro* M)
TokNode* Last;
/* Check for maximum parameter count */
if (E->ParamCount >= M->ParamCount) {
if (E->ParamCount >= E->M->ParamCount) {
ErrorSkip ("Too many macro parameters");
break;
}
}
/* The macro may optionally be enclosed in curly braces */
Term = GetTokListTerm (TOK_COMMA);
@ -730,7 +748,7 @@ static void StartExpClassic (Macro* M)
} else {
Last->Next = T;
}
Last = T;
Last = T;
/* And skip it... */
NextTok ();
@ -752,8 +770,8 @@ static void StartExpClassic (Macro* M)
/* Check for a comma */
if (CurTok.Tok == TOK_COMMA) {
NextTok ();
} else {
NextTok ();
} else {
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 */
{
/* Create a structure holding expansion data */
MacExp* E = NewMacExp (M);
/* A define style macro must be called with as many actual parameters
* as there are formal ones. Get the parameter count.
*/
unsigned Count = M->ParamCount;
unsigned Count = E->M->ParamCount;
/* Skip the current token */
NextTok ();
@ -813,13 +828,13 @@ static void StartExpDefine (Macro* M)
}
Last = T;
/* And skip it... */
NextTok ();
/* And skip it... */
NextTok ();
} while (CurTok.Tok != Term && !TokIsSep (CurTok.Tok));
/* One parameter more */
++E->ParamCount;
/* One parameter more */
++E->ParamCount;
/* If the macro argument was enclosed in curly braces, end-of-line
* is an error. Skip the closing curly brace.
@ -858,9 +873,11 @@ static void StartExpDefine (Macro* M)
void MacExpandStart (void)
/* Start expanding the macro in SVal */
{
MacExp* E;
/* Search for the macro */
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 */
if (M->Incomplete) {
@ -876,11 +893,14 @@ void MacExpandStart (void)
return;
}
/* Create a structure holding expansion data */
E = NewMacExp (M);
/* Call the apropriate subroutine */
switch (M->Style) {
case MAC_STYLE_CLASSIC: StartExpClassic (M); break;
case MAC_STYLE_DEFINE: StartExpDefine (M); break;
default: Internal ("Invalid macro style: %d", M->Style);
case MAC_STYLE_CLASSIC: StartExpClassic (E); break;
case MAC_STYLE_DEFINE: StartExpDefine (E); break;
default: Internal ("Invalid macro style: %d", M->Style);
}
}
@ -908,8 +928,16 @@ int IsMacro (const StrBuf* Name)
int IsDefine (const StrBuf* Name)
/* 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);
}
@ -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,10 +6,10 @@
/* */
/* */
/* */
/* (C) 1998-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* (C) 1998-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
@ -39,19 +39,29 @@
/*****************************************************************************/
/* Data */
/* Forwards */
/*****************************************************************************/
struct StrBuf;
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Macro styles */
#define MAC_STYLE_CLASSIC 0
#define MAC_STYLE_DEFINE 1
#define MAC_STYLE_CLASSIC 0
#define MAC_STYLE_DEFINE 1
/*****************************************************************************/
/* Code */
/* Code */
/*****************************************************************************/
@ -59,6 +69,9 @@
void MacDef (unsigned Style);
/* Parse a macro definition */
void MacUndef (const struct StrBuf* Name);
/* Undefine the macro with the given name. */
void MacExpandStart (void);
/* Start expanding the macro in SVal */
@ -74,6 +87,14 @@ int IsDefine (const StrBuf* Name);
int InMacExpansion (void);
/* 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 */

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)
/* Got an unexpected keyword */
{
@ -1824,7 +1847,7 @@ static void DoZeropage (void)
/*****************************************************************************/
/* Table data */
/* Table data */
/*****************************************************************************/
@ -1914,7 +1937,7 @@ static CtrlDesc CtrlCmdTab [] = {
{ ccKeepToken, DoConditionals }, /* .IFP816 */
{ ccKeepToken, DoConditionals }, /* .IFPC02 */
{ ccKeepToken, DoConditionals }, /* .IFPSC02 */
{ ccKeepToken, DoConditionals }, /* .IFREF */
{ ccKeepToken, DoConditionals }, /* .IFREF */
{ ccNone, DoImport },
{ ccNone, DoImportZP },
{ ccNone, DoIncBin },
@ -1936,7 +1959,7 @@ static CtrlDesc CtrlCmdTab [] = {
{ ccNone, DoInvalid }, /* .MID */
{ ccNone, DoUnexpected }, /* .MIN */
{ ccNone, DoNull },
{ ccNone, DoOrg },
{ ccNone, DoOrg },
{ ccNone, DoOut },
{ ccNone, DoP02 },
{ ccNone, DoP816 },
@ -1970,10 +1993,11 @@ static CtrlDesc CtrlCmdTab [] = {
{ ccNone, DoTag },
{ ccNone, DoUnexpected }, /* .TCOUNT */
{ ccNone, DoUnexpected }, /* .TIME */
{ ccKeepToken, DoUnDef },
{ ccNone, DoUnion },
{ ccNone, DoUnexpected }, /* .VERSION */
{ ccNone, DoWarning },
{ ccNone, DoWord },
{ ccNone, DoWord },
{ ccNone, DoUnexpected }, /* .XMATCH */
{ ccNone, DoZeropage },
};
@ -1981,7 +2005,7 @@ static CtrlDesc CtrlCmdTab [] = {
/*****************************************************************************/
/* Code */
/* Code */
/*****************************************************************************/

View File

@ -265,8 +265,8 @@ struct DotKeyword {
{ ".SEGMENT", TOK_SEGMENT },
{ ".SET", TOK_SET },
{ ".SETCPU", TOK_SETCPU },
{ ".SHL", TOK_SHL },
{ ".SHR", TOK_SHR },
{ ".SHL", TOK_SHL },
{ ".SHR", TOK_SHR },
{ ".SIZEOF", TOK_SIZEOF },
{ ".SMART", TOK_SMART },
{ ".SPRINTF", TOK_SPRINTF },
@ -278,6 +278,8 @@ struct DotKeyword {
{ ".TAG", TOK_TAG },
{ ".TCOUNT", TOK_TCOUNT },
{ ".TIME", TOK_TIME },
{ ".UNDEF", TOK_UNDEF },
{ ".UNDEFINE", TOK_UNDEF },
{ ".UNION", TOK_UNION },
{ ".VERSION", TOK_VERSION },
{ ".WARNING", TOK_WARNING },

View File

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