From ba8bf3b5edf20649a5010041264f209458db6028 Mon Sep 17 00:00:00 2001 From: Devon Tingley Date: Sat, 11 Mar 2023 09:23:47 -0500 Subject: [PATCH] Switch lexer to use anyhow for errors --- src/lexer/error.rs | 16 ------------- src/lexer/mod.rs | 10 ++++---- src/lexer/tokens.rs | 58 +++++++++++++++++++++++++++++++++++---------- 3 files changed, 50 insertions(+), 34 deletions(-) delete mode 100644 src/lexer/error.rs diff --git a/src/lexer/error.rs b/src/lexer/error.rs deleted file mode 100644 index 4bdd46c..0000000 --- a/src/lexer/error.rs +++ /dev/null @@ -1,16 +0,0 @@ -#[derive(Debug)] -pub enum LexerError { - IllegalToken, - InvalidToken, -} - -impl std::error::Error for LexerError {} - -impl std::fmt::Display for LexerError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - LexerError::IllegalToken => write!(f, "illegal token found; only ascii is valid"), - LexerError::InvalidToken => write!(f, "improper token type"), - } - } -} diff --git a/src/lexer/mod.rs b/src/lexer/mod.rs index e39e683..775e474 100644 --- a/src/lexer/mod.rs +++ b/src/lexer/mod.rs @@ -1,12 +1,12 @@ -mod error; mod tokens; use std::{iter::Peekable, str::Chars}; -pub use error::LexerError; +use anyhow::{bail, Result}; + pub use tokens::{InfixOperator, Keyword, PrefixOperator, Term, Token, Tokens}; -pub fn tokenize(input: &str) -> Result { +pub fn tokenize(input: &str) -> Result { let mut input = input.chars().into_iter().peekable(); let mut tokens = Vec::new(); @@ -17,7 +17,7 @@ pub fn tokenize(input: &str) -> Result { Ok(tokens.into_iter().peekable()) } -fn next_token(input: &mut Peekable) -> Result, LexerError> { +fn next_token(input: &mut Peekable) -> Result> { let tok = match input.next() { Some(tok) => tok, None => return Ok(None), @@ -70,7 +70,7 @@ fn next_token(input: &mut Peekable) -> Result, LexerError> None => return Ok(None), }, - _ => return Err(LexerError::IllegalToken), + _ => bail!("illegal token"), }; Ok(Some(tok)) diff --git a/src/lexer/tokens.rs b/src/lexer/tokens.rs index 312af4c..097a477 100644 --- a/src/lexer/tokens.rs +++ b/src/lexer/tokens.rs @@ -1,7 +1,7 @@ use std::iter::Peekable; use std::vec::IntoIter; -use super::LexerError; +use anyhow::{bail, Result}; pub type Tokens = Peekable>; @@ -48,6 +48,38 @@ pub enum Token { RightBrace, } +impl std::fmt::Display for Token { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Token::Assign => write!(f, "="), + Token::Function => write!(f, "fn"), + Token::Let => write!(f, "let"), + Token::If => write!(f, "if"), + Token::Else => write!(f, "else"), + Token::Return => write!(f, "return"), + Token::Ident(tok) => write!(f, "{}", tok), + Token::Int(tok) => write!(f, "{}", tok), + Token::True => write!(f, "true"), + Token::False => write!(f, "false"), + Token::Bang => write!(f, "!"), + Token::Plus => write!(f, "+"), + Token::Minus => write!(f, "-"), + Token::Asterisk => write!(f, "*"), + Token::ForwardSlash => write!(f, "/"), + Token::Equal => write!(f, "="), + Token::NotEqual => write!(f, "!="), + Token::LessThan => write!(f, "<"), + Token::GreaterThan => write!(f, ">"), + Token::Comma => write!(f, ","), + Token::Semicolon => write!(f, ";"), + Token::LeftParenthesis => write!(f, "("), + Token::RightParenthesis => write!(f, ")"), + Token::LeftBrace => write!(f, "{{"), + Token::RightBrace => write!(f, "}}"), + } + } +} + // ==================== Token Types ==================== // Terms #[derive(Debug, PartialEq, PartialOrd, Clone)] @@ -68,16 +100,16 @@ impl Term { } impl TryFrom for Term { - type Error = LexerError; + type Error = anyhow::Error; - fn try_from(token: Token) -> Result { + fn try_from(token: Token) -> Result { let term = match token { Token::Ident(val) => Term::Ident(val), Token::Int(val) => Term::Int(val), Token::True => Term::True, Token::False => Term::False, - _ => return Err(LexerError::InvalidToken), + tok => bail!("invalid token: {} is not a term", tok), }; Ok(term) @@ -94,16 +126,16 @@ pub enum PrefixOperator { } impl TryFrom<&Token> for PrefixOperator { - type Error = LexerError; + type Error = anyhow::Error; - fn try_from(token: &Token) -> Result { + fn try_from(token: &Token) -> Result { let term = match token { Token::Bang => Self::Bang, Token::Minus => Self::Minus, Token::If => Self::If, Token::Function => Self::Function, - _ => return Err(LexerError::InvalidToken), + tok => bail!("invalid token: {} is not a prefix operator", tok), }; Ok(term) @@ -139,9 +171,9 @@ impl InfixOperator { } impl TryFrom<&Token> for InfixOperator { - type Error = LexerError; + type Error = anyhow::Error; - fn try_from(token: &Token) -> Result { + fn try_from(token: &Token) -> Result { let term = match token { Token::Plus => Self::Plus, Token::Minus => Self::Minus, @@ -155,7 +187,7 @@ impl TryFrom<&Token> for InfixOperator { Token::LeftParenthesis => Self::Call, - _ => return Err(LexerError::InvalidToken), + tok => bail!("invalid token: {} is not an infix operator", tok), }; Ok(term) @@ -176,14 +208,14 @@ impl Keyword { } impl TryFrom<&Token> for Keyword { - type Error = LexerError; + type Error = anyhow::Error; - fn try_from(token: &Token) -> Result { + fn try_from(token: &Token) -> Result { let term = match token { Token::Let => Self::Let, Token::Return => Self::Return, - _ => return Err(LexerError::InvalidToken), + tok => bail!("invalid token: {} is not a keyword", tok), }; Ok(term)