lambda_cat/error.rs
1//! Project-wide error type.
2//!
3//! Every fallible operation in `lambda-cat` returns [`Error`]. The enum covers
4//! lexical, syntactic, and evaluation failures across the pipeline.
5
6use crate::syntax::{Position, VarName};
7
8/// All errors in lambda-cat.
9#[derive(Debug, Clone, PartialEq, Eq)]
10pub enum Error {
11 /// The lexer encountered a character that does not begin any token.
12 UnexpectedChar {
13 /// Byte offset in the source where the character was found.
14 at: Position,
15 /// The offending character.
16 ch: char,
17 },
18 /// Input ended while the parser still required more tokens.
19 UnexpectedEnd {
20 /// Short description of what was expected, e.g. `"expression"`.
21 expected: &'static str,
22 },
23 /// The parser found a token that does not satisfy the current production.
24 UnexpectedToken {
25 /// Byte offset in the source where the offending token began.
26 at: Position,
27 /// Short description of what was expected, e.g. `"identifier"`.
28 expected: &'static str,
29 /// Human-readable rendering of the token that was actually found.
30 found: String,
31 },
32 /// Evaluation referenced a variable not bound in the current environment.
33 UnboundVariable {
34 /// The unbound name.
35 name: VarName,
36 },
37 /// Evaluation exceeded its step budget.
38 FuelExhausted {
39 /// The configured step limit that was hit.
40 limit: u64,
41 },
42}
43
44impl std::fmt::Display for Error {
45 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46 match self {
47 Self::UnexpectedChar { at, ch } => {
48 write!(f, "unexpected character {ch:?} at byte {}", at.value())
49 }
50 Self::UnexpectedEnd { expected } => {
51 write!(f, "unexpected end of input; expected {expected}")
52 }
53 Self::UnexpectedToken {
54 at,
55 expected,
56 found,
57 } => {
58 write!(
59 f,
60 "unexpected token {found:?} at byte {}; expected {expected}",
61 at.value()
62 )
63 }
64 Self::UnboundVariable { name } => {
65 write!(f, "unbound variable {:?}", name.as_str())
66 }
67 Self::FuelExhausted { limit } => {
68 write!(f, "evaluation exceeded step limit of {limit}")
69 }
70 }
71 }
72}
73
74impl std::error::Error for Error {}