diff --git a/compiler/cl-interpret/src/builtin.rs b/compiler/cl-interpret/src/builtin.rs index 8d03883..3f49836 100644 --- a/compiler/cl-interpret/src/builtin.rs +++ b/compiler/cl-interpret/src/builtin.rs @@ -143,8 +143,17 @@ pub const Builtins: &[Builtin] = &builtins![ Ok(()) } - fn panic(message) { - Err(error_format!("Panic: {message}"))?; + fn panic(args @ ..) @env { + 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(()) } diff --git a/compiler/cl-interpret/src/error.rs b/compiler/cl-interpret/src/error.rs index f3a039f..a9ed24e 100644 --- a/compiler/cl-interpret/src/error.rs +++ b/compiler/cl-interpret/src/error.rs @@ -10,7 +10,7 @@ pub type IResult = Result; #[derive(Clone, Debug)] pub struct Error { pub kind: ErrorKind, - span: Option, + pub(super) span: Option, } impl Error { @@ -98,6 +98,10 @@ impl Error { pub fn MatchNonexhaustive() -> Self { 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 pub fn BuiltinError(msg: String) -> Self { Self { kind: ErrorKind::BuiltinError(msg), span: None } @@ -155,6 +159,8 @@ pub enum ErrorKind { PatFailed(Box), /// Fell through a non-exhaustive match MatchNonexhaustive, + /// Explicit panic + Panic(String, usize), /// Error produced by a Builtin BuiltinError(String), } @@ -205,6 +211,7 @@ impl std::fmt::Display for ErrorKind { ErrorKind::MatchNonexhaustive => { write!(f, "Fell through a non-exhaustive match expression!") } + ErrorKind::Panic(s, _depth) => write!(f, "Explicit panic: {s}"), ErrorKind::BuiltinError(s) => write!(f, "{s}"), } } diff --git a/compiler/cl-interpret/src/function.rs b/compiler/cl-interpret/src/function.rs index 39cd711..7557fdf 100644 --- a/compiler/cl-interpret/src/function.rs +++ b/compiler/cl-interpret/src/function.rs @@ -73,6 +73,10 @@ impl Callable for Function { match res { Err(Error { kind: ErrorKind::Return(value), .. }) => Ok(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, } }