#[derive(PartialEq, Debug)]
pub enum Assoc {
LEFT,
NONE,
RIGHT,
}
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum Op {
SUM,
SUB,
EXP,
DIV,
MUL,
FAC,
NEG,
}
impl Op {
pub fn from_char(s: char) -> Result<Op, String> {
match s {
'-' => Ok(Op::SUB),
'+' => Ok(Op::SUM),
'*' => Ok(Op::MUL),
'/' => Ok(Op::DIV),
'^' => Ok(Op::EXP),
'!' => Ok(Op::FAC),
_ => Err(format!("Could not parse {} as operator", s)),
}
}
pub fn assoc(&self) -> Assoc {
match *self {
Op::SUM | Op::MUL | Op::SUB | Op::DIV => Assoc::LEFT,
Op::EXP | Op::NEG | Op::FAC => Assoc::RIGHT,
_ => Assoc::NONE,
}
}
pub fn prec(&self) -> u8 {
match *self {
Op::NEG => 5,
Op::EXP | Op::FAC => 4,
Op::SUB | Op::SUM => 2,
Op::MUL | Op::DIV => 3,
_ => 0,
}
}
}
#[derive(Debug, PartialEq, Clone)]
pub enum Token {
Num(f64),
Bin(Op),
Una(Op),
Fn(String),
Var(String),
LP,
RP,
}
impl Token {
#[inline]
pub fn is_bin(&self) -> bool {
matches!(self, Token::Bin(_x))
}
#[inline]
pub fn is_op(&self) -> bool {
matches!(self, Token::Bin(_x)) || matches!(self, Token::Una(_x))
}
#[inline]
pub fn get_op(&self) -> Option<Op> {
if let Token::Bin(op) = self {
Some(op.clone())
} else if let Token::Una(op) = self {
Some(op.clone())
} else {
None
}
}
}