Skip to main content

sim_lib_binding/
runtime.rs

1//! The binding organ as a loadable kernel [`Lib`].
2//!
3//! Registers the binding special forms as callables against the kernel
4//! [`Lib`]/[`Linker`] contract. Today that is the `let` lexical binding form
5//! (COOKBOOK_7 Category B); the crate's lexical/dynamic/mode machinery is the
6//! substrate the forms build on.
7
8use std::sync::Arc;
9
10use sim_kernel::{
11    AbiVersion, Cx, Export, Lib, LibManifest, LibTarget, Linker, Result, Symbol, Version,
12};
13
14use crate::let_form::LetForm;
15
16const BINDING_LIB_ID: &str = "binding";
17
18/// Returns the `sim/binding` manifest id under which this lib registers.
19pub fn manifest_name() -> Symbol {
20    Symbol::qualified("sim", BINDING_LIB_ID)
21}
22
23/// The binding organ lib: installs the binding special forms as callables.
24pub struct BindingLib;
25
26impl Lib for BindingLib {
27    fn manifest(&self) -> LibManifest {
28        LibManifest {
29            id: manifest_name(),
30            version: Version(env!("CARGO_PKG_VERSION").to_owned()),
31            abi: AbiVersion { major: 0, minor: 1 },
32            target: LibTarget::HostRegistered,
33            requires: Vec::new(),
34            capabilities: Vec::new(),
35            exports: binding_exports(),
36        }
37    }
38
39    fn load(&self, cx: &mut sim_kernel::LoadCx, linker: &mut Linker<'_>) -> Result<()> {
40        linker.function_value(LetForm::symbol(), cx.factory().opaque(Arc::new(LetForm))?)?;
41        Ok(())
42    }
43}
44
45/// Returns the lib's exported binding forms as kernel [`Export`]s.
46pub fn binding_exports() -> Vec<Export> {
47    vec![Export::Function {
48        symbol: LetForm::symbol(),
49        function_id: None,
50    }]
51}
52
53/// Installs the binding organ into `cx` (idempotent): loads [`BindingLib`] only
54/// when it is not already registered.
55pub fn install_binding_lib(cx: &mut Cx) -> Result<()> {
56    if cx.registry().lib(&manifest_name()).is_some() {
57        return Ok(());
58    }
59    cx.load_lib(&BindingLib)?;
60    Ok(())
61}