1
1
Fork 0
mirror of https://github.com/azur1s/bobbylisp.git synced 2024-10-16 02:37:40 -05:00

error reporting with ariadne

This commit is contained in:
Natapat Samutpong 2022-03-06 22:50:23 +07:00
parent a8aa4569c3
commit cf65687337
5 changed files with 83 additions and 18 deletions

3
Cargo.lock generated
View file

@ -152,6 +152,8 @@ dependencies = [
name = "hycron"
version = "0.1.0"
dependencies = [
"ariadne",
"chumsky",
"clap",
"lexer",
"parser",
@ -205,7 +207,6 @@ dependencies = [
name = "parser"
version = "0.1.0"
dependencies = [
"ariadne",
"chumsky",
"lexer",
]

View file

@ -8,4 +8,6 @@ edition = "2021"
[dependencies]
clap = { version = "3.0.14", features = ["derive"] }
lexer = { path = "../lexer" }
parser = { path = "../parser" }
parser = { path = "../parser" }
chumsky = "0.8.0"
ariadne = "0.1.5"

View file

@ -1,6 +1,7 @@
use std::fs;
use clap::Parser as ArgParser;
use ariadne::{Report, ReportKind, Label, Source, Color, Fmt};
use lexer::lex;
use parser::parse;
@ -22,22 +23,84 @@ fn main() {
// Lex the file.
let (tokens, lex_error) = lex(src.clone());
if lex_error.is_empty() {
log(0, "Lexing successful.");
let (ast, parse_error) = parse(tokens.unwrap(), src.chars().count());
let (ast, parse_error) = parse(tokens.unwrap(), src.chars().count());
lex_error.into_iter()
.map(|e| e.map(|e| e.to_string()))
.chain(parse_error.into_iter().map(|e| e.map(|tok| tok.to_string())))
.for_each(|e| {
let report = Report::build(ReportKind::Error, (), e.span().start);
if parse_error.is_empty() {
let report = match e.reason() {
chumsky::error::SimpleReason::Unclosed { span, delimiter } => report
.with_message(format!(
"Unclosed delimiter {}",
delimiter.fg(Color::Yellow)
))
.with_label(
Label::new(span.clone())
.with_message(format!(
"Expected closing delimiter {}",
delimiter.fg(Color::Yellow)
))
.with_color(Color::Yellow)
)
.with_label(
Label::new(e.span())
.with_message(format!(
"Must be closed before this {}",
e.found()
.unwrap_or(&"end of file".to_string())
.fg(Color::Red)
))
.with_color(Color::Red)
),
chumsky::error::SimpleReason::Unexpected => report
.with_message(format!(
"{}, expected {}",
if e.found().is_some() {"Unexpected token in input" }
else { "Unexpected end of input" },
if e.expected().len() == 0 { "something else".to_string().fg(Color::Green) }
else {
e.expected()
.map(|expected| match expected {
Some(expected) => expected.to_string(),
None => "end of input".to_string()
})
.collect::<Vec<_>>()
.join(", ")
.fg(Color::Green)
}
))
.with_label(
Label::new(e.span())
.with_message(format!(
"Unexpected token {}",
e.found()
.unwrap_or(&"EOF".to_string())
.fg(Color::Red)
))
.with_color(Color::Red)
),
_ => {
println!("{:?}", e);
todo!();
}
};
report.finish().print(Source::from(&src)).unwrap();
});
match ast {
Some(ast) => {
println!("{:#?}", ast);
log(0, "Parsing successful.");
} else {
println!("{:#?}", parse_error);
log(2, "Parsing failed.");
},
None => {
log(2, "Failed to parse.");
}
} else {
println!("{:#?}", lex_error);
log(2, "Lexing failed.");
}
}
}

View file

@ -3,8 +3,8 @@ use std::fmt::Display;
pub fn log<T: Display>(level: i8, msg: T) {
match level {
0 => println!("\x1b[92m[INFO]\x1b[0m {}", msg),
1 => println!("[WARN] {}", msg),
2 => println!("[ERRO] {}", msg),
1 => println!("\x1b[93m[WARN]\x1b[0m {}", msg),
2 => println!("\x1b[91m[ERRS]\x1b[0m {}", msg),
_ => println!("{}", msg),
}
}

View file

@ -7,5 +7,4 @@ edition = "2021"
[dependencies]
lexer = { path = "../lexer" }
chumsky = "0.8.0"
ariadne = "0.1.5"
chumsky = "0.8.0"