Skip to main content

cl_lexer/
error.rs

1use cl_structures::span::Span;
2
3#[derive(Clone, Copy, Debug, PartialEq, Eq)]
4pub struct LexError {
5    pub pos: Span,
6    pub res: LexFailure,
7}
8
9impl std::error::Error for LexError {}
10impl std::fmt::Display for LexError {
11    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12        let Self { pos, res } = self;
13        write!(f, "{pos}: {res}")
14    }
15}
16
17#[derive(Clone, Copy, Debug, PartialEq, Eq)]
18pub enum LexFailure {
19    /// Reached end of file
20    EOF,
21    UnexpectedEOF,
22    Unexpected(char),
23    UnterminatedBlockComment,
24    UnterminatedCharacter,
25    UnterminatedString,
26    UnterminatedUnicodeEscape,
27    InvalidUnicodeEscape(u32),
28    InvalidDigitForBase(char, u32),
29    IntegerOverflow,
30}
31pub use LexFailure::{EOF, UnexpectedEOF};
32
33impl std::fmt::Display for LexFailure {
34    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35        match self {
36            Self::EOF => "EOF".fmt(f),
37            Self::UnexpectedEOF => "Unexpected EOF".fmt(f),
38            Self::Unexpected(c) => write!(f, "Character {c:?}"),
39            Self::UnterminatedBlockComment => "Unterminated Block Comment".fmt(f),
40            Self::UnterminatedCharacter => "Unterminated Character".fmt(f),
41            Self::UnterminatedString => "Unterminated String".fmt(f),
42            Self::UnterminatedUnicodeEscape => "Unterminated Unicode Escape".fmt(f),
43            Self::InvalidUnicodeEscape(hex) => {
44                write!(f, "'\\u{{{hex:x}}}' is not a valid UTF-8 codepoint")
45            }
46            Self::InvalidDigitForBase(digit, base) => {
47                write!(f, "Invalid digit {digit} for base {base}")
48            }
49            Self::IntegerOverflow => "Integer literal does not fit in 128 bits".fmt(f),
50        }
51    }
52}