gorf_lcobj/
make.rs

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}