add unquote special form
This commit is contained in:
parent
9c65b1618b
commit
798245aa0f
1 changed files with 45 additions and 1 deletions
46
src/main.rs
46
src/main.rs
|
@ -611,6 +611,7 @@ pub fn simp(rules: &[Rule], mut expr: Sexp, step_limit: usize, complexity_limit:
|
||||||
for _ in 0..step_limit {
|
for _ in 0..step_limit {
|
||||||
expr = expr
|
expr = expr
|
||||||
.apply_special_form::<Quote>()
|
.apply_special_form::<Quote>()
|
||||||
|
.apply_special_form::<Unquote>()
|
||||||
.apply_special_form::<Genslop>()
|
.apply_special_form::<Genslop>()
|
||||||
.apply_special_form::<LambdaLike>()
|
.apply_special_form::<LambdaLike>()
|
||||||
.apply_special_form::<App>()
|
.apply_special_form::<App>()
|
||||||
|
@ -909,7 +910,50 @@ fn consify(xs: &[Sexp]) -> Sexp {
|
||||||
None => Sexp::nil(),
|
None => Sexp::nil(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Sexp::List(vec![Sexp::Atom(*CONS), consify(&xs[1..])])
|
|
||||||
|
static UNQUOTE: Lazy<Symbol> = Lazy::new(|| TABLE.lock().unwrap().intern("unquote").unwrap());
|
||||||
|
|
||||||
|
// sbcl has quote take one arg....
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct Unquote<'src>(&'src Sexp);
|
||||||
|
|
||||||
|
impl<'src> SpecialForm<'src> for Unquote<'src> {
|
||||||
|
fn from_sexp(sexp: &'src Sexp) -> Option<Self> {
|
||||||
|
match sexp {
|
||||||
|
Sexp::Atom(_) => None,
|
||||||
|
Sexp::List(xs) => match &xs[..] {
|
||||||
|
[Sexp::Atom(unquote), expr] if *unquote == *UNQUOTE => Some(Self(expr)),
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn eval(self) -> Sexp {
|
||||||
|
let Self(expr) = self;
|
||||||
|
|
||||||
|
deconsify(expr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deconsify(sexp: &Sexp) -> Sexp {
|
||||||
|
match sexp {
|
||||||
|
Sexp::Atom(at) => Sexp::Atom(*at),
|
||||||
|
Sexp::List(xs) => match &xs[..] {
|
||||||
|
[Sexp::Atom(cons), car, cdr] if *cons == *CONS => {
|
||||||
|
let mut out = vec![deconsify(car)];
|
||||||
|
|
||||||
|
let cdr = deconsify(cdr);
|
||||||
|
match cdr {
|
||||||
|
Sexp::Atom(_) => out.push(cdr),
|
||||||
|
Sexp::List(xs) => out.extend(xs),
|
||||||
|
}
|
||||||
|
|
||||||
|
Sexp::List(out)
|
||||||
|
}
|
||||||
|
_ => sexp.clone(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn make_rule(sexp: &Sexp) -> Option<Rule> {
|
pub fn make_rule(sexp: &Sexp) -> Option<Rule> {
|
||||||
match sexp {
|
match sexp {
|
||||||
|
|
Loading…
Reference in a new issue