diff options
| author | Edvard Thörnros <edvard.thornros@gmail.com> | 2021-01-24 01:15:00 +0100 |
|---|---|---|
| committer | Edvard Thörnros <edvard.thornros@gmail.com> | 2021-01-24 01:15:00 +0100 |
| commit | afefce4eabcae1ab9680909b3edb583dd0300b07 (patch) | |
| tree | 4e9e2f78400ad5c41f05361d8b763636663c6308 /src | |
| parent | e7399f69d7ed962a74c3df8d2de981d6225e2f45 (diff) | |
| download | sylt-afefce4eabcae1ab9680909b3edb583dd0300b07.tar.gz | |
Error messages so sexy and descriptive, you won't belive it
Diffstat (limited to 'src')
| -rw-r--r-- | src/error.rs | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/src/error.rs b/src/error.rs index 14308c8..525dbc6 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,5 +1,8 @@ use std::fmt; +use std::fs::File; +use std::io::{self, BufRead}; use std::path::PathBuf; +use owo_colors::OwoColorize; use crate::compiler::Type; use crate::tokenizer::Token; @@ -31,25 +34,25 @@ impl fmt::Display for ErrorKind { let types = types .iter() .fold(String::new(), |a, v| { format!("{}, {:?}", a, v) }); - write!(f, "Cannot apply {:?} to types {}", op, types) + write!(f, "{} Cannot apply {:?} to types {}", "Type Error".bold(), op, types) } ErrorKind::RuntimeTypeError(op, values) => { let values = values .iter() .fold(String::new(), |a, v| { format!("{}, {:?}", a, v) }); - write!(f, "Cannot apply {:?} to values {}", op, values) + write!(f, "{} Cannot apply {:?} to values {}", "Runtime Type Error".bold(), op, values) } ErrorKind::Assert => { - write!(f, "Assertion failed.") + write!(f, "{}", "Assertion failed".bold()) } ErrorKind::SyntaxError(line, token) => { - write!(f, "Syntax error on line {} at token {:?}", line, token) + write!(f, "{} on line {} at token {:?}", "Syntax Error".bold(), line, token) } ErrorKind::Unreachable => { - write!(f, "Reached unreachable code.") + write!(f, "{}", "Unreachable".bold()) } ErrorKind::InvalidProgram => { - write!(f, "[!!!] Invalid program") + write!(f, "{}", "[!!] Invalid program [!!]".bold()) } } } @@ -58,10 +61,19 @@ impl fmt::Display for ErrorKind { impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let message = match &self.message { - Some(s) => format!("\n{}", s), + Some(s) => format!("\n{} {}", ">>>".red(), s), None => String::from(""), }; - write!(f, "{}:{} {}{}", self.file.display(), self.line, self.kind, message) + + let line = if let Ok(file) = File::open(&self.file) { + io::BufReader::new(file).lines().enumerate() + .filter(|(n, _)| self.line-2 <= *n && *n <= self.line) + .fold(String::from("\n"), |a, (n, l)| format!("{} {:3} | {}\n", a, n.blue(), l.unwrap())) + } else { + String::new() + }; + + write!(f, "\n<{}> {}:{} {}{}{}\n", "ERR".red(), self.file.display().blue(), self.line.blue(), self.kind, message, line) } } |
