use std::rc::Rc; use std::convert::From; impl From for Form { fn from(item: i32) -> Self { Form::Int(item) } } impl From for Form { fn from(item: bool) -> Self { Form::Bool(item) } } // todo, strings not symbols? impl From for Form { fn from(item: String) -> Self { Form::Symbol(item) } } impl From<&str> for Form { fn from(item: &str) -> Self { Form::Symbol(item.to_owned()) } } impl, B: Into
> From<(A, B)> for Form { fn from(item: (A, B)) -> Self { Form::Pair(Rc::new(item.0.into()), Rc::new(item.1.into())) } } pub enum PossibleTailCall { Result(Rc), TailCall(Rc, Rc), } #[derive(Debug, Eq, PartialEq)] pub enum Form { Nil, Int(i32), Bool(bool), Symbol(String), Pair(Rc,Rc), PrimComb(String, fn(Rc, Rc) -> PossibleTailCall), DeriComb { se: Rc, de: Option, params: Rc, body: Rc }, } impl Form { pub fn truthy(&self) -> bool { match self { Form::Bool(b) => *b, Form::Nil => false, _ => true, } } pub fn int(&self) -> Option { match self { Form::Int(i) => Some(*i), _ => None, } } pub fn sym(&self) -> Option<&str> { match self { Form::Symbol(s) => Some(s), _ => None, } } pub fn car(&self) -> Option> { match self { Form::Pair(car, cdr) => Some(Rc::clone(car)), _ => None, } } pub fn cdr(&self) -> Option> { match self { Form::Pair(car, cdr) => Some(Rc::clone(cdr)), _ => None, } } pub fn append(&self, x: Rc) -> Option { match self { Form::Pair(car, cdr) => cdr.append(x).map(|x| Form::Pair(Rc::clone(car), Rc::new(x))), Form::Nil => Some(Form::Pair(x, Rc::new(Form::Nil))), _ => None, } } }