2015-12-07 13:15:02 +09:00
using PerCederberg.Grammatica.Runtime ;
using System ;
namespace arookas
{
// base exception type
public class sunCompilerException : Exception
{
public sunCompilerException ( )
{
}
public sunCompilerException ( string format , params object [ ] args )
: base ( String . Format ( format , args ) )
{
}
}
// exceptions that have a location in the source
public abstract class sunScriptException : sunCompilerException
{
public abstract sunSourceLocation Location { get ; }
public sunScriptException ( )
{
}
public sunScriptException ( string format , params object [ ] args )
: base ( format , args )
{
}
}
2015-12-09 10:11:35 +09:00
public class sunImportException : sunCompilerException
{
public string Name { get ; private set ; }
public sunImportResult Result { get ; private set ; }
public override string Message { get { return String . Format ( "Name: {0}, Result: {1}" , Name , Result ) ; } }
public sunImportException ( string name , sunImportResult result )
{
if ( name = = null )
{
throw new ArgumentNullException ( "name" ) ;
}
if ( ! result . IsDefined ( ) )
{
throw new ArgumentOutOfRangeException ( "name" ) ;
}
Name = name ;
Result = result ;
}
}
2015-12-07 13:15:02 +09:00
// wrapper around Grammatica exceptions
class sunParserException : sunScriptException
{
string file ;
public ParseException Info { get ; private set ; }
public override string Message { get { return Info . ErrorMessage ; } }
public override sunSourceLocation Location { get { return new sunSourceLocation ( file , Info . Line , Info . Column ) ; } }
public sunParserException ( string file , ParseException info )
{
if ( file = = null )
{
throw new ArgumentNullException ( "file" ) ;
}
if ( info = = null )
{
throw new ArgumentNullException ( "info" ) ;
}
this . file = file ;
Info = info ;
}
}
// node exceptions
abstract class sunNodeException < TNode > : sunScriptException where TNode : sunNode
{
public TNode Node { get ; private set ; }
public override sunSourceLocation Location { get { return Node . Location ; } }
protected sunNodeException ( TNode node )
{
if ( node = = null )
{
throw new ArgumentNullException ( "node" ) ;
}
Node = node ;
}
}
class sunRedeclaredBuiltinException : sunNodeException < sunBuiltinDeclaration >
{
public override string Message { get { return String . Format ( "Redeclared builtin '{0}'." , Node . Builtin . Value ) ; } }
public sunRedeclaredBuiltinException ( sunBuiltinDeclaration node )
: base ( node )
{
}
}
class sunUndefinedFunctionException : sunNodeException < sunFunctionCall >
{
public override string Message { get { return String . Format ( "Undefined function or builtin '{0}'." , Node . Function . Value ) ; } }
public sunUndefinedFunctionException ( sunFunctionCall node )
: base ( node )
{
}
}
class sunRedefinedFunctionException : sunNodeException < sunFunctionDefinition >
{
public override string Message { get { return String . Format ( "Redefined function '{0}'." , Node . Function . Value ) ; } }
public sunRedefinedFunctionException ( sunFunctionDefinition node )
: base ( node )
{
}
}
class sunUndeclaredVariableException : sunNodeException < sunIdentifier >
{
public override string Message { get { return String . Format ( "Undeclared variable '{0}'." , Node . Value ) ; } }
public sunUndeclaredVariableException ( sunIdentifier node )
: base ( node )
{
}
}
class sunRedeclaredVariableException : sunNodeException < sunIdentifier >
{
public override string Message { get { return String . Format ( "Redeclared variable '{0}'." , Node . Value ) ; } }
public sunRedeclaredVariableException ( sunIdentifier node )
: base ( node )
{
}
}
class sunRedeclaredParameterException : sunNodeException < sunIdentifier >
{
public override string Message { get { return String . Format ( "Redeclared parameter '{0}'." , Node . Value ) ; } }
public sunRedeclaredParameterException ( sunIdentifier node )
: base ( node )
{
}
}
class sunVariadicFunctionException : sunNodeException < sunFunctionDefinition >
{
public override string Message { get { return String . Format ( "Function '{0}' is defined as a variadic function (only builtins may be variadic)." , Node . Function . Value ) ; } }
public sunVariadicFunctionException ( sunFunctionDefinition node )
: base ( node )
{
}
}
class sunEscapeSequenceException : sunNodeException < sunStringLiteral >
{
public override string Message { get { return String . Format ( "Bad escape sequence in string." ) ; } }
public sunEscapeSequenceException ( sunStringLiteral node )
: base ( node )
{
}
}
class sunVariadicParameterListException : sunNodeException < sunParameterList >
{
public override string Message { get { return String . Format ( "Bad variadic parameter list." ) ; } }
public sunVariadicParameterListException ( sunParameterList node )
: base ( node )
{
}
}
class sunArgumentCountException : sunNodeException < sunFunctionCall >
{
public sunCallableSymbolInfo CalledSymbol { get ; private set ; }
public int ArgumentMinimum { get { return CalledSymbol . Parameters . Minimum ; } }
public int ArgumentCount { get { return Node . Arguments . Count ; } }
public override string Message
{
get
{
string format ;
if ( CalledSymbol . Parameters . IsVariadic )
{
// assuming to be missing because there's only a minimum
format = "Missing {0} argument(s) (expected at least {1}; got {2})." ;
}
else if ( Node . Arguments . Count < CalledSymbol . Parameters . Minimum )
{
format = "Missing {0} argument(s) (expected {1}; got {2})." ; // missing arguments
}
else
{
format = "Too many arguments (expected {1}; got {2})." ; // extra arguments
}
return String . Format ( format , ArgumentMinimum - ArgumentCount , ArgumentMinimum , ArgumentCount ) ;
}
}
public sunArgumentCountException ( sunFunctionCall node , sunCallableSymbolInfo calledSymbol )
: base ( node )
{
if ( calledSymbol = = null )
{
throw new ArgumentNullException ( "calledSymbol" ) ;
}
CalledSymbol = calledSymbol ;
}
}
class sunIdentifierException : sunNodeException < sunIdentifier >
{
public override string Message { get { return String . Format ( "Invalid identifier '{0}'." , Node . Value ) ; } }
public sunIdentifierException ( sunIdentifier node )
: base ( node )
{
}
}
class sunMissingImportException : sunNodeException < sunImport >
{
public override string Message { get { return String . Format ( "Could not find import file '{0}'." , Node . ImportFile . Value ) ; } }
public sunMissingImportException ( sunImport node )
: base ( node )
{
}
}
class sunBreakException : sunNodeException < sunBreak >
{
public override string Message { get { return "Break statements must be placed within a loop statement." ; } }
public sunBreakException ( sunBreak node )
: base ( node )
{
}
}
class sunContinueException : sunNodeException < sunContinue >
{
public override string Message { get { return "Continue statements must be placed within a loop statement." ; } }
public sunContinueException ( sunContinue node )
: base ( node )
{
}
}
}