245 lines
6.2 KiB
C#
245 lines
6.2 KiB
C#
|
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)
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 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)
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
}
|