diff --git a/doc/ca65.sgml b/doc/ca65.sgml index b65d337bb..b19a66a2d 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -2522,7 +2522,19 @@ See: ,

- Marks the end of a macro definition. + Marks the end of a macro definition. Note, .ENDMACRO should be on + its own line to successfully end the macro definition. It is possible to use + to create a symbol that references + .ENDMACRO without ending the macro definition. + + Example: + + + .macro new_mac + .define startmac .macro + .define endmac .endmacro + .endmacro + See: , , diff --git a/src/ca65/macro.c b/src/ca65/macro.c index 84f0e8bcd..72436fdec 100644 --- a/src/ca65/macro.c +++ b/src/ca65/macro.c @@ -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 */ { if (Style == MAC_STYLE_CLASSIC) { @@ -375,7 +375,7 @@ static void MacSkipDef (unsigned Style, FilePos Pos) if (CurTok.Tok != TOK_EOF) { SkipUntilSep (); } else { - PError (&Pos, "'.ENDMACRO' expected"); + Error ("'.ENDMACRO' expected"); } } else { /* Skip until end of line */ @@ -390,27 +390,32 @@ void MacDef (unsigned Style) { Macro* M; TokNode* N; + FilePos Pos; int HaveParams; + int LastTokWasSep; - /* Remember if we are at the beginning of the line. If the macro name - ** and parameters pass then this will be set, so set it now */ - int LastTokWasSep = 1; + /* For classic macros, remember if we are at the beginning of the line. + ** If the macro name and parameters pass our checks then we will be on a + ** new line, so set it now + */ + LastTokWasSep = 1; /* Save the position of the start of the macro definition to allow - ** using Perror to display the error if .ENDMACRO isn't found */ - FilePos Pos = CurTok.Pos; + ** using Perror to display the error if .ENDMACRO isn't found + */ + Pos = CurTok.Pos; /* We expect a macro name here */ if (CurTok.Tok != TOK_IDENT) { Error ("Identifier expected"); - MacSkipDef (Style, Pos); + MacSkipDef (Style); return; } else if (!UbiquitousIdents && FindInstruction (&CurTok.SVal) >= 0) { /* The identifier is a name of a 6502 instruction, which is not ** allowed if not explicitly enabled. */ Error ("Cannot use an instruction as macro name"); - MacSkipDef (Style, Pos); + MacSkipDef (Style); return; } @@ -419,7 +424,7 @@ void MacDef (unsigned Style) /* Macro is already defined */ Error ("A macro named '%m%p' is already defined", &CurTok.SVal); /* Skip tokens until we reach the final .endmacro */ - MacSkipDef (Style, Pos); + MacSkipDef (Style); return; } @@ -499,14 +504,16 @@ void MacDef (unsigned Style) while (1) { /* Check for end of macro */ 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) { /* Done */ break; } /* May not have end of file in a macro definition */ if (CurTok.Tok == TOK_EOF) { - PError (&Pos, "'.ENDMACRO' expected"); + PError (&Pos, "'.ENDMACRO' expected for macro '%m%p'", &M->Name); goto Done; } } else { @@ -581,7 +588,9 @@ void MacDef (unsigned Style) } ++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); /* Read the next token */