cl-interpret: Print function call backtrace on panic

This commit is contained in:
John 2025-09-15 00:18:51 -04:00
parent 62940b3d24
commit df6089f84a
3 changed files with 23 additions and 3 deletions

View File

@ -143,8 +143,17 @@ pub const Builtins: &[Builtin] = &builtins![
Ok(()) Ok(())
} }
fn panic(message) { fn panic(args @ ..) @env {
Err(error_format!("Panic: {message}"))?; use std::fmt::Write;
let mut out = String::new();
if let Err(e) = args.iter().try_for_each(|arg| write!(out, "{arg}")) {
println!("{e}");
}
let mut stdout = stdout().lock();
write!(stdout, "Explicit panic: `").ok();
args.iter().try_for_each(|arg| write!(stdout, "{arg}") ).ok();
writeln!(stdout, "`").ok();
Err(Error::Panic(out))?;
Ok(()) Ok(())
} }

View File

@ -10,7 +10,7 @@ pub type IResult<T> = Result<T, Error>;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Error { pub struct Error {
pub kind: ErrorKind, pub kind: ErrorKind,
span: Option<Span>, pub(super) span: Option<Span>,
} }
impl Error { impl Error {
@ -98,6 +98,10 @@ impl Error {
pub fn MatchNonexhaustive() -> Self { pub fn MatchNonexhaustive() -> Self {
Self { kind: ErrorKind::MatchNonexhaustive, span: None } Self { kind: ErrorKind::MatchNonexhaustive, span: None }
} }
/// Explicit panic
pub fn Panic(msg: String) -> Self {
Self { kind: ErrorKind::Panic(msg, 0), span: None }
}
/// Error produced by a Builtin /// Error produced by a Builtin
pub fn BuiltinError(msg: String) -> Self { pub fn BuiltinError(msg: String) -> Self {
Self { kind: ErrorKind::BuiltinError(msg), span: None } Self { kind: ErrorKind::BuiltinError(msg), span: None }
@ -155,6 +159,8 @@ pub enum ErrorKind {
PatFailed(Box<Pattern>), PatFailed(Box<Pattern>),
/// Fell through a non-exhaustive match /// Fell through a non-exhaustive match
MatchNonexhaustive, MatchNonexhaustive,
/// Explicit panic
Panic(String, usize),
/// Error produced by a Builtin /// Error produced by a Builtin
BuiltinError(String), BuiltinError(String),
} }
@ -205,6 +211,7 @@ impl std::fmt::Display for ErrorKind {
ErrorKind::MatchNonexhaustive => { ErrorKind::MatchNonexhaustive => {
write!(f, "Fell through a non-exhaustive match expression!") write!(f, "Fell through a non-exhaustive match expression!")
} }
ErrorKind::Panic(s, _depth) => write!(f, "Explicit panic: {s}"),
ErrorKind::BuiltinError(s) => write!(f, "{s}"), ErrorKind::BuiltinError(s) => write!(f, "{s}"),
} }
} }

View File

@ -73,6 +73,10 @@ impl Callable for Function {
match res { match res {
Err(Error { kind: ErrorKind::Return(value), .. }) => Ok(value), Err(Error { kind: ErrorKind::Return(value), .. }) => Ok(value),
Err(Error { kind: ErrorKind::Break(value), .. }) => Err(Error::BadBreak(value)), Err(Error { kind: ErrorKind::Break(value), .. }) => Err(Error::BadBreak(value)),
Err(Error { kind: ErrorKind::Panic(msg, depth), span: Some(span) }) => {
println!("{depth:>4}: {name}{bind} at {}", span.head);
Err(Error { kind: ErrorKind::Panic(msg, depth + 1), span: None })
}
other => other, other => other,
} }
} }