gorf-lcobj 0.1.1

Lambda calulcus backend library
Documentation
use std::{collections::BTreeMap, convert::Infallible};

use gorf_core::{brujin, debrijun, Id};
use gorf_kiselyov::{RealSki, Ski};

use crate::{Obj, Symbol};

pub fn bake_ski(a: &Ski, x: &mut Obj<Id, Infallible>) -> Id {
    let i: Id = format!("__{a:?}").into();
    if x.syms.contains_key(&i) {
        return i;
    };
    let s = match a {
        Ski::S => Symbol {
            r#impl: debrijun(lambda_calculus::combinators::S()),
            deps: vec![],
        },
        Ski::K => Symbol {
            r#impl: debrijun(lambda_calculus::combinators::K()),
            deps: vec![],
        },
        Ski::B => Symbol {
            r#impl: debrijun(lambda_calculus::combinators::B()),
            deps: vec![],
        },
        Ski::R => Symbol {
            r#impl: debrijun(lambda_calculus::combinators::R()),
            deps: vec![],
        },
        Ski::U => Symbol {
            deps: vec![],
            r#impl: debrijun(lambda_calculus::app(
                lambda_calculus::app(
                    lambda_calculus::combinators::S(),
                    lambda_calculus::combinators::I(),
                ),
                lambda_calculus::combinators::I(),
            )),
        },
        Ski::I => Symbol {
            r#impl: debrijun(lambda_calculus::combinators::I()),
            deps: vec![],
        },
        Ski::App(ski, ski1) => Symbol {
            deps: vec![bake_ski(ski.as_ref(), &mut *x), bake_ski(ski1.as_ref(), x)],
            r#impl: debrijun(lambda_calculus::combinators::I()),
        },
    };
    x.syms.insert(i.clone(), s);
    return i;
}
pub fn bake(a: &Symbol<Id, Infallible>, p: &str, x: &mut Obj<Id, Infallible>) {
    let s = bake_ski(&Ski::convert_default(brujin(a.r#impl.clone())), x);
    x.syms.insert(
        Id(format!("{p}")),
        Symbol {
            deps: [s].into_iter().chain(a.deps.iter().cloned()).collect(),
            r#impl: debrijun(lambda_calculus::combinators::I()),
        },
    );
}
pub fn cache(a: &Obj<Id, Infallible>) -> Obj<Id, Infallible> {
    return a.syms.iter().fold(
        Obj {
            syms: BTreeMap::new(),
        },
        |mut x, (si, s)| {
            bake(s, &si.0, &mut x);
            return x;
        },
    );
}