use thiserror::Error;
use crate::Value;
#[derive(Debug, Error, PartialEq)]
pub enum RuntimeError {
#[error("type error: {0}")]
TypeError(String),
#[error("undefined variable: {name}")]
UndefinedVariable { name: String },
#[error("division by zero")]
DivisionByZero,
#[error("integer overflow")]
IntOverflow,
#[error("index out of bounds: index {index} for length {len}")]
IndexOutOfBounds { index: i64, len: usize },
#[error("field not found: {field} on {type_name}")]
FieldNotFound { field: String, type_name: String },
#[error("not callable: {value}")]
NotCallable { value: String },
#[error("arity mismatch: expected {expected} args, got {got}")]
ArityMismatch { expected: usize, got: usize },
#[error("propagated error: {0}")]
Propagated(Box<Value>),
#[error("integer literal parse failed: {0}")]
IntParseFailed(String),
#[error("float literal parse failed: {0}")]
FloatParseFailed(String),
#[error("return")]
Return(Box<Value>),
#[error("break")]
Break(Option<Box<Value>>),
#[error("continue")]
Continue,
#[error("unreachable code reached")]
Unreachable,
#[error("match failed: no arm matched the scrutinee")]
MatchFailed,
#[error("no handler for effect `{effect}`: provide a handler via a `handling` block, module-level `handle`, or project config")]
NoEffectHandler { effect: String },
#[error("not implemented: {0}")]
NotImplemented(String),
#[error("assertion failed: {0}")]
AssertionFailed(String),
}