Improved error reports
This commit is contained in:
parent
331506af1b
commit
bbbfed7913
16
Cargo.lock
generated
16
Cargo.lock
generated
|
@ -61,6 +61,15 @@ dependencies = [
|
||||||
"x11rb",
|
"x11rb",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ariadne"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f1cb2a2046bea8ce5e875551f5772024882de0b540c7f93dfc5d6cf1ca8b030c"
|
||||||
|
dependencies = [
|
||||||
|
"yansi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atomic_refcell"
|
name = "atomic_refcell"
|
||||||
version = "0.1.8"
|
version = "0.1.8"
|
||||||
|
@ -1556,6 +1565,7 @@ dependencies = [
|
||||||
name = "web-lisp"
|
name = "web-lisp"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"ariadne",
|
||||||
"chumsky",
|
"chumsky",
|
||||||
"eframe",
|
"eframe",
|
||||||
"logos",
|
"logos",
|
||||||
|
@ -1745,3 +1755,9 @@ name = "xml-rs"
|
||||||
version = "0.8.4"
|
version = "0.8.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3"
|
checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yansi"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
|
||||||
|
|
|
@ -6,7 +6,8 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
logos = "*"
|
ariadne = "0.1"
|
||||||
eframe = "*"
|
|
||||||
chumsky = "0.8"
|
chumsky = "0.8"
|
||||||
|
eframe = "*"
|
||||||
|
logos = "*"
|
||||||
ordered-float = "3.0"
|
ordered-float = "3.0"
|
||||||
|
|
85
src/error.rs
Normal file
85
src/error.rs
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
use crate::lexer::Token;
|
||||||
|
use ariadne::{Color, Fmt, Label, Report, ReportKind, Source};
|
||||||
|
use chumsky::error::{Simple, SimpleReason};
|
||||||
|
use std::fmt::Display;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum Error<'a> {
|
||||||
|
Parse(Simple<Token<'a>>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Error<'a> {
|
||||||
|
pub fn report(&self, src: &str) -> std::io::Result<()> {
|
||||||
|
match self {
|
||||||
|
Error::Parse(e) => {
|
||||||
|
let report =
|
||||||
|
Report::<std::ops::Range<usize>>::build(ReportKind::Error, (), e.span().start);
|
||||||
|
match e.reason() {
|
||||||
|
SimpleReason::Unexpected => report
|
||||||
|
.with_message(match e.found() {
|
||||||
|
Some(Token::Error) => {
|
||||||
|
format!("Invalid token: {}", &src[e.span()].fg(Color::Yellow))
|
||||||
|
}
|
||||||
|
Some(t) => format!("Unexpected token `{t:?}`"),
|
||||||
|
None => "Unexpected end of input".to_owned(),
|
||||||
|
})
|
||||||
|
.with_label(
|
||||||
|
Label::new(e.span())
|
||||||
|
.with_message(format!(
|
||||||
|
"Expected: {}",
|
||||||
|
e.expected()
|
||||||
|
.map(|exp| match exp {
|
||||||
|
Some(expected) => format!("{expected:?}"),
|
||||||
|
None => "end of input".to_owned(),
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(", ")
|
||||||
|
))
|
||||||
|
.with_color(Color::Red),
|
||||||
|
),
|
||||||
|
SimpleReason::Unclosed { span, delimiter } => {
|
||||||
|
let msg = format!(
|
||||||
|
"Unclosed delimiter: {:?}",
|
||||||
|
format!("{delimiter:?}").fg(Color::Yellow)
|
||||||
|
);
|
||||||
|
report
|
||||||
|
.with_message(&msg)
|
||||||
|
.with_label(
|
||||||
|
Label::new(span.clone())
|
||||||
|
.with_message(msg)
|
||||||
|
.with_color(Color::Red),
|
||||||
|
)
|
||||||
|
.with_label(
|
||||||
|
Label::new(e.span())
|
||||||
|
.with_message(format!(
|
||||||
|
"Must be closed before {}",
|
||||||
|
match e.found() {
|
||||||
|
Some(x) => format!("{x:?}"),
|
||||||
|
None => "the end of input".to_owned(),
|
||||||
|
}
|
||||||
|
))
|
||||||
|
.with_color(Color::Yellow),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
SimpleReason::Custom(msg) => report.with_message(msg).with_label(
|
||||||
|
Label::new(e.span())
|
||||||
|
.with_message(msg.fg(Color::Red))
|
||||||
|
.with_color(Color::Red),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
.finish()
|
||||||
|
.print(Source::from(&src))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Display for Error<'a> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Error::Parse(e) => write!(f, "{e:?}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> std::error::Error for Error<'a> {}
|
|
@ -1,3 +1,4 @@
|
||||||
|
pub mod error;
|
||||||
pub mod lexer;
|
pub mod lexer;
|
||||||
pub mod list;
|
pub mod list;
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
|
|
14
src/main.rs
14
src/main.rs
|
@ -1,17 +1,21 @@
|
||||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||||
|
|
||||||
use web_lisp::parser;
|
use web_lisp::{error::Error, parser};
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
match parser::read(&std::fs::read_to_string(
|
let src = std::fs::read_to_string(std::env::args().nth(1).ok_or("no filename provided")?)?;
|
||||||
std::env::args().nth(1).ok_or("no filename provided")?,
|
|
||||||
)?) {
|
match parser::read(&src) {
|
||||||
Ok(vals) => {
|
Ok(vals) => {
|
||||||
for val in vals {
|
for val in vals {
|
||||||
println!("{val}");
|
println!("{val}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => eprintln!("Parse error: {e:?}"),
|
Err(errs) => {
|
||||||
|
for err in errs {
|
||||||
|
Error::Parse(err).report(&src)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
Loading…
Reference in a new issue