use crate::tokens::Token;
use thiserror::Error;
#[derive(Error, Debug, PartialEq)]
pub enum SyntaxError {
#[error("Excpected {0} arguments but got {1}.")]
InsufficientArguments(usize, usize),
#[error("Next node called on an empty Token stream")]
EmptyStream,
#[error("Unmatched parenthesis: '{0}'")]
UnmatchedParenthesis(String),
#[error("Unresolved group {0}")]
UnresolvedGroup(String),
#[error("Unhandled tokens {0}")]
UnhandledTokens(String),
#[error("Unexpected token {0:?}")]
UnexpectedToken(Token),
#[error("Unexpected semicolon")]
UnexpectedSemicolon,
#[error("Unknown symbol {0}")]
UnknownSymbol(String),
#[error("Too many inputs")]
TooManyInputs,
#[error("Function without inputs")]
FunctionWithoutInputs,
#[error("Functions must have a single output, but found unparsed tokens: '{0}'")]
FunctionWithUnparsedTokens(String),
#[error("Variable is not allowed to have input arguments")]
VariableWithInput,
#[error(
"Number of variables does not match output arity; got {0} variables but output arity {1}"
)]
IncorrectNumVariables(usize, usize),
#[error("Invalid number format: {0}")]
InvalidNumberFormat(String),
#[error("Expected function but got {0}")]
ExpectedFunction(String),
#[error("Expected binary operator but got {0}")]
ExpectedBinaryOperator(String),
#[error("Expected operator with output arity {0} but got {1}")]
ExpectedOperatorWithOutputArity(usize, String),
#[error("Expected type {0} but got {1}")]
TypeError(String, String),
#[error("Operation with multiple outputs is not supported here.")]
MultipleOutputs,
#[error("Input arity {0} of node {1} exceeds summed output arity {2} of children: {3}")]
InputArityExceedsOutputArity(usize, String, usize, String),
#[error("Function signature {0} does not match expected signature {1}")]
FunctionSignatureMismatch(String, String),
#[error("Function with multiple outputs is not supported yet. Use a group as output instead.")]
FunctionWithMultipleOutputs(usize),
#[error(
"Tried to match multiple types {0} but none of them matched. Longest string has type {1}"
)]
GatherMismatch(String, String),
#[error("Created invalid slice")]
InvalidSlice,
#[error("Invalid type '{0}'")]
InvalidType(String),
#[error("Error inside of lexer: {0}")]
LexerError(String),
#[error("Invalid var statement: {0}")]
InvalidVarStatement(String),
#[error("Invalid assignment statement: {0}")]
InvalidAssignmentStatement(String),
#[error("Not a pure function: {0}")]
NotPureFunction(String),
#[error("Empty input")]
EmptyInput,
#[error("Expected token {0} but got {1}")]
ExpectedToken(String, String),
#[error("Empty slice")]
EmptySlice,
#[error("Function chain is not consistent: {0}")]
FunctionChainInconsistency(String),
#[error(
"Function chain has ambiguous type. It should match exactly one type of the following: {0}"
)]
FunctionChainAmbiguousType(String),
#[error("Function type ambiguous. The slice {0} can resolve to types {1}")]
FunctionTypeAmbiguous(String, String),
#[error("Not implemented: {0}")]
NotImplemented(String),
#[error("Type conversion not possible from {0} to {1}")]
TypeConversionNotPossible(String, String),
#[error("Groups can only return a single function, remaining tokens: {0}")]
GroupReturnsMultipleFunctions(String),
#[error("Empty group")]
EmptyGroup,
#[error("The slice {0} cannot be parsed as a function because {1} is a token without a functional variant")]
SliceCannotBeParsedAsFunction(String, String),
#[error("At least one argument is required")]
EmptyFunctionComposition,
#[error("Tried to retrieve out of bounds token. Index: {0}, length: {1}")]
OutOfBoundsToken(usize, usize),
#[error("None of the function variants {0} match the types of the gathered operands {1}")]
FunctionVariantMismatch(String, String),
#[error("None of the required outputs {0} match the function outputs {1}")]
RequiredOutputsDoNotMatchFunctionOutputs(String, String),
#[error("Cannot infer output number type from operands. Got both {0} and {1}")]
CannotInferOutputNumberType(String, String),
#[error("Number type mismatch {0} and {1}")]
NumberTypeMismatch(String, String),
#[error("Number of variables {0} does not match number of outputs {1} in assignment")]
IncorrectNumberOfVariablesInAssignment(usize, usize),
#[error("Expected group output, but got type {0}")]
ExpectedGroupOutput(String),
#[error("Expected [ token after index operator")]
ExpectedLSqBracketAfterIndex,
#[error("Indexing must either be a tensor or a list of numbers.")]
IndexingMustBeTensorOrNumbers,
#[error("Cannot mix tensor and colon in indexing")]
CannotMixTensorAndColon,
#[error("Invalid enum variant: {0}")]
InvalidEnumVariant(String),
}