use std::fmt::Display;
#[derive(Debug)]
pub enum Expr {
Op(Op),
Val(Val),
}
#[derive(Debug)]
pub enum Op {
Mul(Box<Expr>, Box<Expr>),
Div(Box<Expr>, Box<Expr>),
Mod(Box<Expr>, Box<Expr>),
Add(Box<Expr>, Box<Expr>),
Sub(Box<Expr>, Box<Expr>),
Pow(Box<Expr>, Box<Expr>),
ShiftLeft(Box<Expr>, Box<Expr>),
ShiftRight(Box<Expr>, Box<Expr>),
RotLeft(Box<Expr>, Box<Expr>),
RotRight(Box<Expr>, Box<Expr>),
BitXor(Box<Expr>, Box<Expr>),
BitOr(Box<Expr>, Box<Expr>),
BitAnd(Box<Expr>, Box<Expr>),
}
#[derive(Debug)]
pub enum Val {
Hex(u64),
Int(u64),
Bin(u64),
LastAnswer,
History(usize),
}
impl Display for Expr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Expr::Op(op) => op.fmt(f),
Expr::Val(val) => val.fmt(f),
}
}
}
impl Display for Op {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Op::Mul(a, b) => write!(f, "( {a} * {b} )"),
Op::Div(a, b) => write!(f, "( {a} / {b} )"),
Op::Mod(a, b) => write!(f, "( {a} % {b} )"),
Op::Add(a, b) => write!(f, "( {a} + {b} )"),
Op::Sub(a, b) => write!(f, "( {a} - {b} )"),
Op::Pow(a, b) => write!(f, "( {a} ** {b} )"),
Op::ShiftLeft(a, b) => write!(f, "( {a} << {b} )"),
Op::ShiftRight(a, b) => write!(f, "( {a} >> {b} )"),
Op::RotLeft(a, b) => write!(f, "( {a} rotl {b} )"),
Op::RotRight(a, b) => write!(f, "( {a} rotr {b} )"),
Op::BitXor(a, b) => write!(f, "( {a} ^ {b} )"),
Op::BitOr(a, b) => write!(f, "( {a} | {b} )"),
Op::BitAnd(a, b) => write!(f, "( {a} & {b} )"),
}
}
}
impl Display for Val {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Val::Hex(a) => write!(f, "{a:#x}"),
Val::Int(a) => write!(f, "{a}"),
Val::Bin(a) => write!(f, "{a:#b}"),
Val::LastAnswer => write!(f, "_"),
Val::History(x) => write!(f, "${x}"),
}
}
}