use crate::common::Span;
use core::fmt;
#[derive(PartialEq, Clone, Debug)]
pub enum TokenType {
Float(f64),
Plus,
Minus,
Mult,
Div,
Mod,
Exp,
Equal,
OpenParen,
CloseParen,
OpenBracket,
CloseBracket,
Variable(String),
VariablePattern(String),
ConstPattern(String),
AnyPattern(String),
Invalid(String),
EOF,
}
impl fmt::Display for TokenType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use TokenType::*;
write!(
f,
"{}",
match self {
Float(num) => num.to_string(),
Plus => "+".into(),
Minus => "-".into(),
Mult => "*".into(),
Div => "/".into(),
Mod => "%".into(),
Exp => "^".into(),
Equal => "=".into(),
OpenParen => "(".into(),
CloseParen => ")".into(),
OpenBracket => "[".into(),
CloseBracket => "]".into(),
Variable(s) => s.to_string(),
VariablePattern(s) => s.to_string(),
ConstPattern(s) => s.to_string(),
AnyPattern(s) => s.to_string(),
Invalid(s) => s.to_string(),
EOF => "end of file".into(),
}
)
}
}
#[derive(PartialEq, Clone, Debug)]
pub struct Token {
pub ty: TokenType,
pub span: Span,
}
impl Token {
pub fn new<S>(ty: TokenType, span: S) -> Self
where
S: Into<Span>,
{
Self {
ty,
span: span.into(),
}
}
}
impl fmt::Display for Token {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.ty.to_string())
}
}
#[cfg(test)]
mod tests {
mod format {
use crate::scanner::types::*;
macro_rules! format_tests {
($($name:ident: $ty:expr, $format_str:expr)*) => {
$(
#[test]
fn $name() {
use TokenType::*;
let tok = Token {ty: $ty, span: (0, 0).into()};
assert_eq!(tok.to_string(), $format_str);
}
)*
}
}
format_tests! {
float: Float(1.3), "1.3"
plus: Plus, "+"
minus: Minus, "-"
mult: Mult, "*"
div: Div, "/"
modulo: Mod, "%"
exp: Exp, "^"
equal: Equal, "="
open_paren: OpenParen, "("
close_paren: CloseParen, ")"
open_bracket: OpenBracket, "["
close_bracket: CloseBracket, "]"
variable: Variable("ab".into()), "ab"
invalid: Invalid("@&@".into()), "@&@"
}
}
}