X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fca65%2Fmacro.c;h=75741c479ff7c45eff52e5218422f91bf9dde7b4;hb=85885001b133e2dc320b6f6459259afa69784ca8;hp=719e76f0aaf16bf5a5be384329af29b5967473e1;hpb=44fd1082ae807a0b6b4046c65914e20a7e27101c;p=cc65 diff --git a/src/ca65/macro.c b/src/ca65/macro.c index 719e76f0a..75741c479 100644 --- a/src/ca65/macro.c +++ b/src/ca65/macro.c @@ -1,8 +1,8 @@ /*****************************************************************************/ /* */ -/* macro.c */ +/* macro.c */ /* */ -/* Macros for the ca65 macroassembler */ +/* Macros for the ca65 macroassembler */ /* */ /* */ /* */ @@ -77,7 +77,7 @@ static int HT_Compare (const void* Key1, const void* Key2); /*****************************************************************************/ -/* Data */ +/* Data */ /*****************************************************************************/ @@ -85,7 +85,7 @@ static int HT_Compare (const void* Key1, const void* Key2); /* Struct that describes an identifer (macro param, local list) */ typedef struct IdDesc IdDesc; struct IdDesc { - IdDesc* Next; /* Linked list */ + IdDesc* Next; /* Linked list */ StrBuf Id; /* Identifier, dynamically allocated */ }; @@ -94,17 +94,17 @@ struct IdDesc { /* Struct that describes a macro definition */ struct Macro { HashNode Node; /* Hash list node */ - Macro* List; /* List of all macros */ - unsigned LocalCount; /* Count of local symbols */ - IdDesc* Locals; /* List of local symbols */ - unsigned ParamCount; /* Parameter count of macro */ - IdDesc* Params; /* Identifiers of macro parameters */ - 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 */ + Macro* List; /* List of all macros */ + unsigned LocalCount; /* Count of local symbols */ + IdDesc* Locals; /* List of local symbols */ + unsigned ParamCount; /* Parameter count of macro */ + IdDesc* Params; /* Identifiers of macro parameters */ + 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 Style; /* Macro style */ unsigned char Incomplete; /* Macro is currently built */ }; @@ -121,16 +121,16 @@ static HashTable MacroTab = STATIC_HASHTABLE_INITIALIZER (117, &HashFunc); /* Structs that holds data for a macro expansion */ typedef struct MacExp MacExp; struct MacExp { - MacExp* Next; /* Pointer to next expansion */ - Macro* M; /* Which macro do we expand? */ - unsigned IfSP; /* .IF stack pointer at start of expansion */ - TokNode* Exp; /* Pointer to current token */ - TokNode* Final; /* Pointer to final token */ + MacExp* Next; /* Pointer to next expansion */ + Macro* M; /* Which macro do we expand? */ + unsigned IfSP; /* .IF stack pointer at start of expansion */ + TokNode* Exp; /* Pointer to current token */ + TokNode* Final; /* Pointer to final token */ unsigned MacExpansions; /* Number of active macro expansions */ - unsigned LocalStart; /* Start of counter for local symbol names */ - unsigned ParamCount; /* Number of actual parameters */ - TokNode** Params; /* List of actual parameters */ - TokNode* ParamExp; /* Node for expanding parameters */ + unsigned LocalStart; /* Start of counter for local symbol names */ + unsigned ParamCount; /* Number of actual parameters */ + TokNode** Params; /* List of actual parameters */ + TokNode* ParamExp; /* Node for expanding parameters */ LineInfo* LI; /* Line info for the expansion */ LineInfo* ParamLI; /* Line info for parameter expansion */ }; @@ -186,7 +186,7 @@ static int HT_Compare (const void* Key1, const void* Key2) /*****************************************************************************/ -/* Code */ +/* Code */ /*****************************************************************************/ @@ -244,13 +244,13 @@ static Macro* NewMacro (const StrBuf* Name, unsigned char Style) M->Locals = 0; M->ParamCount = 0; M->Params = 0; - M->TokCount = 0; + M->TokCount = 0; M->TokRoot = 0; M->TokLast = 0; SB_Init (&M->Name); SB_Copy (&M->Name, Name); M->Expansions = 0; - M->Style = Style; + M->Style = Style; M->Incomplete = 1; /* Insert the macro into the hash table */ @@ -297,19 +297,19 @@ static MacExp* NewMacExp (Macro* M) MacExp* E = xmalloc (sizeof (MacExp)); /* Initialize the data */ - E->M = M; - E->IfSP = GetIfStack (); - E->Exp = M->TokRoot; - E->Final = 0; + E->M = M; + E->IfSP = GetIfStack (); + E->Exp = M->TokRoot; + E->Final = 0; E->MacExpansions = ++MacExpansions; /* One macro expansion more */ E->LocalStart = LocalName; LocalName += M->LocalCount; E->ParamCount = 0; E->Params = xmalloc (M->ParamCount * sizeof (TokNode*)); for (I = 0; I < M->ParamCount; ++I) { - E->Params[I] = 0; + E->Params[I] = 0; } - E->ParamExp = 0; + E->ParamExp = 0; E->LI = 0; E->ParamLI = 0; @@ -355,7 +355,7 @@ static void FreeMacExp (MacExp* E) /* Free the final token if we have one */ if (E->Final) { - FreeTokNode (E->Final); + FreeTokNode (E->Final); } /* Free the structure itself */ @@ -368,18 +368,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 (); } } @@ -394,9 +394,9 @@ void MacDef (unsigned Style) /* We expect a macro name here */ if (CurTok.Tok != TOK_IDENT) { - Error ("Identifier expected"); - MacSkipDef (Style); - return; + Error ("Identifier expected"); + 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. @@ -408,11 +408,11 @@ void MacDef (unsigned Style) /* Did we already define that macro? */ if (HT_Find (&MacroTab, &CurTok.SVal) != 0) { - /* 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); - return; + /* 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); + return; } /* Define the macro */ @@ -426,62 +426,62 @@ void MacDef (unsigned Style) * otherwise we may have parameters without braces. */ if (Style == MAC_STYLE_CLASSIC) { - HaveParams = 1; + HaveParams = 1; } else { - if (CurTok.Tok == TOK_LPAREN) { - HaveParams = 1; - NextTok (); - } else { - HaveParams = 0; - } + if (CurTok.Tok == TOK_LPAREN) { + HaveParams = 1; + NextTok (); + } else { + HaveParams = 0; + } } /* Parse the parameter list */ if (HaveParams) { - while (CurTok.Tok == TOK_IDENT) { - - /* Create a struct holding the identifier */ - IdDesc* I = NewIdDesc (&CurTok.SVal); - - /* Insert the struct into the list, checking for duplicate idents */ - if (M->ParamCount == 0) { - M->Params = I; - } else { - IdDesc* List = M->Params; - while (1) { - if (SB_Compare (&List->Id, &CurTok.SVal) == 0) { - Error ("Duplicate symbol `%m%p'", &CurTok.SVal); - } - if (List->Next == 0) { - break; - } else { - List = List->Next; - } - } - List->Next = I; - } - ++M->ParamCount; - - /* Skip the name */ - NextTok (); - - /* Maybe there are more params... */ - if (CurTok.Tok == TOK_COMMA) { - NextTok (); - } else { - break; - } - } + while (CurTok.Tok == TOK_IDENT) { + + /* Create a struct holding the identifier */ + IdDesc* I = NewIdDesc (&CurTok.SVal); + + /* Insert the struct into the list, checking for duplicate idents */ + if (M->ParamCount == 0) { + M->Params = I; + } else { + IdDesc* List = M->Params; + while (1) { + if (SB_Compare (&List->Id, &CurTok.SVal) == 0) { + Error ("Duplicate symbol `%m%p'", &CurTok.SVal); + } + if (List->Next == 0) { + break; + } else { + List = List->Next; + } + } + List->Next = I; + } + ++M->ParamCount; + + /* Skip the name */ + NextTok (); + + /* Maybe there are more params... */ + if (CurTok.Tok == TOK_COMMA) { + NextTok (); + } else { + break; + } + } } /* For class macros, we expect a separator token, for define style macros, * we expect the closing paren. */ if (Style == MAC_STYLE_CLASSIC) { - ConsumeSep (); + ConsumeSep (); } else if (HaveParams) { - ConsumeRParen (); + ConsumeRParen (); } /* Preparse the macro body. We will read the tokens until we reach end of @@ -491,98 +491,98 @@ void MacDef (unsigned Style) */ while (1) { - /* Check for end of macro */ - if (Style == MAC_STYLE_CLASSIC) { - /* In classic macros, only .endmacro is allowed */ - if (CurTok.Tok == TOK_ENDMACRO) { - /* Done */ - break; - } - /* May not have end of file in a macro definition */ - if (CurTok.Tok == TOK_EOF) { - Error ("`.ENDMACRO' expected"); - goto Done; - } - } else { - /* Accept a newline or end of file for new style macros */ - if (TokIsSep (CurTok.Tok)) { - break; - } - } - - /* Check for a .LOCAL declaration */ - if (CurTok.Tok == TOK_LOCAL && Style == MAC_STYLE_CLASSIC) { - - while (1) { - - IdDesc* I; - - /* Skip .local or comma */ - NextTok (); - - /* Need an identifer */ - if (CurTok.Tok != TOK_IDENT && CurTok.Tok != TOK_LOCAL_IDENT) { - Error ("Identifier expected"); - SkipUntilSep (); - break; - } - - /* Put the identifier into the locals list and skip it */ - I = NewIdDesc (&CurTok.SVal); - I->Next = M->Locals; - M->Locals = I; - ++M->LocalCount; - NextTok (); - - /* Check for end of list */ - if (CurTok.Tok != TOK_COMMA) { - break; - } - - } - - /* We need end of line after the locals */ - ConsumeSep (); - continue; - } - - /* Create a token node for the current token */ - N = NewTokNode (); + /* Check for end of macro */ + if (Style == MAC_STYLE_CLASSIC) { + /* In classic macros, only .endmacro is allowed */ + if (CurTok.Tok == TOK_ENDMACRO) { + /* Done */ + break; + } + /* May not have end of file in a macro definition */ + if (CurTok.Tok == TOK_EOF) { + Error ("`.ENDMACRO' expected"); + goto Done; + } + } else { + /* Accept a newline or end of file for new style macros */ + if (TokIsSep (CurTok.Tok)) { + break; + } + } + + /* Check for a .LOCAL declaration */ + if (CurTok.Tok == TOK_LOCAL && Style == MAC_STYLE_CLASSIC) { + + while (1) { + + IdDesc* I; + + /* Skip .local or comma */ + NextTok (); + + /* Need an identifer */ + if (CurTok.Tok != TOK_IDENT && CurTok.Tok != TOK_LOCAL_IDENT) { + Error ("Identifier expected"); + SkipUntilSep (); + break; + } + + /* Put the identifier into the locals list and skip it */ + I = NewIdDesc (&CurTok.SVal); + I->Next = M->Locals; + M->Locals = I; + ++M->LocalCount; + NextTok (); + + /* Check for end of list */ + if (CurTok.Tok != TOK_COMMA) { + break; + } + + } + + /* We need end of line after the locals */ + ConsumeSep (); + continue; + } + + /* Create a token node for the current token */ + N = NewTokNode (); /* If the token is an identifier, check if it is a local parameter */ - if (CurTok.Tok == TOK_IDENT) { - unsigned Count = 0; - IdDesc* I = M->Params; - while (I) { - if (SB_Compare (&I->Id, &CurTok.SVal) == 0) { - /* Local param name, replace it */ - N->T.Tok = TOK_MACPARAM; - N->T.IVal = Count; - break; - } - ++Count; - I = I->Next; - } - } - - /* Insert the new token in the list */ - if (M->TokCount == 0) { - /* First token */ - M->TokRoot = M->TokLast = N; - } else { - /* We have already tokens */ - M->TokLast->Next = N; - M->TokLast = N; - } - ++M->TokCount; - - /* Read the next token */ - NextTok (); + if (CurTok.Tok == TOK_IDENT) { + unsigned Count = 0; + IdDesc* I = M->Params; + while (I) { + if (SB_Compare (&I->Id, &CurTok.SVal) == 0) { + /* Local param name, replace it */ + N->T.Tok = TOK_MACPARAM; + N->T.IVal = Count; + break; + } + ++Count; + I = I->Next; + } + } + + /* Insert the new token in the list */ + if (M->TokCount == 0) { + /* First token */ + M->TokRoot = M->TokLast = N; + } else { + /* We have already tokens */ + M->TokLast->Next = N; + M->TokLast = N; + } + ++M->TokCount; + + /* Read the next token */ + NextTok (); } /* Skip the .endmacro for a classic macro */ if (Style == MAC_STYLE_CLASSIC) { - NextTok (); + NextTok (); } /* Reset the Incomplete flag now that parsing is done */ @@ -634,14 +634,14 @@ static int MacExpand (void* Data) /* Check if we should abort this macro */ if (DoMacAbort) { - /* Reset the flag */ - DoMacAbort = 0; + /* Reset the flag */ + DoMacAbort = 0; - /* Abort any open .IF statements in this macro expansion */ - CleanupIfStack (Mac->IfSP); + /* Abort any open .IF statements in this macro expansion */ + CleanupIfStack (Mac->IfSP); - /* Terminate macro expansion */ - goto MacEnd; + /* Terminate macro expansion */ + goto MacEnd; } /* We're expanding a macro. Check if we are expanding one of the @@ -650,8 +650,8 @@ static int MacExpand (void* Data) ExpandParam: if (Mac->ParamExp) { - /* Ok, use token from parameter list */ - TokSet (Mac->ParamExp); + /* Ok, use token from parameter list */ + TokSet (Mac->ParamExp); /* Create new line info for this parameter token */ if (Mac->ParamLI) { @@ -659,11 +659,11 @@ ExpandParam: } Mac->ParamLI = StartLine (&CurTok.Pos, LI_TYPE_MACPARAM, Mac->MacExpansions); - /* Set pointer to next token */ - Mac->ParamExp = Mac->ParamExp->Next; + /* Set pointer to next token */ + Mac->ParamExp = Mac->ParamExp->Next; - /* Done */ - return 1; + /* Done */ + return 1; } else if (Mac->ParamLI) { @@ -678,8 +678,8 @@ ExpandParam: */ if (Mac->Exp) { - /* Use next macro token */ - TokSet (Mac->Exp); + /* Use next macro token */ + TokSet (Mac->Exp); /* Create new line info for this token */ if (Mac->LI) { @@ -687,35 +687,35 @@ ExpandParam: } Mac->LI = StartLine (&CurTok.Pos, LI_TYPE_MACRO, Mac->MacExpansions); - /* Set pointer to next token */ - Mac->Exp = Mac->Exp->Next; + /* Set pointer to next token */ + Mac->Exp = Mac->Exp->Next; - /* Is it a request for actual parameter count? */ - if (CurTok.Tok == TOK_PARAMCOUNT) { - CurTok.Tok = TOK_INTCON; - CurTok.IVal = Mac->ParamCount; - return 1; - } + /* Is it a request for actual parameter count? */ + if (CurTok.Tok == TOK_PARAMCOUNT) { + CurTok.Tok = TOK_INTCON; + CurTok.IVal = Mac->ParamCount; + return 1; + } - /* Is it the name of a macro parameter? */ - if (CurTok.Tok == TOK_MACPARAM) { + /* Is it the name of a macro parameter? */ + if (CurTok.Tok == TOK_MACPARAM) { - /* Start to expand the parameter token list */ - Mac->ParamExp = Mac->Params[CurTok.IVal]; + /* Start to expand the parameter token list */ + Mac->ParamExp = Mac->Params[CurTok.IVal]; - /* Go back and expand the parameter */ - goto ExpandParam; - } + /* Go back and expand the parameter */ + goto ExpandParam; + } - /* If it's an identifier, it may in fact be a local symbol */ - if ((CurTok.Tok == TOK_IDENT || CurTok.Tok == TOK_LOCAL_IDENT) && + /* If it's an identifier, it may in fact be a local symbol */ + if ((CurTok.Tok == TOK_IDENT || CurTok.Tok == TOK_LOCAL_IDENT) && Mac->M->LocalCount) { - /* Search for the local symbol in the list */ - unsigned Index = 0; - IdDesc* I = Mac->M->Locals; - while (I) { - if (SB_Compare (&CurTok.SVal, &I->Id) == 0) { - /* This is in fact a local symbol, change the name. Be sure + /* Search for the local symbol in the list */ + unsigned Index = 0; + IdDesc* I = Mac->M->Locals; + while (I) { + if (SB_Compare (&CurTok.SVal, &I->Id) == 0) { + /* This is in fact a local symbol, change the name. Be sure * to generate a local label name if the original name was * a local label, and also generate a name that cannot be * generated by a user. @@ -729,28 +729,28 @@ ExpandParam: SB_Printf (&CurTok.SVal, "LOCAL-MACRO_SYMBOL-%04X", Mac->LocalStart + Index); } - break; - } - /* Next symbol */ - ++Index; - I = I->Next; - } - - /* Done */ - return 1; - } - - /* The token was successfully set */ - return 1; + break; + } + /* Next symbol */ + ++Index; + I = I->Next; + } + + /* Done */ + return 1; + } + + /* The token was successfully set */ + return 1; } /* No more macro tokens. Do we have a final token? */ if (Mac->Final) { - /* Set the final token and remove it */ - TokSet (Mac->Final); - FreeTokNode (Mac->Final); - Mac->Final = 0; + /* Set the final token and remove it */ + TokSet (Mac->Final); + FreeTokNode (Mac->Final); + Mac->Final = 0; /* Problem: When a .define style macro is expanded within the call * of a classic one, the latter may be terminated and removed while @@ -765,8 +765,8 @@ ExpandParam: FreeMacExp (Mac); PopInput (); - /* The token was successfully set */ - return 1; + /* The token was successfully set */ + return 1; } MacEnd: @@ -793,47 +793,47 @@ static void StartExpClassic (MacExp* E) /* Read the actual parameters */ while (!TokIsSep (CurTok.Tok)) { - TokNode* Last; + TokNode* Last; - /* Check for maximum parameter count */ - if (E->ParamCount >= E->M->ParamCount) { - ErrorSkip ("Too many macro parameters"); - break; - } + /* Check for maximum parameter count */ + 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); - /* Read tokens for one parameter, accept empty params */ - Last = 0; - while (CurTok.Tok != Term && CurTok.Tok != TOK_SEP) { + /* Read tokens for one parameter, accept empty params */ + Last = 0; + while (CurTok.Tok != Term && CurTok.Tok != TOK_SEP) { - TokNode* T; + TokNode* T; - /* Check for end of file */ - if (CurTok.Tok == TOK_EOF) { - Error ("Unexpected end of file"); + /* Check for end of file */ + if (CurTok.Tok == TOK_EOF) { + Error ("Unexpected end of file"); FreeMacExp (E); - return; - } + return; + } - /* Get the next token in a node */ - T = NewTokNode (); + /* Get the next token in a node */ + T = NewTokNode (); - /* Insert it into the list */ - if (Last == 0) { - E->Params [E->ParamCount] = T; - } else { - Last->Next = T; - } - Last = T; + /* Insert it into the list */ + if (Last == 0) { + E->Params [E->ParamCount] = T; + } else { + Last->Next = T; + } + Last = T; - /* And skip it... */ - NextTok (); - } + /* And skip it... */ + NextTok (); + } - /* 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. @@ -846,12 +846,12 @@ static void StartExpClassic (MacExp* E) NextTok (); } - /* Check for a comma */ - if (CurTok.Tok == TOK_COMMA) { - NextTok (); - } else { - break; - } + /* Check for a comma */ + if (CurTok.Tok == TOK_COMMA) { + NextTok (); + } else { + break; + } } /* We must be at end of line now, otherwise something is wrong */ @@ -877,42 +877,42 @@ static void StartExpDefine (MacExp* E) /* Read the actual parameters */ while (Count--) { - TokNode* Last; + TokNode* Last; /* The macro may optionally be enclosed in curly braces */ token_t Term = GetTokListTerm (TOK_COMMA); - /* Check if there is really a parameter */ - if (TokIsSep (CurTok.Tok) || CurTok.Tok == Term) { + /* Check if there is really a parameter */ + if (TokIsSep (CurTok.Tok) || CurTok.Tok == Term) { ErrorSkip ("Macro parameter #%u is empty", E->ParamCount+1); FreeMacExp (E); return; } - /* Read tokens for one parameter */ - Last = 0; - do { + /* Read tokens for one parameter */ + Last = 0; + do { - TokNode* T; + TokNode* T; - /* Get the next token in a node */ - T = NewTokNode (); + /* Get the next token in a node */ + T = NewTokNode (); - /* Insert it into the list */ - if (Last == 0) { - E->Params [E->ParamCount] = T; - } else { - Last->Next = T; - } - Last = T; + /* Insert it into the list */ + if (Last == 0) { + E->Params [E->ParamCount] = T; + } else { + Last->Next = T; + } + Last = T; - /* And skip it... */ - NextTok (); + /* And skip it... */ + NextTok (); - } while (CurTok.Tok != Term && !TokIsSep (CurTok.Tok)); + } 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. @@ -925,14 +925,14 @@ static void StartExpDefine (MacExp* E) NextTok (); } - /* Check for a comma */ - if (Count > 0) { - if (CurTok.Tok == TOK_COMMA) { - NextTok (); - } else { - Error ("`,' expected"); - } - } + /* Check for a comma */ + if (Count > 0) { + if (CurTok.Tok == TOK_COMMA) { + NextTok (); + } else { + Error ("`,' expected"); + } + } } /* Macro expansion will overwrite the current token. This is a problem @@ -975,9 +975,9 @@ void MacExpandStart (Macro* M) /* Call the apropriate subroutine */ switch (M->Style) { - case MAC_STYLE_CLASSIC: StartExpClassic (E); break; - case MAC_STYLE_DEFINE: StartExpDefine (E); 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); } }