1
0
mirror of https://github.com/cc65/cc65.git synced 2025-01-03 16:33:19 +00:00

Finished implemenation of commands to delete macros. Added the new commands to

the docs.


git-svn-id: svn://svn.cc65.org/cc65/trunk@5050 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz 2011-06-12 21:29:07 +00:00
parent eaa45269e7
commit d1426aaa43
6 changed files with 239 additions and 72 deletions

View File

@ -2113,7 +2113,22 @@ Here's a list of all control commands and a description, what they do:
Start a define style macro definition. The command is followed by an
identifier (the macro name) and optionally by a list of formal arguments
in braces.
See section <ref id="macros" name="Macros">.
See also the <tt><ref id=".UNDEFINE" name=".UNDEFINE"></tt> command and
section <ref id="macros" name="Macros">.
<sect1><tt>.DELMAC, .DELMACRO</tt><label id=".DELMACRO"><p>
Delete a classic macro (defined with <tt><ref id=".MACRO"
name=".MACRO"></tt>) . The command is followed by the name of an
existing macro. Its definition will be deleted together with the name.
If necessary, another macro with this name may be defined later.
See: <tt><ref id=".ENDMACRO" name=".ENDMACRO"></tt>,
<tt><ref id=".EXITMACRO" name=".EXITMACRO"></tt>,
<tt><ref id=".MACRO" name=".MACRO"></tt>
See also section <ref id="macros" name="Macros">.
<sect1><tt>.DEF, .DEFINED</tt><label id=".DEFINED"><p>
@ -2201,7 +2216,13 @@ Here's a list of all control commands and a description, what they do:
<sect1><tt>.ENDMAC, .ENDMACRO</tt><label id=".ENDMACRO"><p>
End of macro definition (see section <ref id="macros" name="Macros">).
Marks the end of a macro definition.
See: <tt><ref id=".DELMACRO" name=".DELMACRO"></tt>,
<tt><ref id=".EXITMACRO" name=".EXITMACRO"></tt>,
<tt><ref id=".MACRO" name=".MACRO"></tt>
See also section <ref id="macros" name="Macros">.
<sect1><tt>.ENDPROC</tt><label id=".ENDPROC"><p>
@ -2315,7 +2336,13 @@ Here's a list of all control commands and a description, what they do:
<sect1><tt>.EXITMAC, .EXITMACRO</tt><label id=".EXITMACRO"><p>
Abort a macro expansion immediately. This command is often useful in
recursive macros. See separate section <ref id="macros" name="Macros">.
recursive macros.
See: <tt><ref id=".DELMACRO" name=".DELMACRO"></tt>,
<tt><ref id=".ENDMACRO" name=".ENDMACRO"></tt>,
<tt><ref id=".MACRO" name=".MACRO"></tt>
See also section <ref id="macros" name="Macros">.
<sect1><tt>.EXPORT</tt><label id=".EXPORT"><p>
@ -3081,13 +3108,26 @@ Here's a list of all control commands and a description, what they do:
id="macropackages" name="Macro packages">.
<sect1><tt>.MAC, .MACRO</tt><label id=".MAC"><p>
<sect1><tt>.MAC, .MACRO</tt><label id=".MACRO"><p>
Start a classic macro definition. The command is followed by an identifier
(the macro name) and optionally by a comma separated list of identifiers
that are macro parameters.
that are macro parameters. A macro definition is terminated by <tt><ref
id=".ENDMACRO" name=".ENDMACRO"></tt>.
See section <ref id="macros" name="Macros">.
Example:
<tscreen><verb>
.macro ldax arg ; Define macro ldax
lda arg
ldx arg+1
</verb></tscreen>
See: <tt><ref id=".DELMACRO" name=".DELMACRO"></tt>,
<tt><ref id=".ENDMACRO" name=".ENDMACRO"></tt>,
<tt><ref id=".EXITMACRO" name=".EXITMACRO"></tt>
See also section <ref id="macros" name="Macros">.
<sect1><tt>.ORG</tt><label id=".ORG"><p>
@ -3519,6 +3559,17 @@ Here's a list of all control commands and a description, what they do:
</verb></tscreen>
<sect1><tt>.UNDEF, .UNDEFINE</tt><label id=".UNDEFINE"><p>
Delete a define style macro definition. The command is followed by an
identifier which specifies the name of the macro to delete. Macro
replacement is switched of when reading the token following the command
(otherwise the macro name would be replaced by it's replacement list).
See also the <tt><ref id=".DEFINE" name=".DEFINE"></tt> command and
section <ref id="macros" name="Macros">.
<sect1><tt>.WARNING</tt><label id=".WARNING"><p>
Force an assembly warning. The assembler will output a warning message
@ -3974,6 +4025,47 @@ doing more complex macros. If you compare characters against numeric values,
be sure to take the translation into account.
<sect1>Deleting macros<p>
Macros can be deleted. This will not work if the macro that should be deleted
is currently expanded as in the following non working example:
<tscreen><verb>
.macro notworking
.delmacro notworking
.endmacro
notworking ; Will not work
</verb></tscreen>
The commands to delete classic and define style macros differ. Classic macros
can be deleted by use of <tt><ref id=".DELMACRO" name=".DELMACRO"></tt>, while
for <tt><ref id=".DEFINE" name=".DEFINE"></tt> style macros, <tt><ref
id=".UNDEFINE" name=".UNDEFINE"></tt> must be used. Example:
<tscreen><verb>
.define value 1
.macro mac
.byte 2
.endmacro
.byte value ; Emit one byte with value 1
mac ; Emit another byte with value 2
.undefine value
.delmacro mac
.byte value ; Error: Unknown identifier
mac ; Error: Missing ":"
</verb></tscreen>
A separate command for <tt>.DEFINE</tt> style macros was necessary, because
the name of such a macro is replaced by its replacement list on a very low
level. To get the actual name, macro replacement has to be switched off when
reading the argument to <tt>.UNDEFINE</tt>. This does also mean that the
argument to <tt>.UNDEFINE</tt> is not allowed to come from another
<tt>.DEFINE</tt>. All this is not necessary for classic macros, so having two
different commands increases flexibility.
<sect>Macro packages<label id="macropackages"><p>

View File

@ -206,15 +206,39 @@ static IdDesc* NewIdDesc (const StrBuf* Id)
/* Create a new IdDesc, initialize and return it */
{
/* Allocate memory */
IdDesc* I = xmalloc (sizeof (IdDesc));
IdDesc* ID = xmalloc (sizeof (IdDesc));
/* Initialize the struct */
I->Next = 0;
SB_Init (&I->Id);
SB_Copy (&I->Id, Id);
ID->Next = 0;
SB_Init (&ID->Id);
SB_Copy (&ID->Id, Id);
/* Return the new struct */
return I;
return ID;
}
static void FreeIdDesc (IdDesc* ID)
/* Free an IdDesc */
{
/* Free the name */
SB_Done (&ID->Id);
/* Free the structure itself */
xfree (ID);
}
static void FreeIdDescList (IdDesc* ID)
/* Free a complete list of IdDesc structures */
{
while (ID) {
IdDesc* This = ID;
ID = ID->Next;
FreeIdDesc (This);
}
}
@ -249,6 +273,32 @@ static Macro* NewMacro (const StrBuf* Name, unsigned char Style)
static void FreeMacro (Macro* M)
/* Free a macro entry which has already been removed from the macro table. */
{
TokNode* T;
/* Free locals */
FreeIdDescList (M->Locals);
/* Free identifiers of parameters */
FreeIdDescList (M->Params);
/* Free the token list for the macro */
while ((T = M->TokRoot) != 0) {
M->TokRoot = T->Next;
FreeTokNode (T);
}
/* Free the macro name */
SB_Done (&M->Name);
/* Free the macro structure itself */
xfree (M);
}
static MacExp* NewMacExp (Macro* M)
/* Create a new expansion structure for the given macro */
{
@ -552,14 +602,16 @@ Done:
void MacUndef (const StrBuf* Name)
/* Undefine the macro with the given name. */
void MacUndef (const StrBuf* Name, unsigned char Style)
/* Undefine the macro with the given name and style. A style mismatch is
* treated as if the macro didn't exist.
*/
{
/* Search for the macro */
Macro* M = HT_FindEntry (&MacroTab, Name);
/* Don't let the user kid with us */
if (M == 0) {
if (M == 0 || M->Style != Style) {
Error ("No such macro: %m%p", Name);
return;
}
@ -570,6 +622,9 @@ void MacUndef (const StrBuf* Name)
/* Remove the macro from the macro table */
HT_RemoveEntry (&MacroTab, M);
/* Free the macro structure */
FreeMacro (M);
}

View File

@ -69,8 +69,10 @@ struct StrBuf;
void MacDef (unsigned Style);
/* Parse a macro definition */
void MacUndef (const struct StrBuf* Name);
/* Undefine the macro with the given name. */
void MacUndef (const StrBuf* Name, unsigned char Style);
/* Undefine the macro with the given name and style. A style mismatch is
* treated as if the macro didn't exist.
*/
void MacExpandStart (void);
/* Start expanding the macro in SVal */

View File

@ -753,6 +753,20 @@ static void DoDefine (void)
static void DoDelMac (void)
/* Delete a classic macro */
{
/* We expect an identifier */
if (CurTok.Tok != TOK_IDENT) {
ErrorSkip ("Identifier expected");
} else {
MacUndef (&CurTok.SVal, MAC_STYLE_CLASSIC);
NextTok ();
}
}
static void DoDestructor (void)
/* Export a symbol as destructor */
{
@ -1779,7 +1793,7 @@ static void DoTag (void)
static void DoUnDef (void)
/* Undefine a macro */
/* Undefine a define style macro */
{
/* The function is called with the .UNDEF token in place, because we need
* to disable .define macro expansions before reading the next token.
@ -1794,7 +1808,7 @@ static void DoUnDef (void)
if (CurTok.Tok != TOK_IDENT) {
ErrorSkip ("Identifier expected");
} else {
MacUndef (&CurTok.SVal);
MacUndef (&CurTok.SVal, MAC_STYLE_DEFINE);
NextTok ();
}
}
@ -1893,6 +1907,7 @@ static CtrlDesc CtrlCmdTab [] = {
{ ccNone, DoDebugInfo },
{ ccNone, DoDefine },
{ ccNone, DoUnexpected }, /* .DEFINED */
{ ccNone, DoDelMac },
{ ccNone, DoDestructor },
{ ccNone, DoDWord },
{ ccKeepToken, DoConditionals }, /* .ELSE */

View File

@ -166,6 +166,8 @@ struct DotKeyword {
{ ".DEF", TOK_DEFINED },
{ ".DEFINE", TOK_DEFINE },
{ ".DEFINED", TOK_DEFINED },
{ ".DELMAC", TOK_DELMAC },
{ ".DELMACRO", TOK_DELMAC },
{ ".DESTRUCTOR", TOK_DESTRUCTOR },
{ ".DWORD", TOK_DWORD },
{ ".ELSE", TOK_ELSE },

View File

@ -147,6 +147,7 @@ typedef enum token_t {
TOK_DEBUGINFO,
TOK_DEFINE,
TOK_DEFINED,
TOK_DELMAC,
TOK_DESTRUCTOR,
TOK_DWORD,
TOK_ELSE,