1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
use super::Token; use std::{error::Error, fmt::Display, fmt::Formatter}; pub type LexResult<T> = Result<T, LexError>; pub type LiteralResult<T> = Result<T, LiteralParseError>; #[derive(Debug)] pub enum LexError { TokenAfterLineContinue(Token), ExpectedChar(String, String), UnexpectedChar(char), LoneChar(char), TrailingEscape, InvalidEscapedChar(char), LiteralError(LiteralParseError), ErrorWrapper(String, usize, Box<dyn Error>), } #[derive(Debug)] pub enum LiteralParseError { ExpectedBinary, ExpectedHex, InvalidDouble(String), InvalidBinary(String), InvalidHex(String), InvalidInt(String), BinaryTooLarge(String), HexTooLarge(String), IntTooLarge(String), } impl Error for LexError {} impl Error for LiteralParseError {} impl Display for LexError { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { LexError::TokenAfterLineContinue(token) => { write!( f, "Error parsing, \\ should only be followed by a newline. Found: {}", token.as_str() ) } LexError::ExpectedChar(found, expected) => { write!(f, "Found {}, expected {}", found, expected) } LexError::UnexpectedChar(c) => { write!(f, "Unexpected char {} while parsing token", c) } LexError::LoneChar(c) => { write!(f, "Found line {} char", c) } LexError::TrailingEscape => { write!( f, "Found trailing \\, consider \\\\ or finishing the escape sequence" ) } LexError::InvalidEscapedChar(c) => { write!(f, "\\{} is not a valid escape sequence", c) } LexError::LiteralError(e) => { write!(f, "{}", e) } LexError::ErrorWrapper(file, line, e) => { write!( f, "Error lexing input in file {} line {}. {}.", file, line, e ) } } } } impl Display for LiteralParseError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { LiteralParseError::ExpectedBinary => { write!(f, "Found characters 0b, expected binary literal") } LiteralParseError::ExpectedHex => { write!(f, "Found characters 0x, expected hex literal") } LiteralParseError::InvalidDouble(d) => { write!(f, "Invalid double literal {}", d) } LiteralParseError::InvalidBinary(b) => { write!(f, "Invalid binary literal {}", b) } LiteralParseError::InvalidHex(x) => { write!(f, "Invalid hex literal {}", x) } LiteralParseError::InvalidInt(i) => { write!(f, "Invalid int literal {}", i) } LiteralParseError::BinaryTooLarge(b) => { write!( f, "Binary literal {} too large to fit into 32-bit integer", b ) } LiteralParseError::HexTooLarge(x) => { write!( f, "Hexadecimal literal {} too large to fit into 32-bit integer", x ) } LiteralParseError::IntTooLarge(i) => { write!( f, "Integer literal {} too large to fit into 32-bit integer", i ) } } } }