add unquote special form

This commit is contained in:
mehbark 2023-06-14 23:47:03 -04:00
parent 9c65b1618b
commit 798245aa0f

View file

@ -611,6 +611,7 @@ pub fn simp(rules: &[Rule], mut expr: Sexp, step_limit: usize, complexity_limit:
for _ in 0..step_limit {
expr = expr
.apply_special_form::<Quote>()
.apply_special_form::<Unquote>()
.apply_special_form::<Genslop>()
.apply_special_form::<LambdaLike>()
.apply_special_form::<App>()
@ -909,7 +910,50 @@ fn consify(xs: &[Sexp]) -> Sexp {
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> {
match sexp {