Minimal error display for syntax error

master
Araozu 2024-01-02 06:31:27 -05:00
parent 6e2b7da22f
commit ef70bc1cc0
2 changed files with 30 additions and 7 deletions

View File

@ -24,8 +24,8 @@
- [x] Hand-make CLI, remove clap - [x] Hand-make CLI, remove clap
- [x] Compile a single file - [x] Compile a single file
- [ ] Display error messages during compilation instead of panicking - [x] Display error messages during compilation instead of panicking
- [ ] Improve errror messages - [x] Improve error messages
- [ ] Implement code generation for ast nodes implemented as of now - [ ] Implement code generation for ast nodes implemented as of now

View File

@ -1,22 +1,29 @@
use std::collections::VecDeque;
use super::{PrintableError, SyntaxError}; use super::{PrintableError, SyntaxError};
use std::collections::VecDeque;
impl PrintableError for SyntaxError { impl PrintableError for SyntaxError {
fn get_error_str(&self, chars: &Vec<char>) -> String { fn get_error_str(&self, chars: &Vec<char>) -> String {
let (line, before, length) = get_line(chars, self.error_start, self.error_end); let (line, before, length) = get_line(chars, self.error_start, self.error_end);
let line_number = get_line_number(chars, self.error_start);
let line_number_whitespace = " ".repeat(line_number.to_string().len());
let whitespace = vec![' '; before].iter().collect::<String>(); let whitespace = vec![' '; before].iter().collect::<String>();
let indicator = vec!['^'; length].iter().collect::<String>(); let indicator = vec!['^'; length].iter().collect::<String>();
let reason = &self.reason;
format!( format!(
"\n{}\n{}{}\n\n{}{}{}\n{}", r#"
line, whitespace, indicator, "Syntax error at pos ", self.error_start, ":", self.reason {line_number_whitespace} |
{line_number } | {line}
{line_number_whitespace} | {whitespace}{indicator}
{reason} at line {line_number}:{before}"#,
) )
} }
} }
/// Extracts a lin e of code /// Extracts a line of code
/// ///
/// - `chars`: Input where to extract the line from /// - `chars`: Input where to extract the line from
/// - `start_position`: Position where the erroneous code starts /// - `start_position`: Position where the erroneous code starts
@ -90,6 +97,22 @@ fn get_line(
) )
} }
fn get_line_number(chars: &Vec<char>, target_pos: usize) -> usize {
let mut count = 1;
for (pos, char) in chars.iter().enumerate() {
if pos >= target_pos {
break;
}
if *char == '\n' {
count += 1;
}
}
count
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;