/* * Canonical Expressions * * AKA, simplified, normalized algebraic expressions. * */ use crate::sexpr::SExpr; pub enum NumericConstant { Pi, // 3.141592... E, // 2.718281... Infinity, } #[derive(Clone, PartialEq)] pub enum CNumber { Integer(i64), Rational(i64, u64), // Float // Constant } impl CNumber { pub fn to_sexpr(&self) -> Result { match self { CNumber::Integer(v) => Ok(SExpr::SInteger(*v)), CNumber::Rational(a, b) => Ok(SExpr::SList(vec![ SExpr::SIdentifier("/".to_string()), SExpr::SInteger(*a), SExpr::SInteger(*b as i64), ])), } } } #[derive(Clone, PartialEq)] pub enum CExpr { Symbol(String), Number(CNumber), Sum(Option, Vec), Product(Option, Vec), Power(Box, Box), Factorial(Box), UnaryFunction(String, Box), // TODO: Infinity? // TODO: Limit? // TODO: Vector? } impl CExpr { pub fn from_sexpr(sexpr: &SExpr) -> Result { // not all cases are handled; some atoms are covered trivialy match sexpr { SExpr::SNull => Err("null not handled".to_string()), SExpr::SBoolean(_) => Err("booleans not handled".to_string()), SExpr::SInteger(v) => Ok(CExpr::Number(CNumber::Integer(*v))), SExpr::SFloat(v) => Err("floats not handled".to_string()), SExpr::SString(_) => Err("null not handled".to_string()), SExpr::SIdentifier(v) => Ok(CExpr::Symbol(v.to_string())), SExpr::SList(_) => Err("null not handled".to_string()), //SExpr::SList(l) => CExpr::from_sexpr_list(l), } } /* pub fn from_sexpr_list(list: &Vec) -> Result { if list.is_empty() { unimplemented!() } match list[0] { SExpr::SIdentifier("+") => { Ok(CExpr::Sum( // XXX None, list[1..].iter().map(|v| CExpr::from_sexpr(v)).collect::, String>>()?, )) }, SExpr::SIdentifier("*") => { }, SExpr::SIdentifier("^") => { }, _ => { unimplemented!() } } } */ pub fn new_sum(list: &Vec) -> Result { unimplemented!() } pub fn new_product(list: &Vec) -> Result { unimplemented!() } pub fn to_sexpr(&self) -> Result { match self { CExpr::Symbol(s) => Ok(SExpr::SIdentifier(s.to_string())), CExpr::Number(n) => n.to_sexpr(), CExpr::Sum(n, l) => Ok(SExpr::SList(vec![ SExpr::SIdentifier("+".to_string()), SExpr::SList(l.iter().map(|v| v.to_sexpr()).collect::, String>>()?), // XXX: n ])), CExpr::Product(n, l) => Ok(SExpr::SList(vec![ SExpr::SIdentifier("*".to_string()), SExpr::SList(l.iter().map(|v| v.to_sexpr()).collect::, String>>()?), // XXX: n ])), CExpr::Power(a, b) => Ok(SExpr::SList(vec![ SExpr::SIdentifier("^".to_string()), a.to_sexpr()?, b.to_sexpr()?, ])), CExpr::Factorial(v) => Ok(SExpr::SList(vec![ SExpr::SIdentifier("factorial".to_string()), v.to_sexpr()?, ])), CExpr::UnaryFunction(s, v) => Ok(SExpr::SList(vec![ SExpr::SIdentifier(s.to_string()), v.to_sexpr()?, ])), } } }