add app special form for convenience
should probably add some sort of macro system
This commit is contained in:
parent
87e5bdad48
commit
180f03244a
1 changed files with 49 additions and 0 deletions
49
src/main.rs
49
src/main.rs
|
@ -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[..] {
|
||||||
|
|
Loading…
Reference in a new issue