use crate::errors::panic; use crate::value::Value; use crate::vm::CallFrame; #[derive(Debug, Clone, PartialEq)] pub enum PanicMsg { NoLetMatch, NoFnMatch, NoMatch, Generic(String), } impl std::fmt::Display for PanicMsg { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { use PanicMsg::*; match self { NoLetMatch => write!(f, "no match in `let`"), NoFnMatch => write!(f, "no match calling fn"), NoMatch => write!(f, "no match in `match` form"), Generic(s) => write!(f, "{s}"), } } } #[derive(Debug, Clone, PartialEq)] pub struct Panic { pub msg: PanicMsg, pub scrutinee: Option, pub call_stack: Vec, } fn frame_dump(frame: &CallFrame) -> String { let dump = format!("stack name: {}\nspans: {:?}", frame, frame.chunk().spans); dump } impl std::fmt::Display for Panic { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { let stub_trace = self .call_stack .iter() .map(frame_dump) .collect::>() .join("\n"); write!(f, "Panic: {}\n{stub_trace}", self.msg) } }