narju/error/
mod.rs

1//! The crate-wide error type.
2
3use thiserror::Error;
4
5/// Any error the evaluator or its entry points can produce.
6///
7/// Errors abort the current top-level evaluation and unwind the CK
8/// machine's continuation stack. Two forms survive in-language: a
9/// [`NarjuError::Throw`] raised inside a `catch` arrives at the catch
10/// site with its payload intact, and any *other* error inside a `catch`
11/// arrives stringified via `Display`. The `#[error]` strings here are
12/// therefore user-visible surface, both at the REPL and through
13/// `catch`.
14#[derive(Debug, Error)]
15pub enum NarjuError {
16    /// Malformed source, from the reader or from lowering (which
17    /// reports unbound names at parse time with their surface names).
18    #[error("parse error: {0}")]
19    Parse(String),
20
21    /// A `Var` index past the end of the runtime environment. Lowering
22    /// makes this unreachable from surface source; it can only arise
23    /// from hand-built or mis-translated `Exp` trees, so the message
24    /// reports raw indices — there is no name to report.
25    #[error("unbound variable at level {level} (env len {env_len})")]
26    UnboundVar {
27        /// The out-of-range `Var` index.
28        level: usize,
29        /// Environment length at the point of lookup.
30        env_len: usize,
31    },
32
33    /// A primitive applied to a value of the wrong shape.
34    #[error("type error in {op}: expected {expected}, got {actual}")]
35    TypeError {
36        /// Surface name of the offending operation (e.g. `"car"`).
37        op: &'static str,
38        /// What the operation accepts.
39        expected: &'static str,
40        /// Compact description of what it got — `Val::short_desc`
41        /// output, which never dumps a full code tree.
42        actual: String,
43    },
44
45    /// A staging-discipline violation: lifting the unliftable,
46    /// running at the wrong level, a malformed `trans`/`evalms`
47    /// argument, and the like.
48    #[error("staging error: {0}")]
49    Stage(String),
50
51    /// A failure from the underlying I/O implementation
52    /// (`read`, `read-file`, `print`).
53    #[error("i/o error: {0}")]
54    Io(#[from] std::io::Error),
55
56    /// `(throw v)`: a user-raised error carrying a first-class `Val`
57    /// payload. `unwind_to_catch` unpacks the payload structurally into
58    /// `(error <payload> ())` instead of stringifying it, so structured
59    /// signals like `(unbound . name)` survive to the catch site.
60    #[error("uncaught throw: {}", crate::eval::display(.0))]
61    Throw(crate::core::Val),
62}