use thiserror::Error; use crate::lexer::Token; use crate::misc::CodePos; #[derive(Error, Debug)] pub enum LexerError { #[error("Unexpected character '{c}' at {code_pos}.")] UnexpectedCharacter { c: char, code_pos: CodePos }, #[error("Unterminated string literal starting at {code_pos}.")] UnterminatedStringLiteral { code_pos: CodePos }, #[error("Unterminated block comment starting at {code_pos}.")] UnterminatedBlockComment { code_pos: CodePos }, #[error("Invalid number literal {lexeme} at {code_pos}: {msg}")] InvalidNumberLiteral { lexeme: String, msg: String, code_pos: CodePos, }, } #[derive(Error, Debug)] pub enum ParserError { #[error("Token stream ended unexpectedly.")] TokenStreamEnded, #[error("Unexpected token {token} at {0}.", token.code_pos())] UnexpectedToken { token: Token }, } #[derive(Error, Debug)] pub enum LoxError { #[error("{msg}")] LexerError { msg: String }, #[error("{msg}")] ParserError { msg: String }, } impl From> for LoxError { fn from(lexer_errs: Vec) -> Self { let msg = if lexer_errs.len() == 1 { format!("{}", lexer_errs[0]) } else { let msgs: Vec = lexer_errs.iter().map(|err| format!("{}", err)).collect(); msgs.join("\n") }; LoxError::LexerError { msg } } } impl From for LoxError { fn from(parser_error: ParserError) -> Self { LoxError::ParserError { msg: format!("{parser_error}"), } } }