1use alloc::collections::BTreeMap;
2use core::convert::Infallible;
3use alloc::{format,vec};
4
5use gorf_core::{brujin, debrijun, Id};
6use gorf_kiselyov::{RealSki, Ski};
7
8use crate::{Obj, Symbol};
9
10pub fn bake_ski(a: &Ski, x: &mut Obj<Id, Infallible>) -> Id {
11 let i: Id = format!("__{a:?}").into();
12 if x.syms.contains_key(&i) {
13 return i;
14 };
15 let s = match a {
16 Ski::S => Symbol {
17 r#impl: debrijun(lambda_calculus::combinators::S()),
18 deps: vec![],
19 },
20 Ski::K => Symbol {
21 r#impl: debrijun(lambda_calculus::combinators::K()),
22 deps: vec![],
23 },
24 Ski::B => Symbol {
25 r#impl: debrijun(lambda_calculus::combinators::B()),
26 deps: vec![],
27 },
28 Ski::R => Symbol {
29 r#impl: debrijun(lambda_calculus::combinators::R()),
30 deps: vec![],
31 },
32 Ski::U => Symbol {
33 deps: vec![],
34 r#impl: debrijun(lambda_calculus::app(
35 lambda_calculus::app(
36 lambda_calculus::combinators::S(),
37 lambda_calculus::combinators::I(),
38 ),
39 lambda_calculus::combinators::I(),
40 )),
41 },
42 Ski::I => Symbol {
43 r#impl: debrijun(lambda_calculus::combinators::I()),
44 deps: vec![],
45 },
46 Ski::App(ski, ski1) => Symbol {
47 deps: vec![bake_ski(ski.as_ref(), &mut *x), bake_ski(ski1.as_ref(), x)],
48 r#impl: debrijun(lambda_calculus::combinators::I()),
49 },
50 };
51 x.syms.insert(i.clone(), s);
52 return i;
53}
54pub fn bake(a: &Symbol<Id, Infallible>, p: &str, x: &mut Obj<Id, Infallible>) {
55 let s = bake_ski(&Ski::convert_default(brujin(a.r#impl.clone())), x);
56 x.syms.insert(
57 Id(format!("{p}")),
58 Symbol {
59 deps: [s].into_iter().chain(a.deps.iter().cloned()).collect(),
60 r#impl: debrijun(lambda_calculus::combinators::I()),
61 },
62 );
63}
64pub fn cache(a: &Obj<Id, Infallible>) -> Obj<Id, Infallible> {
65 return a.syms.iter().fold(
66 Obj {
67 syms: BTreeMap::new(),
68 },
69 |mut x, (si, s)| {
70 bake(s, &si.0, &mut x);
71 return x;
72 },
73 );
74}