1#![no_std]
2extern crate alloc;
3use alloc::boxed::Box;
4use core::iter::once;
5
6use lambda_calculus::Term;
7
8pub fn encode(a: &Term) -> Box<dyn Iterator<Item = bool> + '_> {
9 match a {
10 Term::Var(a) => Box::new((0..=*a).map(|_| true).chain(once(false))),
11 Term::Abs(term) => Box::new([false, false].into_iter().chain(encode(&term))),
12 Term::App(a) => {
13 let (a, b) = &**a;
14 return Box::new([false, true].into_iter().chain(encode(a)).chain(encode(b)));
15 }
16 }
17}
18pub fn decode(a: &mut (dyn Iterator<Item = bool> + '_)) -> Option<Term> {
19 Some(match a.next()? {
20 true => {
21 let mut i = 0;
22 while a.next()? {
23 i += 1
24 }
25 Term::Var(i)
26 }
27 false => match a.next()? {
28 false => Term::Abs(Box::new(decode(a)?)),
29 true => Term::App(Box::new((decode(a)?, decode(a)?))),
30 },
31 })
32}