diff --git a/example/hello_world.vy b/example/hello_world.vy index b88d905..cefeee7 100644 --- a/example/hello_world.vy +++ b/example/hello_world.vy @@ -1 +1,3 @@ -(print '(Hello, World!)) \ No newline at end of file +(print '(Hello, World!)) +(print (format "Hello" (format "World"))) +) \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index e2e28ed..3d638f6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -36,6 +36,8 @@ fn main() { if args_index < args.len() { let file_path: &str = &args[args_index]; let file_content: String = read_to_string(file_path).unwrap(); + // Used for error reporting + let file_content_joined: String = file_content.split("\n").collect::>().join(" "); let parsed = parser::parse(&file_content); let mut ast = Vec::new(); @@ -43,7 +45,7 @@ fn main() { match node { Ok(node) => { ast.push(node); }, Err(error) => { - eprintln!("ERROR: {}", error); + eprintln!("{}", error.at(&file_content_joined)); exit(1); } } diff --git a/src/parser.rs b/src/parser.rs index a0a6f50..a7cb021 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -167,16 +167,15 @@ pub struct ParseError { pub pos: (usize, usize), } -impl fmt::Display for ParseError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{} at {}", self.kind, self.pos.0) - } -} - impl ParseError { fn new(kind: ParseErrorKind, pos: (usize, usize)) -> Self { ParseError { kind, pos } } + + pub fn at(&self, src: &str) -> String { + let snip = &src[(self.pos.0.saturating_sub(5))..(if self.pos.0 + 5 > src.len() { src.len() } else { self.pos.0 + 5 })]; + format!("\n{}..{}\n{}\nError: {} at {}", " ".repeat(3), snip, format!("{}^", " ".repeat(10)), self.kind, self.pos.0) + } } fn read<'a>( @@ -192,7 +191,10 @@ fn read<'a>( match token { "(" => { parenths += 1; - block_start = start; + + if parenths == 1 { + block_start = start; + } stack.push(Tree::List { vec: Vec::new(),