// Does Uniplating Conjure-Oxide Expressions Compile? // // Using the AST as of 30/04/2024 // -- Niklas Dewally use core::fmt::Display; use core::fmt::Formatter; use uniplate::derive::Uniplate; #[derive(Clone, Debug, PartialEq, Eq, Uniplate)] #[uniplate()] #[biplate(to=Constant)] #[biplate(to=String,walk_into=[Name])] enum Expression { Nothing, Bubble(Metadata, Box, Box), Constant(Metadata, Constant), Reference(Metadata, Name), Sum(Metadata, Vec), Min(Metadata, Vec), Not(Metadata, Box), Or(Metadata, Vec), And(Metadata, Vec), Eq(Metadata, Box, Box), Neq(Metadata, Box, Box), Geq(Metadata, Box, Box), Leq(Metadata, Box, Box), Gt(Metadata, Box, Box), Lt(Metadata, Box, Box), SafeDiv(Metadata, Box, Box), UnsafeDiv(Metadata, Box, Box), SumEq(Metadata, Vec, Box), SumGeq(Metadata, Vec, Box), SumLeq(Metadata, Vec, Box), DivEq(Metadata, Box, Box, Box), Ineq(Metadata, Box, Box, Box), AllDiff(Metadata, Vec), } #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash,Uniplate)] #[uniplate()] #[biplate(to=String)] enum Name { UserName(String), MachineName(i32), } impl Display for Name { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Name::UserName(s) => write!(f, "UserName({})", s), Name::MachineName(i) => write!(f, "MachineName({})", i), } } } #[derive(Clone, Debug, PartialEq, Eq, Default)] pub struct Metadata { pub clean: bool, } #[derive(Clone, Debug, PartialEq, Eq,Uniplate)] #[uniplate()] pub enum Constant { Int(i32), Bool(bool), } impl TryFrom for i32 { type Error = &'static str; fn try_from(value: Constant) -> Result { match value { Constant::Int(i) => Ok(i), _ => Err("Cannot convert non-i32 Constant to i32"), } } } impl TryFrom for bool { type Error = &'static str; fn try_from(value: Constant) -> Result { match value { Constant::Bool(b) => Ok(b), _ => Err("Cannot convert non-bool Constant to bool"), } } } impl From for Constant { fn from(i: i32) -> Self { Constant::Int(i) } } impl From for Constant { fn from(b: bool) -> Self { Constant::Bool(b) } } impl Display for Constant { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match &self { Constant::Int(i) => write!(f, "Int({})", i), Constant::Bool(b) => write!(f, "Bool({})", b), } } } pub fn main() {}