Display ParseErrors with source

This commit is contained in:
mars 2022-10-11 02:35:34 -06:00
parent 10a324172b
commit 0bbc6e2a62
2 changed files with 53 additions and 4 deletions

View File

@ -1,6 +1,6 @@
use std::ops::Range;
use std::fmt::{Debug, Display};
use std::ops::{Deref, Range};
use std::sync::Arc;
use std::{fmt::Debug, ops::Deref};
use logos::{Lexer, Logos};
@ -262,6 +262,35 @@ impl<T: Debug> Debug for WithSource<T> {
}
}
impl<T: Debug + Display> Display for WithSource<T> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
writeln!(f, " {}", self.inner)?;
for line_idx in self.range.start.row..=self.range.end.row {
let line = &self.source.lines[line_idx];
writeln!(f, " {:<4}| {}", line_idx + 1, line)?;
let start = if line_idx == self.range.start.row {
self.range.start.col
} else {
0
};
let end = if line_idx == self.range.end.row {
self.range.end.col
} else {
line.len()
};
let spaces: String = std::iter::repeat(" ").take(start).collect();
let carats: String = std::iter::repeat("^").take(end - start).collect();
writeln!(f, " |{}{}", spaces, carats)?;
}
Ok(())
}
}
impl<T> AsRef<T> for WithSource<T> {
fn as_ref(&self) -> &T {
&self.inner
@ -380,3 +409,21 @@ pub enum ParseErrorKind {
UnexpectedToken(TokenKind, Option<TokenKind>),
UnexpectedEof,
}
impl Display for ParseErrorKind {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "Error: ")?;
use ParseErrorKind::*;
match self {
InvalidToken => write!(f, "Invalid token"),
DuplicateArgument(name) => write!(f, "Duplicate {} argument", name),
UnmatchedParen => write!(f, "Unmatched parentheses"),
UnexpectedToken(kind, Some(expected)) => {
write!(f, "Unexpected {:?} token (expected {:?})", kind, expected)
}
UnexpectedToken(kind, None) => write!(f, "Unexpected token {:?}", kind),
UnexpectedEof => write!(f, "Unexpected end-of-file"),
}
}
}

View File

@ -19,9 +19,11 @@ fn main() {
let source = std::sync::Arc::new(ast::Source::from_string(src.clone()));
let mut ast_builder = ast::AstBuilder::new(&source);
let body = ast_builder.expect_value();
println!("{:#?}", body);
match ast_builder.expect_value() {
Ok(body) => println!("{:#?}", body),
Err(e) => panic!("Parse error:\n{}", e),
}
let options = lexpr::parse::Options::new()
.with_string_syntax(lexpr::parse::StringSyntax::Elisp)