From eaa45269e7572b3795d81bcc0c4f597de7f01b6c Mon Sep 17 00:00:00 2001 From: uz Date: Sat, 11 Jun 2011 22:18:48 +0000 Subject: [PATCH] First implementation of .UNDEF for deleting a macro. git-svn-id: svn://svn.cc65.org/cc65/trunk@5049 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/ca65/macro.c | 154 +++++++++++++++++++++++++++++---------------- src/ca65/macro.h | 37 ++++++++--- src/ca65/pseudo.c | 34 ++++++++-- src/ca65/scanner.c | 6 +- src/ca65/token.h | 1 + 5 files changed, 163 insertions(+), 69 deletions(-) diff --git a/src/ca65/macro.c b/src/ca65/macro.c index 868b03f19..21db6e81f 100644 --- a/src/ca65/macro.c +++ b/src/ca65/macro.c @@ -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; +} + + diff --git a/src/ca65/macro.h b/src/ca65/macro.h index 045204a6e..921b601db 100644 --- a/src/ca65/macro.h +++ b/src/ca65/macro.h @@ -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 */ diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 4b81e7c62..85891e471 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -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 */ /*****************************************************************************/ diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index a9fd7c2d9..a49c8a222 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -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 }, diff --git a/src/ca65/token.h b/src/ca65/token.h index cbff651d8..a95edfb52 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -247,6 +247,7 @@ typedef enum token_t { TOK_TAG, TOK_TCOUNT, TOK_TIME, + TOK_UNDEF, TOK_UNION, TOK_VERSION, TOK_WARNING,