diff --git a/src/anonymouslabels.cpp b/src/anonymouslabels.cpp index 5ea7e56..9c422f9 100644 --- a/src/anonymouslabels.cpp +++ b/src/anonymouslabels.cpp @@ -29,7 +29,7 @@ AnonymousLabels AnonymousLabels::m_gInstance; // Update the forward references when a '+' label is seen -void AnonymousLabels::UpdateForwardReferences(int pc) +void AnonymousLabelsData::UpdateForwardReferences(int pc) { for (std::vector::iterator it = m_forwardReferences.begin(); it != m_forwardReferences.end(); ++it) { diff --git a/src/anonymouslabels.h b/src/anonymouslabels.h index 00b71f1..9dc7518 100644 --- a/src/anonymouslabels.h +++ b/src/anonymouslabels.h @@ -28,11 +28,9 @@ #include -class AnonymousLabels +class AnonymousLabelsData { public: - static inline AnonymousLabels& Instance() { return m_gInstance; } - // Get PC of last '-' label int GetBackReference() { return m_backReference; } // Set PC of '-' label @@ -47,6 +45,45 @@ class AnonymousLabels private: int m_backReference; std::vector m_forwardReferences; +}; + + +class AnonymousLabels +{ +public: + static inline AnonymousLabelsData& Instance() { return m_gInstance.Current(); } + + AnonymousLabels() : m_level(0) + { + } + + static void EnterMacro() { m_gInstance.Enter(); } + static void LeaveMacro() { m_gInstance.Leave(); } + +private: + void Enter() + { + m_level++; + } + void Leave() + { + if ( m_level < m_data.size() ) + { + m_data[m_level].Clear(); + } + m_level--; + } + AnonymousLabelsData& Current() + { + if ( m_level >= m_data.size() ) + { + m_data.resize(m_level + 1); + } + return m_data[m_level]; + } + + unsigned int m_level; + std::vector m_data; static AnonymousLabels m_gInstance; }; diff --git a/src/lineparser.cpp b/src/lineparser.cpp index 169f2b6..4040376 100644 --- a/src/lineparser.cpp +++ b/src/lineparser.cpp @@ -29,6 +29,7 @@ #include "symboltable.h" #include "globaldata.h" #include "sourcefile.h" +#include "anonymouslabels.h" using namespace std; @@ -124,17 +125,6 @@ void LineParser::Process( const string& line ) m_column = oldColumn; - // Check for an anonymous label declaration, + or - - // Must be followed by a newline or space. - if ( !bIsSymbolAssignment ) - { - if (( m_line[ m_column ] == '+' || m_line[ m_column ] == '-' ) && (m_column + 1 == m_line.length() || m_line[ m_column + 1 ] == ' ')) - { - HandleAnonymousLabel(); - continue; - } - } - // first check tokens - they have priority over opcodes, so that they can have names // like INCLUDE (which would otherwise be interpreted as INC LUDE) @@ -159,6 +149,18 @@ void LineParser::Process( const string& line ) continue; } + // Check for an anonymous label declaration, + or - + // Must be followed by a newline or space. + + if ( !bIsSymbolAssignment ) + { + if (( m_line[ m_column ] == '+' || m_line[ m_column ] == '-' ) && (m_column + 1 == m_line.length() || m_line[ m_column + 1 ] == ' ')) + { + HandleAnonymousLabel(); + continue; + } + } + // No token match - check against opcodes if ( !bIsSymbolAssignment ) @@ -238,6 +240,7 @@ void LineParser::Process( const string& line ) cout << "Macro " << macroName << ":" << endl; } + AnonymousLabels::EnterMacro(); HandleOpenBrace(); for ( int i = 0; i < macro->GetNumberOfParameters(); i++ ) @@ -291,6 +294,7 @@ void LineParser::Process( const string& line ) macroInstance.Process(); HandleCloseBrace(); + AnonymousLabels::LeaveMacro(); if ( m_sourceCode->ShouldOutputAsm() ) { diff --git a/test/4-assembler/anonmacro.6502 b/test/4-assembler/anonmacro.6502 new file mode 100644 index 0000000..35982af --- /dev/null +++ b/test/4-assembler/anonmacro.6502 @@ -0,0 +1,22 @@ +MACRO anon N +LDY #N +- JSR &FFEE +DEY +BNE - +ENDMACRO + +ORG &2000 +.start +LDX #0 +- +LDA text,X +BEQ + +anon 2 +INX +BNE - ++ RTS +.text +EQUS "Hello", 0 +.end + +SAVE "hello",start,end diff --git a/test/4-assembler/anonmacro.gold.ssd b/test/4-assembler/anonmacro.gold.ssd new file mode 100644 index 0000000..5c3c13a Binary files /dev/null and b/test/4-assembler/anonmacro.gold.ssd differ