use super::{Expression, ExpressionKind, Pattern, Token, TokenKind};
pub type CompilerResult<T> = Result<T, CompilerError>;
#[derive(Debug, Clone)]
pub enum CompilerError {
Generic(String),
DuplicateMethodSignature {
method_name: String,
signature: Option<Pattern>,
},
MethodNotFound(String),
MethodSignatureNotFound {
method_name: String,
pattern: Option<Pattern>,
},
ParserError(ParserError),
}
impl std::fmt::Display for CompilerError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let error_description: String = match self {
Self::Generic(string) => string.clone(),
Self::ParserError(error) => format!("{}", error),
Self::DuplicateMethodSignature { method_name, .. } => format!(
"this method signature has already been defined for the `{}` multimethod",
format!("{}", method_name)
),
Self::MethodNotFound(method_name) => format!(
"cannot find multimethod named `{}`",
format!("{}", method_name)
),
Self::MethodSignatureNotFound {
method_name,
pattern,
} => format!(
"cannot find method signature `{:?}` for `{}`",
pattern, method_name
),
};
write!(f, "{}", error_description)
}
}
impl From<ParserError> for CompilerError {
fn from(e: ParserError) -> Self {
CompilerError::ParserError(e)
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum ParserError {
MissingPrefixParselet(TokenKind),
UnexpectedToken {
expected: TokenKind,
found: Token,
},
UnexpectedEOF,
UnexpectedExpression {
expected: ExpressionKind,
found: Expression,
},
UnexpectedType {
expected: String,
found: Option<String>,
},
UnexpectedPattern {
expected: String,
found: String,
},
ExpectedPattern,
NoMatch,
}
impl std::fmt::Display for ParserError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let error_description = match self {
Self::MissingPrefixParselet(kind) => {
format!("no prefix parselet found for token {:?}", kind)
}
Self::UnexpectedToken { expected, found } => {
format!("expected token {:?}, found {:?}", expected, found)
}
Self::UnexpectedEOF => format!("expected expression, found end of input"),
Self::UnexpectedExpression { expected, found } => {
format!("expected expression {:?}, found {:?}", expected, found)
}
Self::UnexpectedType { expected, found } => {
format!("expected type {:?}, found {:?}", expected, found)
}
Self::UnexpectedPattern { expected, found } => {
format!("expected pattern {:?}, found {:?}", expected, found)
}
Self::ExpectedPattern => format!("expected to find a pattern"),
Self::NoMatch => format!("the given patterns do not match"),
};
write!(f, "{}", error_description)
}
}