use crate::{common::traits::private::Sealed, v0::tokens::ExprToken};
use super::{traits::ExprObj, *};
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq)]
pub enum Expr<S: Sized> {
Variable(ExprVariable<S>),
SignedIntLiteral(ExprSignedIntLiteral<S>),
UnsignedIntLiteral(ExprUnsignedIntLiteral<S>),
BinaryFloat32Literal(ExprBinaryFloat32Literal<S>),
BinaryFloat64Literal(ExprBinaryFloat64Literal<S>),
TrueLiteral(ExprTrueLiteral<S>),
FalseLiteral(ExprFalseLiteral<S>),
Addition(ExprAddition<S>),
Subtraction(ExprSubtraction<S>),
Multiplication(ExprMultiplication<S>),
Division(ExprDivision<S>),
IntDivision(ExprIntDivision<S>),
Modulo(ExprModulo<S>),
Power(ExprPower<S>),
Negation(ExprNegation<S>),
Root(ExprRoot<S>),
IntRoot(ExprIntRoot<S>),
Square(ExprSquare<S>),
Cube(ExprCube<S>),
SquareRoot(ExprSquareRoot<S>),
CubeRoot(ExprCubeRoot<S>),
Reciprocal(ExprReciprocal<S>),
}
impl<S: Sized> Sealed for Expr<S> {}
impl<S: Sized> ExprObj<S> for Expr<S> {
fn token(&self) -> ExprToken {
match self {
Expr::Variable(inner) => ExprObj::<S>::token(inner),
Expr::SignedIntLiteral(inner) => ExprObj::<S>::token(inner),
Expr::UnsignedIntLiteral(inner) => ExprObj::<S>::token(inner),
Expr::BinaryFloat32Literal(inner) => ExprObj::<S>::token(inner),
Expr::BinaryFloat64Literal(inner) => ExprObj::<S>::token(inner),
Expr::TrueLiteral(inner) => ExprObj::<S>::token(inner),
Expr::FalseLiteral(inner) => ExprObj::<S>::token(inner),
Expr::Addition(inner) => ExprObj::<S>::token(inner),
Expr::Subtraction(inner) => ExprObj::<S>::token(inner),
Expr::Multiplication(inner) => ExprObj::<S>::token(inner),
Expr::Division(inner) => ExprObj::<S>::token(inner),
Expr::IntDivision(inner) => ExprObj::<S>::token(inner),
Expr::Modulo(inner) => ExprObj::<S>::token(inner),
Expr::Power(inner) => ExprObj::<S>::token(inner),
Expr::Negation(inner) => ExprObj::<S>::token(inner),
Expr::Root(inner) => ExprObj::<S>::token(inner),
Expr::IntRoot(inner) => ExprObj::<S>::token(inner),
Expr::Square(inner) => ExprObj::<S>::token(inner),
Expr::Cube(inner) => ExprObj::<S>::token(inner),
Expr::SquareRoot(inner) => ExprObj::<S>::token(inner),
Expr::CubeRoot(inner) => ExprObj::<S>::token(inner),
Expr::Reciprocal(inner) => ExprObj::<S>::token(inner),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct ExprTree {
inner: Box<Expr<ExprTree>>,
}
impl ExprTree {
pub fn into_inner(self) -> Expr<ExprTree> {
*self.inner
}
pub fn inner(&self) -> &Expr<ExprTree> {
&self.inner
}
pub fn inner_mut(&mut self) -> &mut Expr<ExprTree> {
&mut self.inner
}
}
impl From<Expr<ExprTree>> for ExprTree {
fn from(expr: Expr<ExprTree>) -> Self {
Self {
inner: Box::new(expr),
}
}
}
impl Into<Expr<ExprTree>> for ExprTree {
fn into(self) -> Expr<ExprTree> {
*self.inner
}
}