1
0

261 lines
7.6 KiB
Rust
Raw Normal View History

2024-12-10 10:03:11 -05:00
use std::num::{ParseFloatError, ParseIntError};
use smallvec::{smallvec, SmallVec};
use crate::{AnnotatedError, LexError, Scope, Span, TokenKind, TokenOwned, Type, TypeConflict};
/// Compilation errors
#[derive(Clone, Debug, PartialEq)]
pub enum CompileError {
// Token errors
ExpectedToken {
expected: TokenKind,
found: TokenOwned,
position: Span,
},
ExpectedTokenMultiple {
expected: &'static [TokenKind],
found: TokenOwned,
position: Span,
},
// Parsing errors
ComparisonChain {
2024-12-10 10:03:11 -05:00
position: Span,
},
2024-12-10 16:04:36 -05:00
ExpectedBoolean {
found: TokenOwned,
position: Span,
},
2024-12-10 10:03:11 -05:00
ExpectedExpression {
found: TokenOwned,
position: Span,
},
ExpectedFunction {
found: TokenOwned,
actual_type: Type,
position: Span,
},
ExpectedFunctionType {
found: Type,
position: Span,
},
InvalidAssignmentTarget {
found: TokenOwned,
position: Span,
},
UnexpectedReturn {
position: Span,
},
// Variable errors
CannotMutateImmutableVariable {
identifier: String,
position: Span,
},
ExpectedMutableVariable {
found: TokenOwned,
position: Span,
},
UndeclaredVariable {
identifier: String,
position: Span,
},
VariableOutOfScope {
identifier: String,
variable_scope: Scope,
access_scope: Scope,
position: Span,
},
// Type errors
CannotAddType {
argument_type: Type,
position: Span,
},
CannotAddArguments {
left_type: Type,
left_position: Span,
right_type: Type,
right_position: Span,
},
CannotDivideType {
argument_type: Type,
position: Span,
},
CannotDivideArguments {
left_type: Type,
right_type: Type,
position: Span,
},
CannotModuloType {
argument_type: Type,
position: Span,
},
CannotModuloArguments {
left_type: Type,
right_type: Type,
position: Span,
},
CannotMultiplyType {
argument_type: Type,
position: Span,
},
CannotMultiplyArguments {
left_type: Type,
right_type: Type,
position: Span,
},
CannotSubtractType {
argument_type: Type,
position: Span,
},
CannotSubtractArguments {
left_type: Type,
right_type: Type,
position: Span,
},
CannotResolveRegisterType {
register_index: usize,
position: Span,
},
CannotResolveVariableType {
identifier: String,
position: Span,
},
IfElseBranchMismatch {
conflict: TypeConflict,
position: Span,
},
IfMissingElse {
position: Span,
},
ListItemTypeConflict {
conflict: TypeConflict,
position: Span,
},
ReturnTypeConflict {
conflict: TypeConflict,
position: Span,
},
// Chunk errors
ConstantIndexOutOfBounds {
index: usize,
position: Span,
},
InstructionIndexOutOfBounds {
index: usize,
position: Span,
},
LocalIndexOutOfBounds {
index: usize,
position: Span,
},
// Wrappers around foreign errors
Lex(LexError),
ParseFloatError {
error: ParseFloatError,
position: Span,
},
ParseIntError {
error: ParseIntError,
position: Span,
},
}
impl CompileError {}
impl AnnotatedError for CompileError {
fn title() -> &'static str {
"Compilation Error"
}
fn description(&self) -> &'static str {
match self {
Self::CannotAddArguments { .. } => "Cannot add these types",
Self::CannotAddType { .. } => "Cannot add to this type",
Self::ComparisonChain { .. } => "Cannot chain comparison operations",
2024-12-10 10:03:11 -05:00
Self::CannotDivideArguments { .. } => "Cannot divide these types",
Self::CannotDivideType { .. } => "Cannot divide this type",
Self::CannotModuloArguments { .. } => "Cannot modulo these types",
Self::CannotModuloType { .. } => "Cannot modulo this type",
Self::CannotMutateImmutableVariable { .. } => "Cannot mutate immutable variable",
Self::CannotMultiplyArguments { .. } => "Cannot multiply these types",
Self::CannotMultiplyType { .. } => "Cannot multiply this type",
Self::CannotResolveRegisterType { .. } => "Cannot resolve register type",
Self::CannotResolveVariableType { .. } => "Cannot resolve type",
Self::CannotSubtractType { .. } => "Cannot subtract from this type",
Self::CannotSubtractArguments { .. } => "Cannot subtract these types",
Self::ConstantIndexOutOfBounds { .. } => "Constant index out of bounds",
2024-12-10 16:04:36 -05:00
Self::ExpectedBoolean { .. } => "Expected a boolean",
2024-12-10 10:03:11 -05:00
Self::ExpectedExpression { .. } => "Expected an expression",
Self::ExpectedFunction { .. } => "Expected a function",
Self::ExpectedFunctionType { .. } => "Expected a function type",
Self::ExpectedMutableVariable { .. } => "Expected a mutable variable",
Self::ExpectedToken { .. } => "Expected a specific token",
Self::ExpectedTokenMultiple { .. } => "Expected one of multiple tokens",
Self::IfElseBranchMismatch { .. } => "Type mismatch in if/else branches",
Self::IfMissingElse { .. } => "If statement missing else branch",
Self::InstructionIndexOutOfBounds { .. } => "Instruction index out of bounds",
Self::InvalidAssignmentTarget { .. } => "Invalid assignment target",
Self::Lex(error) => error.description(),
Self::ListItemTypeConflict { .. } => "List item type conflict",
Self::LocalIndexOutOfBounds { .. } => "Local index out of bounds",
Self::ParseFloatError { .. } => "Failed to parse float",
Self::ParseIntError { .. } => "Failed to parse integer",
Self::ReturnTypeConflict { .. } => "Return type conflict",
Self::UndeclaredVariable { .. } => "Undeclared variable",
Self::UnexpectedReturn { .. } => "Unexpected return",
Self::VariableOutOfScope { .. } => "Variable out of scope",
}
}
fn detail_snippets(&self) -> SmallVec<[(String, Span); 2]> {
match self {
Self::CannotAddArguments {
left_type,
left_position,
right_type,
right_position,
} => {
smallvec![
(
format!("A value of type \"{left_type}\" was used here."),
*left_position
),
(
format!("A value of type \"{right_type}\" was used here."),
*right_position
)
]
}
2024-12-17 07:10:47 -05:00
_ => SmallVec::new(),
2024-12-10 10:03:11 -05:00
}
}
fn help_snippets(&self) -> SmallVec<[(String, Span); 2]> {
match self {
Self::CannotAddArguments {
left_type,
left_position,
right_type,
right_position,
} => {
smallvec![(
format!("Type \"{left_type}\" cannot be added to type \"{right_type}\". Try converting one of the values to the other type."),
Span(left_position.0, right_position.1)
)]
}
2024-12-17 07:10:47 -05:00
_ => SmallVec::new(),
2024-12-10 10:03:11 -05:00
}
}
}
impl From<LexError> for CompileError {
fn from(error: LexError) -> Self {
Self::Lex(error)
}
}