rlox/src/error.rs

57 lines
1.6 KiB
Rust
Raw Normal View History

2023-01-20 16:10:03 +01:00
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<Vec<LexerError>> for LoxError {
fn from(lexer_errs: Vec<LexerError>) -> Self {
let msg = if lexer_errs.len() == 1 {
format!("{}", lexer_errs[0])
} else {
let msgs: Vec<String> = lexer_errs.iter().map(|err| format!("{}", err)).collect();
msgs.join("\n")
};
LoxError::LexerError { msg }
}
}
impl From<ParserError> for LoxError {
fn from(parser_error: ParserError) -> Self {
LoxError::ParserError {
msg: format!("{parser_error}"),
}
}
}