Skip to content

Commit

Permalink
refactor: ♻️ simplify error display fmt
Browse files Browse the repository at this point in the history
  • Loading branch information
wowkster committed Aug 6, 2023
1 parent 3ce474a commit 61b8edb
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 57 deletions.
61 changes: 9 additions & 52 deletions compiler/src/frontend/lexer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ use crate::{
frontend::reader::CharacterReader,
};

use self::token::{TokenKind, IntegerLiteralKind, Token, KeywordKind};
use self::token::{IntegerLiteralKind, KeywordKind, Token, TokenKind};

use super::position::highlight_span;

pub mod token;
mod test;
pub mod token;

/// Represents an error when lexing a file
#[derive(Debug)]
Expand Down Expand Up @@ -57,55 +59,6 @@ pub enum LexerErrorKind {

impl Display for LexerError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(
f,
"{}:{}",
match &self.source_file.path {
Some(file) => file
.canonicalize()
.expect("Could not canonicalize file path")
.to_str()
.expect("Could not convert file path to string")
.trim_start_matches(r"\\?\")
.to_owned(),
None => "<literal string>".to_owned(),
},
self.position
)?;

let lines: Vec<_> = self.source_file.content.lines().collect();

// Print the lines around and including the one with the error
let start = if self.position.row < 2 {
0
} else {
self.position.row - 2
} as usize;

// Print each line and the line number
for (n, line) in lines[start..(self.position.row + 1) as usize]
.iter()
.enumerate()
{
writeln!(f, "{:>3}: {}", n + start + 1, line)?;
}

// Print the space before the highlight
for _ in 0..self.position.col + 5 {
write!(f, " ")?;
}

// Print the underline highlight
writeln!(f, "^")?;

// Print the space before "here"
for _ in 0..self.position.col + 5 {
write!(f, " ")?;
}

writeln!(f, "here")?;
writeln!(f)?;

match &self.kind {
LexerErrorKind::UnexpectedChar(c) => writeln!(f, "Unexpected char `{c}`"),
LexerErrorKind::UnclosedWrappedLiteral(kind) => {
Expand All @@ -126,7 +79,11 @@ impl Display for LexerError {
LexerErrorKind::UnexpectedCharactersInIntegerLiteral(kind) => {
writeln!(f, "Unexpected characters inside {kind:?} integer literal")
}
}
}?;

highlight_span(f, &self.source_file, Span::from_position(&self.position))?;

Ok(())
}
}

Expand Down
10 changes: 5 additions & 5 deletions compiler/src/frontend/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,17 +137,17 @@ impl Display for ParserError {
f,
"Unexpected token {:?}. Expected one of: {:?}",
found, expected
)?,
),
ParserErrorKind::UnexpectedKeyword { expected, found } => writeln!(
f,
"Unexpected keyword {:?}. Expected one of: {:?}",
found, expected
)?,
ParserErrorKind::UnexpectedEndOfInput => writeln!(f, "Unexpected end of input.")?,
),
ParserErrorKind::UnexpectedEndOfInput => writeln!(f, "Unexpected end of input."),
ParserErrorKind::IndexIntoNonIdentifier => {
writeln!(f, "Cannot access field of non-struct object.")?
writeln!(f, "Cannot access field of non-struct object.")
}
}
}?;

highlight_span(f, &self.source_file, self.span.clone())?;

Expand Down
12 changes: 12 additions & 0 deletions compiler/src/frontend/position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,18 @@ impl Span {
Self { start, end }
}

pub fn from_position(pos: &Position) -> Self {
let end = Position {
row: pos.row,
col: pos.col + 1,
};

Self {
start: pos.clone(),
end,
}
}

pub fn start(&self) -> &Position {
&self.start
}
Expand Down

0 comments on commit 61b8edb

Please sign in to comment.