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 {
|
||||
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 {
|
||||
|
@ -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 {
|
||||
for _ in 0..step_limit {
|
||||
expr = expr
|
||||
.apply_special_form::<Genslop>()
|
||||
.apply_special_form::<App>()
|
||||
.apply_special_form::<Log>()
|
||||
.apply_special_form::<Let>()
|
||||
.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> {
|
||||
match sexp {
|
||||
Sexp::List(xs) => match &xs[..] {
|
||||
|
|
Loading…
Reference in a new issue