2023-02-07 02:07:53 -05:00
|
|
|
use std::rc::Rc;
|
2023-02-08 23:37:23 -05:00
|
|
|
use std::convert::From;
|
|
|
|
|
|
|
|
|
|
impl From<i32> for Form { fn from(item: i32) -> Self { Form::Int(item) } }
|
|
|
|
|
impl From<bool> for Form { fn from(item: bool) -> Self { Form::Bool(item) } }
|
|
|
|
|
// todo, strings not symbols?
|
|
|
|
|
impl From<String> 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<A: Into<Form>, B: Into<Form>> From<(A, B)> for Form {
|
|
|
|
|
fn from(item: (A, B)) -> Self {
|
|
|
|
|
Form::Pair(Rc::new(item.0.into()), Rc::new(item.1.into()))
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-02-07 02:07:53 -05:00
|
|
|
|
2023-02-10 19:38:44 -05:00
|
|
|
pub enum PossibleTailCall {
|
|
|
|
|
Result(Rc<Form>),
|
|
|
|
|
TailCall(Rc<Form>, Rc<Form>),
|
|
|
|
|
}
|
2023-02-08 01:54:53 -05:00
|
|
|
#[derive(Debug, Eq, PartialEq)]
|
2023-02-07 02:07:53 -05:00
|
|
|
pub enum Form {
|
2023-02-08 01:54:53 -05:00
|
|
|
Nil,
|
2023-02-07 02:07:53 -05:00
|
|
|
Int(i32),
|
2023-02-08 01:54:53 -05:00
|
|
|
Bool(bool),
|
2023-02-07 02:07:53 -05:00
|
|
|
Symbol(String),
|
|
|
|
|
Pair(Rc<Form>,Rc<Form>),
|
2023-02-10 19:38:44 -05:00
|
|
|
PrimComb(String, fn(Rc<Form>, Rc<Form>) -> PossibleTailCall),
|
2023-02-08 01:54:53 -05:00
|
|
|
DeriComb { se: Rc<Form>, de: Option<String>, params: Rc<Form>, body: Rc<Form> },
|
2023-02-07 02:07:53 -05:00
|
|
|
}
|
|
|
|
|
impl Form {
|
2023-02-08 01:54:53 -05:00
|
|
|
pub fn truthy(&self) -> bool {
|
|
|
|
|
match self {
|
|
|
|
|
Form::Bool(b) => *b,
|
|
|
|
|
Form::Nil => false,
|
|
|
|
|
_ => true,
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-02-07 02:07:53 -05:00
|
|
|
pub fn int(&self) -> Option<i32> {
|
|
|
|
|
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<Rc<Form>> {
|
|
|
|
|
match self {
|
|
|
|
|
Form::Pair(car, cdr) => Some(Rc::clone(car)),
|
|
|
|
|
_ => None,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
pub fn cdr(&self) -> Option<Rc<Form>> {
|
|
|
|
|
match self {
|
|
|
|
|
Form::Pair(car, cdr) => Some(Rc::clone(cdr)),
|
|
|
|
|
_ => None,
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-02-10 01:01:04 -05:00
|
|
|
pub fn append(&self, x: Rc<Form>) -> Option<Form> {
|
|
|
|
|
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,
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-02-07 02:07:53 -05:00
|
|
|
}
|
|
|
|
|
|