use strum::{AsRefStr, EnumString}; use crate::diagnostic::span::Span; #[derive(Debug, Clone, PartialEq, Eq)] pub struct Token { pub value: TokenValue, pub span: Span, } #[derive(Debug, Clone, PartialEq, Eq)] pub enum TokenValue { IntLit(i64), // TODO: more literal types Ident(String), TypeIdent(TypeIdent), Plus, Minus, Star, Slash, Percent, Equal, DoubleEqual, Not, NotEqual, Less, LessEqual, Greater, GreaterEqual, And, Or, LParen, RParen, LBrace, RBrace, LBracket, RBracket, Comma, Semicolon, If, Else, While, Return, Break, Continue, Eof, Unrecognized, } impl TokenValue { pub fn as_type_ident(&self) -> Option { if let TokenValue::TypeIdent(t) = self { Some(t.clone()) } else { None } } pub fn as_ident(&self) -> Option { if let TokenValue::Ident(s) = self { Some(s.clone()) } else { None } } } impl std::fmt::Display for TokenValue { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { TokenValue::IntLit(i) => write!(f, "literal int {}", i), TokenValue::Ident(s) => write!(f, "identifier {}", s), TokenValue::TypeIdent(t) => write!(f, "type {}", t.as_ref()), TokenValue::Plus => write!(f, "`+`"), TokenValue::Minus => write!(f, "`-`"), TokenValue::Star => write!(f, "`*`"), TokenValue::Slash => write!(f, "`/`"), TokenValue::Percent => write!(f, "`%`"), TokenValue::Equal => write!(f, "`=`"), TokenValue::DoubleEqual => write!(f, "`==`"), TokenValue::Not => write!(f, "`!`"), TokenValue::And => write!(f, "`&&`"), TokenValue::Or => write!(f, "`||`"), TokenValue::NotEqual => write!(f, "`!=`"), TokenValue::Less => write!(f, "`<`"), TokenValue::LessEqual => write!(f, "`<=`"), TokenValue::Greater => write!(f, "`>`"), TokenValue::GreaterEqual => write!(f, "`>=`"), TokenValue::LParen => write!(f, "`(`"), TokenValue::RParen => write!(f, "`)`"), TokenValue::LBrace => write!(f, "`{{`"), TokenValue::RBrace => write!(f, "`}}`"), TokenValue::LBracket => write!(f, "`[`"), TokenValue::RBracket => write!(f, "`]`"), TokenValue::Comma => write!(f, "`,`"), TokenValue::Semicolon => write!(f, "`;`"), TokenValue::If => write!(f, "if"), TokenValue::Else => write!(f, "else"), TokenValue::While => write!(f, "while"), TokenValue::Return => write!(f, "return"), TokenValue::Break => write!(f, "break"), TokenValue::Continue => write!(f, "continue"), TokenValue::Eof => write!(f, ""), TokenValue::Unrecognized => write!(f, "unrecognized"), } } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum TokenKind { IntLit, Ident, TypeIdent, Plus, Minus, Star, Slash, Percent, Equal, DoubleEqual, NotEqual, Less, LessEqual, Greater, GreaterEqual, LParen, RParen, LBrace, RBrace, LBracket, RBracket, Comma, Semicolon, If, Else, While, Return, Break, Continue, Eof, Unrecognized, } #[derive(Debug, Clone, Copy, PartialEq, Eq, EnumString, AsRefStr)] pub enum TypeIdent { #[strum(serialize = "int")] Int, #[strum(serialize = "void")] Void, }