add app special form for convenience

should probably add some sort of macro system
This commit is contained in:
mehbark 2023-06-14 20:58:05 -04:00
parent 87e5bdad48
commit 180f03244a

View file

@ -100,6 +100,7 @@ impl Sexp {
} }
} }
#[must_use]
pub fn rw(&self, rule: &Rule) -> Sexp { pub fn rw(&self, rule: &Rule) -> Sexp {
rw(rule, self) rw(rule, self)
} }
@ -177,6 +178,14 @@ impl Sexp {
}, },
} }
} }
#[must_use]
pub fn is_this_atom(&self, atom: Symbol) -> bool {
match self {
Sexp::Atom(at) => *at == atom,
Sexp::List(_) => false,
}
}
} }
impl fmt::Display for Sexp { impl fmt::Display for Sexp {
@ -597,10 +606,12 @@ pub fn rw(rule: &Rule, sexp: &Sexp) -> Sexp {
} }
} }
#[must_use]
pub fn simp(rules: &[Rule], mut expr: Sexp, step_limit: usize, complexity_limit: usize) -> Sexp { pub fn simp(rules: &[Rule], mut expr: Sexp, step_limit: usize, complexity_limit: usize) -> Sexp {
for _ in 0..step_limit { for _ in 0..step_limit {
expr = expr expr = expr
.apply_special_form::<Genslop>() .apply_special_form::<Genslop>()
.apply_special_form::<App>()
.apply_special_form::<Log>() .apply_special_form::<Log>()
.apply_special_form::<Let>() .apply_special_form::<Let>()
.apply_special_form::<Eq>(); .apply_special_form::<Eq>();
@ -743,6 +754,44 @@ impl<'src> SpecialForm<'src> for Log<'src> {
} }
} }
static APP: Lazy<Symbol> = Lazy::new(|| TABLE.lock().unwrap().intern("app").unwrap());
#[derive(Debug, Clone)]
struct App<'src> {
f: &'src Sexp,
args: &'src [Sexp],
}
impl<'src> SpecialForm<'src> for App<'src> {
fn from_sexp(sexp: &'src Sexp) -> Option<Self> {
match sexp {
Sexp::Atom(_) => None,
Sexp::List(xs) => {
if xs.len() >= 2 && xs[0].is_this_atom(*APP) {
Some(Self {
f: xs.get(1).unwrap(),
args: &xs[2..],
})
} else {
None
}
}
}
}
fn eval(self) -> Sexp {
let Self { f, args } = self;
let mut out = f.clone();
for arg in args {
out = Sexp::List(vec![out, arg.clone()]);
}
out
}
}
pub fn make_rule(sexp: &Sexp) -> Option<Rule> { pub fn make_rule(sexp: &Sexp) -> Option<Rule> {
match sexp { match sexp {
Sexp::List(xs) => match &xs[..] { Sexp::List(xs) => match &xs[..] {