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 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}