beebasm
changeset 37:bc0355ba8a53
Added better error handling for macros, and corrected problem that reported incorrect line number for any error inside a macro definition.
| author | RichTW <richtw1@gmail.com> |
|---|---|
| date | Mon Apr 25 03:53:44 2011 +0200 |
| parents | 9988a3cb5311 |
| children | c2cd2f187a7f |
| files | about.txt beebasm.exe src/Makefile src/asmexception.h src/commands.cpp src/globaldata.cpp src/main.cpp src/sourcecode.cpp src/sourcecode.h |
| diffstat | 9 files changed, 65 insertions(+), 16 deletions(-) [+] |
line diff
1.1 --- a/about.txt Mon Apr 25 02:40:57 2011 +0200 1.2 +++ b/about.txt Mon Apr 25 03:53:44 2011 +0200 1.3 @@ -152,6 +152,13 @@ 1.4 absence of any switches specifying disc image filenames, SAVE commands in the 1.5 source code will write out object files directly to the current directory. 1.6 1.7 +-o <filename> 1.8 + 1.9 +If this is specified, then the SAVE command can be used without supplying a 1.10 +filename, and this one will be used instead. This allows BeebAsm to be used 1.11 +like a conventional assembler, specifying both input and output filenames 1.12 +from the command line. 1.13 + 1.14 -do <filename> 1.15 1.16 This specifies the name of a new disc image to be created. All object code 1.17 @@ -548,8 +555,8 @@ 1.18 ADDI8 bonus, 10 ; add 10 to the memory location 'bonus' 1.19 ADDI8 pills, pill_add ; pills += pill_add 1.20 1.21 - Macros can also be nested, as demonstrated by this somewhat contrived 1.22 - example: 1.23 + Macros can also be called from other macros, as demonstrated by this somewhat 1.24 + contrived example: 1.25 1.26 MACRO ADDI16 addr, val 1.27 IF val=0
2.1 Binary file beebasm.exe has changed
3.1 --- a/src/Makefile Mon Apr 25 02:40:57 2011 +0200 3.2 +++ b/src/Makefile Mon Apr 25 03:53:44 2011 +0200 3.3 @@ -51,8 +51,8 @@ 3.4 3.5 # Parameters to the executable 3.6 3.7 -#PARAMS := -i ../demo.6502 -do ../demo.ssd -boot Code -v 3.8 -PARAMS := -i ../test.6502 -v 3.9 +PARAMS := -i ../demo.6502 -do ../demo.ssd -boot Code -v 3.10 +#PARAMS := -i ../test.6502 -v 3.11 3.12 3.13
4.1 --- a/src/asmexception.h Mon Apr 25 02:40:57 2011 +0200 4.2 +++ b/src/asmexception.h Mon Apr 25 03:53:44 2011 +0200 4.3 @@ -204,6 +204,7 @@ 4.4 DEFINE_SYNTAX_EXCEPTION( InvalidMacroName, "Invalid macro name; must start with a letter and contain only letters, numbers and underscore." ); 4.5 DEFINE_SYNTAX_EXCEPTION( NoNestedMacros, "Cannot define one macro inside another." ); 4.6 DEFINE_SYNTAX_EXCEPTION( EndMacroUnexpected, "ENDMACRO encountered without a matching MACRO directive." ); 4.7 +DEFINE_SYNTAX_EXCEPTION( NoEndMacro, "Unterminated macro (ENDMACRO not found)." ); 4.8 DEFINE_SYNTAX_EXCEPTION( DuplicateMacroName, "Macro name already defined." ); 4.9 4.10 // meta-language parsing exceptions
5.1 --- a/src/commands.cpp Mon Apr 25 02:40:57 2011 +0200 5.2 +++ b/src/commands.cpp Mon Apr 25 03:53:44 2011 +0200 5.3 @@ -1731,6 +1731,18 @@ 5.4 throw AsmException_SyntaxError_UnexpectedComma( m_line, m_column - 1 ); 5.5 } 5.6 5.7 + // If there is nothing else on the line following the MACRO command, put a newline at the 5.8 + // beginning of the macro definition, so any errors are reported on the correct line 5.9 + 5.10 + if ( m_column == m_line.length() && 5.11 + GlobalData::Instance().IsFirstPass() ) 5.12 + { 5.13 + m_sourceCode->GetCurrentMacro()->AddLine("\n"); 5.14 + } 5.15 + 5.16 + // Set the IF condition to false - this is a cheaty way of ensuring that the macro body 5.17 + // is not assembled as it is parsed 5.18 + 5.19 m_sourceCode->SetCurrentIfCondition(false); 5.20 } 5.21
6.1 --- a/src/globaldata.cpp Mon Apr 25 02:40:57 2011 +0200 6.2 +++ b/src/globaldata.cpp Mon Apr 25 03:53:44 2011 +0200 6.3 @@ -71,7 +71,8 @@ 6.4 m_bVerbose( false ), 6.5 m_bUseDiscImage( false ), 6.6 m_pDiscImage( NULL ), 6.7 - m_bSaved( false ) 6.8 + m_bSaved( false ), 6.9 + m_pOutputFile( NULL ) 6.10 { 6.11 } 6.12
7.1 --- a/src/main.cpp Mon Apr 25 02:40:57 2011 +0200 7.2 +++ b/src/main.cpp Mon Apr 25 03:53:44 2011 +0200 7.3 @@ -146,6 +146,7 @@ 7.4 case WAITING_FOR_OUTPUT_FILENAME: 7.5 7.6 pOutputFile = argv[i]; 7.7 + GlobalData::Instance().SetOutputFile( pOutputFile ); 7.8 state = READY; 7.9 break; 7.10
8.1 --- a/src/sourcecode.cpp Mon Apr 25 02:40:57 2011 +0200 8.2 +++ b/src/sourcecode.cpp Mon Apr 25 03:53:44 2011 +0200 8.3 @@ -154,16 +154,26 @@ 8.4 } 8.5 } 8.6 8.7 - // Check that we have no IF mismatch 8.8 + // Check that we have no IF / MACRO mismatch 8.9 8.10 if ( m_ifStackPtr > initialIfStackPtr ) 8.11 { 8.12 If& mismatchedIf = m_ifStack[ m_ifStackPtr - 1 ]; 8.13 8.14 - AsmException_SyntaxError_IfWithoutEndif e( mismatchedIf.m_line, mismatchedIf.m_column ); 8.15 - e.SetFilename( m_filename ); 8.16 - e.SetLineNumber( mismatchedIf.m_lineNumber ); 8.17 - throw e; 8.18 + if ( mismatchedIf.m_isMacroDefinition ) 8.19 + { 8.20 + AsmException_SyntaxError_NoEndMacro e( mismatchedIf.m_line, mismatchedIf.m_column ); 8.21 + e.SetFilename( m_filename ); 8.22 + e.SetLineNumber( mismatchedIf.m_lineNumber ); 8.23 + throw e; 8.24 + } 8.25 + else 8.26 + { 8.27 + AsmException_SyntaxError_IfWithoutEndif e( mismatchedIf.m_line, mismatchedIf.m_column ); 8.28 + e.SetFilename( m_filename ); 8.29 + e.SetLineNumber( mismatchedIf.m_lineNumber ); 8.30 + throw e; 8.31 + } 8.32 } 8.33 } 8.34 8.35 @@ -385,12 +395,13 @@ 8.36 throw AsmException_SyntaxError_TooManyIFs( line, column ); 8.37 } 8.38 8.39 - m_ifStack[ m_ifStackPtr ].m_condition = true; 8.40 - m_ifStack[ m_ifStackPtr ].m_passed = false; 8.41 - m_ifStack[ m_ifStackPtr ].m_hadElse = false; 8.42 - m_ifStack[ m_ifStackPtr ].m_line = line; 8.43 - m_ifStack[ m_ifStackPtr ].m_column = column; 8.44 - m_ifStack[ m_ifStackPtr ].m_lineNumber = m_lineNumber; 8.45 + m_ifStack[ m_ifStackPtr ].m_condition = true; 8.46 + m_ifStack[ m_ifStackPtr ].m_passed = false; 8.47 + m_ifStack[ m_ifStackPtr ].m_hadElse = false; 8.48 + m_ifStack[ m_ifStackPtr ].m_isMacroDefinition = false; 8.49 + m_ifStack[ m_ifStackPtr ].m_line = line; 8.50 + m_ifStack[ m_ifStackPtr ].m_column = column; 8.51 + m_ifStack[ m_ifStackPtr ].m_lineNumber = m_lineNumber; 8.52 m_ifStackPtr++; 8.53 } 8.54 8.55 @@ -398,6 +409,19 @@ 8.56 8.57 /*************************************************************************************************/ 8.58 /** 8.59 + SourceCode::SetCurrentIfAsMacroDefinition() 8.60 +*/ 8.61 +/*************************************************************************************************/ 8.62 +void SourceCode::SetCurrentIfAsMacroDefinition() 8.63 +{ 8.64 + assert( m_ifStackPtr > 0 ); 8.65 + m_ifStack[ m_ifStackPtr - 1 ].m_isMacroDefinition = true; 8.66 +} 8.67 + 8.68 + 8.69 + 8.70 +/*************************************************************************************************/ 8.71 +/** 8.72 SourceCode::SetCurrentIfCondition() 8.73 */ 8.74 /*************************************************************************************************/ 8.75 @@ -486,6 +510,7 @@ 8.76 } 8.77 8.78 AddIfLevel( line, column ); 8.79 + SetCurrentIfAsMacroDefinition(); 8.80 } 8.81 8.82
9.1 --- a/src/sourcecode.h Mon Apr 25 02:40:57 2011 +0200 9.2 +++ b/src/sourcecode.h Mon Apr 25 03:53:44 2011 +0200 9.3 @@ -83,6 +83,7 @@ 9.4 bool m_condition; 9.5 bool m_hadElse; 9.6 bool m_passed; 9.7 + bool m_isMacroDefinition; 9.8 std::string m_line; 9.9 int m_column; 9.10 int m_lineNumber; 9.11 @@ -118,6 +119,7 @@ 9.12 9.13 bool IsIfConditionTrue() const; 9.14 void AddIfLevel( const std::string& line, int column ); 9.15 + void SetCurrentIfAsMacroDefinition(); 9.16 void SetCurrentIfCondition( bool b ); 9.17 void StartElse( const std::string& line, int column ); 9.18 void StartElif( const std::string& line, int column );
