Display ParseErrors with source
This commit is contained in:
parent
10a324172b
commit
0bbc6e2a62
51
src/ast.rs
51
src/ast.rs
|
@ -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"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue