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
20pub 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
46pub 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}