Fix .endmacro not at the start of the line. Fix style, add doc., add tests
This commit is contained in:
@@ -2522,7 +2522,19 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".CHARMAP" name=".CH
|
|||||||
|
|
||||||
<sect1><tt>.ENDMAC, .ENDMACRO</tt><label id=".ENDMACRO"><p>
|
<sect1><tt>.ENDMAC, .ENDMACRO</tt><label id=".ENDMACRO"><p>
|
||||||
|
|
||||||
Marks the end of a macro definition.
|
Marks the end of a macro definition. Note, <tt>.ENDMACRO</tt> should be on
|
||||||
|
its own line to successfully end the macro definition. It is possible to use
|
||||||
|
<tt><ref id=".DEFINE" name=".DEFINE"></tt> to create a symbol that references
|
||||||
|
<tt>.ENDMACRO</tt> without ending the macro definition.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
<tscreen><verb>
|
||||||
|
.macro new_mac
|
||||||
|
.define startmac .macro
|
||||||
|
.define endmac .endmacro
|
||||||
|
.endmacro
|
||||||
|
</verb></tscreen>
|
||||||
|
|
||||||
See: <tt><ref id=".DELMACRO" name=".DELMACRO"></tt>,
|
See: <tt><ref id=".DELMACRO" name=".DELMACRO"></tt>,
|
||||||
<tt><ref id=".EXITMACRO" name=".EXITMACRO"></tt>,
|
<tt><ref id=".EXITMACRO" name=".EXITMACRO"></tt>,
|
||||||
|
|||||||
@@ -364,7 +364,7 @@ static void FreeMacExp (MacExp* E)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void MacSkipDef (unsigned Style, FilePos Pos)
|
static void MacSkipDef (unsigned Style)
|
||||||
/* Skip a macro definition */
|
/* Skip a macro definition */
|
||||||
{
|
{
|
||||||
if (Style == MAC_STYLE_CLASSIC) {
|
if (Style == MAC_STYLE_CLASSIC) {
|
||||||
@@ -375,7 +375,7 @@ static void MacSkipDef (unsigned Style, FilePos Pos)
|
|||||||
if (CurTok.Tok != TOK_EOF) {
|
if (CurTok.Tok != TOK_EOF) {
|
||||||
SkipUntilSep ();
|
SkipUntilSep ();
|
||||||
} else {
|
} else {
|
||||||
PError (&Pos, "'.ENDMACRO' expected");
|
Error ("'.ENDMACRO' expected");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Skip until end of line */
|
/* Skip until end of line */
|
||||||
@@ -390,27 +390,32 @@ void MacDef (unsigned Style)
|
|||||||
{
|
{
|
||||||
Macro* M;
|
Macro* M;
|
||||||
TokNode* N;
|
TokNode* N;
|
||||||
|
FilePos Pos;
|
||||||
int HaveParams;
|
int HaveParams;
|
||||||
|
int LastTokWasSep;
|
||||||
|
|
||||||
/* Remember if we are at the beginning of the line. If the macro name
|
/* For classic macros, remember if we are at the beginning of the line.
|
||||||
** and parameters pass then this will be set, so set it now */
|
** If the macro name and parameters pass our checks then we will be on a
|
||||||
int LastTokWasSep = 1;
|
** new line, so set it now
|
||||||
|
*/
|
||||||
|
LastTokWasSep = 1;
|
||||||
|
|
||||||
/* Save the position of the start of the macro definition to allow
|
/* Save the position of the start of the macro definition to allow
|
||||||
** using Perror to display the error if .ENDMACRO isn't found */
|
** using Perror to display the error if .ENDMACRO isn't found
|
||||||
FilePos Pos = CurTok.Pos;
|
*/
|
||||||
|
Pos = CurTok.Pos;
|
||||||
|
|
||||||
/* We expect a macro name here */
|
/* We expect a macro name here */
|
||||||
if (CurTok.Tok != TOK_IDENT) {
|
if (CurTok.Tok != TOK_IDENT) {
|
||||||
Error ("Identifier expected");
|
Error ("Identifier expected");
|
||||||
MacSkipDef (Style, Pos);
|
MacSkipDef (Style);
|
||||||
return;
|
return;
|
||||||
} else if (!UbiquitousIdents && FindInstruction (&CurTok.SVal) >= 0) {
|
} else if (!UbiquitousIdents && FindInstruction (&CurTok.SVal) >= 0) {
|
||||||
/* The identifier is a name of a 6502 instruction, which is not
|
/* The identifier is a name of a 6502 instruction, which is not
|
||||||
** allowed if not explicitly enabled.
|
** allowed if not explicitly enabled.
|
||||||
*/
|
*/
|
||||||
Error ("Cannot use an instruction as macro name");
|
Error ("Cannot use an instruction as macro name");
|
||||||
MacSkipDef (Style, Pos);
|
MacSkipDef (Style);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -419,7 +424,7 @@ void MacDef (unsigned Style)
|
|||||||
/* Macro is already defined */
|
/* Macro is already defined */
|
||||||
Error ("A macro named '%m%p' is already defined", &CurTok.SVal);
|
Error ("A macro named '%m%p' is already defined", &CurTok.SVal);
|
||||||
/* Skip tokens until we reach the final .endmacro */
|
/* Skip tokens until we reach the final .endmacro */
|
||||||
MacSkipDef (Style, Pos);
|
MacSkipDef (Style);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,14 +504,16 @@ void MacDef (unsigned Style)
|
|||||||
while (1) {
|
while (1) {
|
||||||
/* Check for end of macro */
|
/* Check for end of macro */
|
||||||
if (Style == MAC_STYLE_CLASSIC) {
|
if (Style == MAC_STYLE_CLASSIC) {
|
||||||
/* In classic macros, only .endmacro is allowed, but do no exit the macro definition if not at the start of a line */
|
/* In classic macros, if .endmacro is not at the start of the line
|
||||||
|
** it will be added to the macro definition instead of closing it.
|
||||||
|
*/
|
||||||
if (CurTok.Tok == TOK_ENDMACRO && LastTokWasSep) {
|
if (CurTok.Tok == TOK_ENDMACRO && LastTokWasSep) {
|
||||||
/* Done */
|
/* Done */
|
||||||
break;
|
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) {
|
if (CurTok.Tok == TOK_EOF) {
|
||||||
PError (&Pos, "'.ENDMACRO' expected");
|
PError (&Pos, "'.ENDMACRO' expected for macro '%m%p'", &M->Name);
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -581,7 +588,9 @@ void MacDef (unsigned Style)
|
|||||||
}
|
}
|
||||||
++M->TokCount;
|
++M->TokCount;
|
||||||
|
|
||||||
/* Save if last token was a separator to know if .endmacro is valid */
|
/* Save if last token was a separator to know if .endmacro is at
|
||||||
|
** the start of a line
|
||||||
|
*/
|
||||||
LastTokWasSep = TokIsSep(CurTok.Tok);
|
LastTokWasSep = TokIsSep(CurTok.Tok);
|
||||||
|
|
||||||
/* Read the next token */
|
/* Read the next token */
|
||||||
|
|||||||
Reference in New Issue
Block a user