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 );