1#![no_std]
2extern crate alloc;
3use core::sync::atomic::AtomicU8;
4
5use alloc::{boxed::Box, sync::Arc, vec::Vec};
6use dyn_clone::DynClone;
7#[derive(Clone)]
8pub struct B(pub Arc<dyn O>);
9pub trait O: Fn(&B) -> B {}
10impl<T: Fn(&B) -> B> O for T {}
11pub fn o<A: O + 'static>(a: A) -> B {
14 return B(Arc::new(a));
15}
16
17pub fn K(a: B) -> B {
18 return B(Arc::new(move |_| a.clone()));
19}
20pub fn l(a: impl Fn() -> B + Clone + 'static) -> B {
21 return B(Arc::new(move |v| a().0(v)));
22}
23pub fn scott(a: usize, n: usize, b: Arc<[B]>) -> B {
24 return B(Arc::new(move |mut x| {
25 if a == 0 {
26 let mut x = x.clone();
27 for b in b.iter() {
28 x = x.0(b);
29 }
30 for _ in 0..n {
31 x = K(x);
32 }
33 return x;
34 } else {
35 return scott(a - 1, n - 1, b.clone());
36 }
37 }));
38}
39pub fn u8_from_term(a: B) -> u8 {
40 pub fn go(a: B, x: Arc<AtomicU8>) {
41 let x2 = x.clone();
43 a.0(&o(move |a| {
44 return a.clone();
45 }))
46 .0(&o(move |a| {
47 x2.fetch_add(1, core::sync::atomic::Ordering::SeqCst);
48 go(a.clone(), x2.clone());
49 return a.clone();
50 }))
51 .0(&o(|a| a.clone()));
52 }
53 let mut x = Arc::new(AtomicU8::new(0));
54 go(a, x.clone());
55 return x.load(core::sync::atomic::Ordering::Relaxed);
56}
57pub fn u8_to_term(a: u8) -> B {
58 return o(move |arg| {
59 let arg = arg.clone();
60 return o(move |arg2| {
61 let arg2 = arg2.clone();
62 if (a == 0) {
63 return arg.clone();
64 }
65 return arg2.0(&u8_to_term(a - 1));
66 });
67 });
68}
69pub use gorf_gen_macro::lamc;
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74
75 }