Skip to main content

sim/runtime/install/
bootstrap.rs

1use std::sync::Arc;
2
3use sim_kernel::{
4    AbiVersion, Cx, Lib, LibManifest, LibTarget, Linker, LoadCx, Result, Symbol, Version,
5};
6
7use crate::{
8    macros::RegistryMacroExpander,
9    runtime::{
10        browse::reflection::install_schema_examples,
11        install::{
12            register::{register_core_classes, register_core_functions, register_core_values},
13            register_shapes::register_core_shapes,
14        },
15    },
16};
17
18use super::{exports::core_exports, optional::install_optional_runtime_libs};
19
20/// Lib that registers the core runtime: its classes, shapes, functions, and
21/// values.
22pub struct CoreRuntimeLib;
23
24impl Lib for CoreRuntimeLib {
25    fn manifest(&self) -> LibManifest {
26        LibManifest {
27            id: Symbol::new("core"),
28            version: Version(env!("CARGO_PKG_VERSION").to_owned()),
29            abi: AbiVersion { major: 0, minor: 1 },
30            target: LibTarget::HostRegistered,
31            requires: Vec::new(),
32            capabilities: Vec::new(),
33            exports: core_exports(),
34        }
35    }
36
37    fn load(&self, cx: &mut LoadCx, linker: &mut Linker<'_>) -> Result<()> {
38        register_core_classes(cx, linker)?;
39        register_core_shapes(cx, linker)?;
40        register_core_functions(cx, linker)?;
41        register_core_values(cx, linker)?;
42        Ok(())
43    }
44}
45
46/// Installs the core runtime into a context: registers the macro expander, the
47/// core lib, and the default number domains for the enabled features.
48pub fn install_core_runtime(cx: &mut Cx) {
49    cx.set_macro_expander(Arc::new(RegistryMacroExpander::new()));
50
51    let loaded = sim_lib_core::install_once(cx, &CoreRuntimeLib)
52        .expect("core runtime should load through the lib registry");
53    if !loaded {
54        install_schema_examples(cx).expect("core runtime should install browse schema examples");
55        return;
56    }
57
58    #[cfg(feature = "numbers-f64")]
59    install_number_domain(
60        cx,
61        Symbol::qualified("numbers", "f64"),
62        crate::numbers_f64::F64NumbersLib::new(),
63        "core runtime should install the default numbers/f64 domain",
64    );
65    #[cfg(feature = "numbers-i64")]
66    install_number_domain(
67        cx,
68        Symbol::qualified("numbers", "i64"),
69        crate::numbers_i64::I64NumbersLib::new(),
70        "core runtime should install the default numbers/i64 domain",
71    );
72    #[cfg(feature = "numbers-bool")]
73    install_number_domain(
74        cx,
75        Symbol::qualified("numbers", "bool"),
76        crate::numbers_bool::BoolNumbersLib::new(),
77        "core runtime should install the numbers/bool domain",
78    );
79    #[cfg(feature = "numbers-fixed")]
80    install_registered_lib(
81        cx,
82        Symbol::qualified("numbers", "fixed"),
83        crate::numbers_fixed::FixedNumbersLib::new(),
84        "core runtime should install fixed integer domains",
85    );
86    #[cfg(feature = "numbers-float")]
87    install_number_domain(
88        cx,
89        Symbol::qualified("numbers", "f32"),
90        crate::numbers_float::F32NumbersLib::new(),
91        "core runtime should install the numbers/f32 domain",
92    );
93    #[cfg(feature = "numbers-bigint")]
94    install_number_domain(
95        cx,
96        Symbol::qualified("numbers", "bigint"),
97        crate::numbers_bigint::BigIntNumbersLib::new(),
98        "core runtime should install the numbers/bigint domain",
99    );
100    #[cfg(feature = "numbers-rational")]
101    install_number_domain(
102        cx,
103        Symbol::qualified("numbers", "rational"),
104        crate::numbers_rational::RationalNumbersLib::new(),
105        "core runtime should install the default numbers/rational domain",
106    );
107    #[cfg(feature = "numbers-tensor")]
108    install_number_domain(
109        cx,
110        Symbol::qualified("numbers", "tensor"),
111        crate::numbers_tensor::TensorNumbersLib::new(),
112        "core runtime should install the default numbers/tensor domain",
113    );
114    #[cfg(feature = "numbers-cas")]
115    install_number_domain(
116        cx,
117        Symbol::qualified("numbers", "cas"),
118        crate::numbers_cas::CasNumbersLib::new(),
119        "core runtime should install the default numbers/cas domain",
120    );
121    #[cfg(feature = "numbers-cas-diff")]
122    install_function_lib(
123        cx,
124        Symbol::new("diff"),
125        crate::numbers_cas_diff::CasDiffLib::new(),
126        "core runtime should install CAS differentiation helpers",
127    );
128    #[cfg(feature = "numbers-cas-eval")]
129    install_function_lib(
130        cx,
131        Symbol::new("eval-cas"),
132        crate::numbers_cas_eval::CasEvalLib::new(),
133        "core runtime should install CAS evaluation helpers",
134    );
135    #[cfg(feature = "numbers-complex")]
136    install_number_domain(
137        cx,
138        Symbol::qualified("numbers", "complex"),
139        crate::numbers_complex::ComplexNumbersLib::new(),
140        "core runtime should install the default numbers/complex domain",
141    );
142    #[cfg(feature = "numbers-exotic")]
143    install_number_domain(
144        cx,
145        Symbol::qualified("numbers", "cf"),
146        crate::numbers_exotic::ExoticNumbersLib::new(),
147        "core runtime should install the default numbers/cf domain",
148    );
149    #[cfg(feature = "numbers-func")]
150    install_number_domain(
151        cx,
152        Symbol::qualified("numbers", "func"),
153        crate::numbers_func::FuncNumbersLib::new(),
154        "core runtime should install the default numbers/func domain",
155    );
156    #[cfg(feature = "numbers-arith")]
157    install_function_lib(
158        cx,
159        Symbol::qualified("math", "add"),
160        crate::numbers_arith::NumbersArithmeticLib::new(),
161        "core runtime should install generic numeric arithmetic functions",
162    );
163    #[cfg(feature = "numbers-numeric")]
164    install_function_lib(
165        cx,
166        Symbol::new("numeric-diff"),
167        crate::numbers_numeric::NumericNumbersLib::new(),
168        "core runtime should install numeric method registry functions",
169    );
170    #[cfg(feature = "numbers-quad")]
171    install_registered_lib(
172        cx,
173        Symbol::qualified("numbers", "quad"),
174        crate::numbers_quad::QuadNumbersLib::new(),
175        "core runtime should install standard quadrature and finite-difference plugins",
176    );
177    #[cfg(feature = "numbers-rk")]
178    install_registered_lib(
179        cx,
180        Symbol::qualified("numbers", "rk"),
181        crate::numbers_rk::RkNumbersLib::new(),
182        "core runtime should install standard ODE solver plugins",
183    );
184    #[cfg(feature = "numbers-tensor-bcast")]
185    install_registered_lib(
186        cx,
187        Symbol::qualified("numbers", "tensor-bcast"),
188        crate::numbers_tensor_bcast::TensorBroadcastLib::new(),
189        "core runtime should install tensor broadcasting rules",
190    );
191    #[cfg(feature = "numbers-tensor-linalg")]
192    install_function_lib(
193        cx,
194        Symbol::new("dot"),
195        crate::numbers_tensor_linalg::TensorLinalgLib::new(),
196        "core runtime should install tensor linear algebra helpers",
197    );
198
199    install_optional_runtime_libs(cx);
200    install_schema_examples(cx).expect("core runtime should install browse schema examples");
201}
202
203#[cfg(any(
204    feature = "numbers-f64",
205    feature = "numbers-i64",
206    feature = "numbers-bool",
207    feature = "numbers-float",
208    feature = "numbers-bigint",
209    feature = "numbers-rational",
210    feature = "numbers-tensor",
211    feature = "numbers-cas",
212    feature = "numbers-complex",
213    feature = "numbers-exotic",
214    feature = "numbers-func"
215))]
216fn install_number_domain<L: Lib>(cx: &mut Cx, symbol: Symbol, lib: L, message: &'static str) {
217    if cx.registry().number_domain_by_symbol(&symbol).is_none() {
218        cx.load_lib(&lib).expect(message);
219    }
220}
221
222#[cfg(any(
223    feature = "numbers-fixed",
224    feature = "numbers-tensor-bcast",
225    feature = "numbers-quad",
226    feature = "numbers-rk"
227))]
228fn install_registered_lib<L: Lib>(cx: &mut Cx, symbol: Symbol, lib: L, message: &'static str) {
229    let _ = symbol;
230    sim_lib_core::install_once(cx, &lib).expect(message);
231}
232
233#[cfg(any(
234    feature = "numbers-cas-diff",
235    feature = "numbers-cas-eval",
236    feature = "numbers-arith",
237    feature = "numbers-numeric",
238    feature = "numbers-tensor-linalg"
239))]
240fn install_function_lib<L: Lib>(cx: &mut Cx, symbol: Symbol, lib: L, message: &'static str) {
241    if cx.registry().function_by_symbol(&symbol).is_none() {
242        cx.load_lib(&lib).expect(message);
243    }
244}