Merge branch 'master' into seglist

This commit is contained in:
Bob Andrews
2025-07-10 22:21:57 +02:00
committed by GitHub
10 changed files with 199 additions and 11 deletions

View File

@@ -94,6 +94,8 @@ Short options:
-W n Set warning level n -W n Set warning level n
-d Debug mode -d Debug mode
-g Add debug info to object file -g Add debug info to object file
-x Expand macros in the listing
repeat -x for full expansion
-h Help (this text) -h Help (this text)
-i Ignore case of symbols -i Ignore case of symbols
-l name Create a listing file if assembly was ok -l name Create a listing file if assembly was ok
@@ -113,6 +115,8 @@ Long options:
--create-full-dep name Create a full make dependency file --create-full-dep name Create a full make dependency file
--debug Debug mode --debug Debug mode
--debug-info Add debug info to object file --debug-info Add debug info to object file
--expand-macros Expand macros in listing
Repeat to get full expansion
--feature name Set an emulation feature --feature name Set an emulation feature
--help Help (this text) --help Help (this text)
--ignore-case Ignore case of symbols --ignore-case Ignore case of symbols

View File

@@ -69,7 +69,8 @@ unsigned char RelaxChecks = 0; /* Relax a few assembler checks */
unsigned char StringEscapes = 0; /* Allow C-style escapes in strings */ unsigned char StringEscapes = 0; /* Allow C-style escapes in strings */
unsigned char LongJsrJmpRts = 0; /* Allow JSR/JMP/RTS as alias for JSL/JML/RTL */ unsigned char LongJsrJmpRts = 0; /* Allow JSR/JMP/RTS as alias for JSL/JML/RTL */
unsigned char WarningsAsErrors = 0; /* Error if any warnings */ unsigned char WarningsAsErrors = 0; /* Error if any warnings */
unsigned char SegList = 0; unsigned char SegList = 0; /* Show segments in listing */
unsigned char ExpandMacros = 0; /* Expand macros in listing */
/* Emulation features */ /* Emulation features */
unsigned char DollarIsPC = 0; /* Allow the $ symbol as current PC */ unsigned char DollarIsPC = 0; /* Allow the $ symbol as current PC */

View File

@@ -71,7 +71,8 @@ extern unsigned char RelaxChecks; /* Relax a few assembler checks */
extern unsigned char StringEscapes; /* Allow C-style escapes in strings */ extern unsigned char StringEscapes; /* Allow C-style escapes in strings */
extern unsigned char LongJsrJmpRts; /* Allow JSR/JMP/RTS as alias for JSL/JML/RTL */ extern unsigned char LongJsrJmpRts; /* Allow JSR/JMP/RTS as alias for JSL/JML/RTL */
extern unsigned char WarningsAsErrors; /* Error if any warnings */ extern unsigned char WarningsAsErrors; /* Error if any warnings */
extern unsigned char SegList; extern unsigned char SegList; /* Show segments in listing */
extern unsigned char ExpandMacros; /* Expand macros in listing */
/* Emulation features */ /* Emulation features */
extern unsigned char DollarIsPC; /* Allow the $ symbol as current PC */ extern unsigned char DollarIsPC; /* Allow the $ symbol as current PC */

View File

@@ -93,6 +93,7 @@ void PushInput (int (*Func) (void*), void* Data, const char* Desc)
/* Push it */ /* Push it */
E->Next = IStack; E->Next = IStack;
ICount++;
IStack = E; IStack = E;
} }
@@ -111,7 +112,7 @@ void PopInput (void)
/* Pop it */ /* Pop it */
IStack = IStack->Next; IStack = IStack->Next;
ICount--;
/* And delete it */ /* And delete it */
xfree (E); xfree (E);
} }
@@ -157,6 +158,10 @@ void CheckInputStack (void)
} }
} }
unsigned GetStackDepth (void)
{
return ICount;
}
InputStack RetrieveInputStack (void) InputStack RetrieveInputStack (void)

View File

@@ -74,6 +74,9 @@ void CheckInputStack (void);
** stuff on the input stack. ** stuff on the input stack.
*/ */
unsigned GetStackDepth (void);
InputStack RetrieveInputStack (void); InputStack RetrieveInputStack (void);
/* Retrieve the current input stack. This will also clear it. Used when /* Retrieve the current input stack. This will also clear it. Used when
** including a file. The current input stack is stored together with the old ** including a file. The current input stack is stored together with the old

View File

@@ -54,6 +54,7 @@
#include "pseudo.h" #include "pseudo.h"
#include "toklist.h" #include "toklist.h"
#include "macro.h" #include "macro.h"
#include "listing.h"
@@ -75,7 +76,8 @@ static int HT_Compare (const void* Key1, const void* Key2);
** than zero if Key1 is greater then Key2. ** than zero if Key1 is greater then Key2.
*/ */
static char* GetTokenString (Token* T);
/* decompile a token back to a string */
/*****************************************************************************/ /*****************************************************************************/
/* Data */ /* Data */
@@ -136,6 +138,7 @@ struct MacExp {
TokNode* ParamExp; /* Node for expanding parameters */ TokNode* ParamExp; /* Node for expanding parameters */
LineInfo* LI; /* Line info for the expansion */ LineInfo* LI; /* Line info for the expansion */
LineInfo* ParamLI; /* Line info for parameter expansion */ LineInfo* ParamLI; /* Line info for parameter expansion */
unsigned ExpandStart; /* First pass through expansion ?*/
}; };
/* Maximum number of nested macro expansions */ /* Maximum number of nested macro expansions */
@@ -318,6 +321,7 @@ static MacExp* NewMacExp (Macro* M)
E->ParamExp = 0; E->ParamExp = 0;
E->LI = 0; E->LI = 0;
E->ParamLI = 0; E->ParamLI = 0;
E->ExpandStart = 1; /* set up detection of first call */
/* Mark the macro as expanding */ /* Mark the macro as expanding */
++M->Expansions; ++M->Expansions;
@@ -714,6 +718,8 @@ ExpandParam:
Mac->ParamLI = 0; Mac->ParamLI = 0;
} }
/* boolean to indicate that we need to start a new macro expansion line*/
static int new_expand_line = 1;
/* We're not expanding macro parameters. Check if we have tokens left from /* We're not expanding macro parameters. Check if we have tokens left from
** the macro itself. ** the macro itself.
@@ -722,7 +728,33 @@ ExpandParam:
/* Use next macro token */ /* Use next macro token */
TokSet (Mac->Exp); TokSet (Mac->Exp);
if (ExpandMacros) {
if (new_expand_line) {
/* Suppress unneeded lines if short expansion
** the ExpandStart is used to ensure that
** the invokation line itself isnt suppress
** This is becuase we are always working a line behind
** Lines we want to keep are upvoted so that this downvote
** will not suppress them
*/
if (LineLast->FragList == 0 && ExpandMacros == 1 && !Mac->ExpandStart) {
LineCur->Output--;
}
Mac->ExpandStart = 0;
StrBuf mac_line = MakeLineFromTokens (Mac->Exp);
NewListingLine (&mac_line, 0, 0);
InitListingLine ();
if (CurTok.Tok == TOK_SEGMENT) {
/* upvote the lines to keep*/
LineCur->Output = 2;
}
SB_Done (&mac_line);
new_expand_line = 0;
}
if (CurTok.Tok == TOK_SEP) {
new_expand_line = 1;
}
}
/* Create new line info for this token */ /* Create new line info for this token */
if (Mac->LI) { if (Mac->LI) {
EndLine (Mac->LI); EndLine (Mac->LI);
@@ -819,6 +851,7 @@ MacEnd:
PopInput (); PopInput ();
/* No token available */ /* No token available */
new_expand_line = 1;
return 0; return 0;
} }
@@ -1105,3 +1138,93 @@ void EnableDefineStyleMacros (void)
PRECONDITION (DisableDefines > 0); PRECONDITION (DisableDefines > 0);
--DisableDefines; --DisableDefines;
} }
StrBuf MakeLineFromTokens (TokNode* first)
{
/* This code reconstitutes a Macro line from the 'compiled' tokens*/
unsigned I;
/* string to be returned */
StrBuf S = STATIC_STRBUF_INITIALIZER;
/* prepend depth indicator */
for (I = 0; I < GetStackDepth (); I++) {
SB_AppendStr (&S, ">");
}
SB_AppendStr (&S, " ");
TokNode* tn = first;
while (tn) {
/* per token string */
StrBuf T = STATIC_STRBUF_INITIALIZER;
Token* token = &tn->T;
tn = tn->Next;
char* token_string;
/* leading white space?*/
if (token->WS) SB_AppendChar (&T, ' ');
/* is it a string of some sort?*/
unsigned len = SB_GetLen (&token->SVal);
if (len > 0) {
SB_Append (&T, &token->SVal);
} else if (token->Tok == TOK_INTCON) {
char ival[12]; // max size a long can be
snprintf (ival, sizeof(ival), "%ld", token->IVal);
SB_AppendStr (&T, ival);
} else if ((token_string = GetTokenString (token)) != NULL) {
SB_AppendStr (&T, token_string);
}
SB_Append (&S, &T);
if (token->Tok == TOK_SEP) {
return S;
}
}
return S;
}
static char* GetTokenString (Token* T)
{
switch (T->Tok) {
case TOK_ASSIGN: return ":="; /* := */
case TOK_ULABEL: return ":++"; /* :++ or :-- */
case TOK_EQ:return "="; /* = */
case TOK_NE: return "<>"; /* <> */
case TOK_LT: return "<"; /* < */
case TOK_GT:return ">"; /* > */
case TOK_LE: return "<="; /* <= */
case TOK_GE:return ">="; /* >= */
case TOK_PLUS: return "+"; /* + */
case TOK_MINUS:return "-"; /* - */
case TOK_MUL: return "*"; /* * */
case TOK_DIV: return "/"; /* / */
case TOK_MOD:return "!"; /* ! */
case TOK_OR: return "|"; /* | */
case TOK_XOR: return "^"; /* ^ */
case TOK_AND:return "&"; /* & */
case TOK_SHL: return "<<"; /* << */
case TOK_SHR: return ">>"; /* >> */
case TOK_NOT:return "~"; /* ~ */
case TOK_PC: return "$"; /* $ if enabled */
case TOK_NAMESPACE:return "::"; /* :: */
case TOK_DOT:return "."; /* . */
case TOK_COMMA:return ","; /* , */
case TOK_HASH: return "#"; /* # */
case TOK_COLON:return ":"; /* : */
case TOK_LPAREN:return "("; /* ( */
case TOK_RPAREN:return ")"; /* ) */
case TOK_LBRACK:return "["; /* [ */
case TOK_RBRACK:return "]"; /* ] */
case TOK_LCURLY:return "{"; /* { */
case TOK_RCURLY:return "}"; /* } */
case TOK_AT:return "@"; /* @ - in Sweet16 mode */
case TOK_OVERRIDE_ZP:return "z:"; /* z: */
case TOK_OVERRIDE_ABS:return "a:"; /* a: */
case TOK_OVERRIDE_FAR:return "f:"; /* f: */
default: return NULL;
}
}

View File

@@ -36,7 +36,7 @@
#ifndef MACRO_H #ifndef MACRO_H
#define MACRO_H #define MACRO_H
#include "toklist.h"
/*****************************************************************************/ /*****************************************************************************/
/* Forwards */ /* Forwards */
@@ -105,7 +105,7 @@ void EnableDefineStyleMacros (void);
** DisableDefineStyleMacros. ** DisableDefineStyleMacros.
*/ */
StrBuf MakeLineFromTokens (TokNode* first);
/* End of macro.h */ /* End of macro.h */

View File

@@ -110,6 +110,7 @@ static void Usage (void)
" -S\t\t\t\tEnable segment offset listing\n" " -S\t\t\t\tEnable segment offset listing\n"
" -t sys\t\t\tSet the target system\n" " -t sys\t\t\tSet the target system\n"
" -v\t\t\t\tIncrease verbosity\n" " -v\t\t\t\tIncrease verbosity\n"
" -x\t\t\t\tExpand macros\n"
"\n" "\n"
"Long options:\n" "Long options:\n"
" --auto-import\t\t\tMark unresolved symbols as import\n" " --auto-import\t\t\tMark unresolved symbols as import\n"
@@ -120,6 +121,7 @@ static void Usage (void)
" --create-full-dep name\tCreate a full make dependency file\n" " --create-full-dep name\tCreate a full make dependency file\n"
" --debug\t\t\tDebug mode\n" " --debug\t\t\tDebug mode\n"
" --debug-info\t\t\tAdd debug info to object file\n" " --debug-info\t\t\tAdd debug info to object file\n"
" --expand-macros\t\tExpand macros in the listing\n"
" --feature name\t\tSet an emulation feature\n" " --feature name\t\tSet an emulation feature\n"
" --help\t\t\tHelp (this text)\n" " --help\t\t\tHelp (this text)\n"
" --ignore-case\t\t\tIgnore case of symbols\n" " --ignore-case\t\t\tIgnore case of symbols\n"
@@ -757,7 +759,16 @@ static void OptWarningsAsErrors (const char* Opt attribute ((unused)),
WarningsAsErrors = 1; WarningsAsErrors = 1;
} }
static void OptExpandMacros (const char* Opt attribute ((unused)),
const char* Arg attribute ((unused)))
/* Expand macros in listing
** one -x means short listing
** two means full listing
*/
{
ExpandMacros++;
}
static void DoPCAssign (void) static void DoPCAssign (void)
/* Start absolute code */ /* Start absolute code */
@@ -782,9 +793,10 @@ static void OneLine (void)
int Instr = -1; int Instr = -1;
/* Initialize the new listing line if we are actually reading from file /* Initialize the new listing line if we are actually reading from file
** and not from internally pushed input. ** and not from internally pushed input
*/ */
if (!HavePushedInput ()) {
if (!HavePushedInput () ) {
InitListingLine (); InitListingLine ();
} }
@@ -994,6 +1006,7 @@ static void Assemble (void)
while (CurTok.Tok != TOK_EOF) { while (CurTok.Tok != TOK_EOF) {
OneLine (); OneLine ();
} }
} }
@@ -1056,6 +1069,7 @@ int main (int argc, char* argv [])
{ "--create-full-dep", 1, OptCreateFullDep }, { "--create-full-dep", 1, OptCreateFullDep },
{ "--debug", 0, OptDebug }, { "--debug", 0, OptDebug },
{ "--debug-info", 0, OptDebugInfo }, { "--debug-info", 0, OptDebugInfo },
{ "--expand-macros", 0, OptExpandMacros },
{ "--feature", 1, OptFeature }, { "--feature", 1, OptFeature },
{ "--help", 0, OptHelp }, { "--help", 0, OptHelp },
{ "--ignore-case", 0, OptIgnoreCase }, { "--ignore-case", 0, OptIgnoreCase },
@@ -1187,6 +1201,10 @@ int main (int argc, char* argv [])
case 'W': case 'W':
WarnLevel = atoi (GetArg (&I, 2)); WarnLevel = atoi (GetArg (&I, 2));
break; break;
case 'x':
ExpandMacros++;
break;
default: default:
UnknownOption (Arg); UnknownOption (Arg);

View File

@@ -406,6 +406,16 @@ static void IFMarkStart (CharSource* S)
static void IFNextChar (CharSource* S) static void IFNextChar (CharSource* S)
/* Read the next character from the input file */ /* Read the next character from the input file */
{ {
/* if expanding macros the next input line gets pushed too early
** to the output. So defer the push.
** Its harmless to do it regardless of expansion or not
*/
static int pending_line = 0;
if (pending_line) {
NewListingLine (&S->V.File.Line, S->V.File.Pos.Name, FCount);
pending_line = 0;
};
/* Check for end of line, read the next line if needed */ /* Check for end of line, read the next line if needed */
while (SB_GetIndex (&S->V.File.Line) >= SB_GetLen (&S->V.File.Line)) { while (SB_GetIndex (&S->V.File.Line) >= SB_GetLen (&S->V.File.Line)) {
@@ -471,7 +481,8 @@ static void IFNextChar (CharSource* S)
S->V.File.Pos.Line++; S->V.File.Pos.Line++;
/* Remember the new line for the listing */ /* Remember the new line for the listing */
NewListingLine (&S->V.File.Line, S->V.File.Pos.Name, FCount);
pending_line = 1;
} }

View File

@@ -46,7 +46,9 @@
#include "nexttok.h" #include "nexttok.h"
#include "scanner.h" #include "scanner.h"
#include "toklist.h" #include "toklist.h"
#include "macro.h"
#include "listing.h"
#include "global.h"
/*****************************************************************************/ /*****************************************************************************/
@@ -248,6 +250,26 @@ static int ReplayTokList (void* List)
} }
L->LI = StartLine (&CurTok.Pos, LI_TYPE_ASM, PushCounter); L->LI = StartLine (&CurTok.Pos, LI_TYPE_ASM, PushCounter);
/* see description in macro.c */
static int new_expand_line = 1;
if (ExpandMacros) {
if (new_expand_line) {
if (LineLast->FragList == 0 && ExpandMacros==1) {
LineCur->Output--;
}
StrBuf mac_line = MakeLineFromTokens (L->Last);
if (L->Last->T.Tok == TOK_SEGMENT) {
LineCur->Output = 2;
}
NewListingLine (&mac_line, 0, 0);
InitListingLine ();
SB_Done (&mac_line);
new_expand_line = 0;
}
if (L->Last->T.Tok == TOK_SEP) {
new_expand_line = 1;
}
}
/* If a check function is defined, call it, so it may look at the token /* If a check function is defined, call it, so it may look at the token
** just set and changed it as apropriate. ** just set and changed it as apropriate.
*/ */