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-tensor-bit")]
115 install_registered_lib(
116 cx,
117 Symbol::qualified("numbers", "tensor-bit"),
118 crate::numbers_tensor_bit::BitTensorLib::new(),
119 "core runtime should install bit tensor domains",
120 );
121 #[cfg(feature = "numbers-tensor-cmplxf")]
122 install_registered_lib(
123 cx,
124 Symbol::qualified("numbers", "tensor-cmplxf"),
125 crate::numbers_tensor_cmplxf::ComplexFTensorLib::new(),
126 "core runtime should install complex tensor domains",
127 );
128 #[cfg(feature = "numbers-tensor-f64")]
129 install_registered_lib(
130 cx,
131 Symbol::qualified("numbers", "tensor-f64"),
132 crate::numbers_tensor_f64::F64TensorLib::new(),
133 "core runtime should install f64 tensor domains",
134 );
135 #[cfg(feature = "numbers-tensor-i64")]
136 install_registered_lib(
137 cx,
138 Symbol::qualified("numbers", "tensor-i64"),
139 crate::numbers_tensor_i64::I64TensorLib::new(),
140 "core runtime should install i64 tensor domains",
141 );
142 #[cfg(feature = "numbers-tensor-rat64")]
143 install_registered_lib(
144 cx,
145 Symbol::qualified("numbers", "tensor-rat64"),
146 crate::numbers_tensor_rat64::Rat64TensorLib::new(),
147 "core runtime should install rational tensor domains",
148 );
149 #[cfg(feature = "numbers-cas")]
150 install_number_domain(
151 cx,
152 Symbol::qualified("numbers", "cas"),
153 crate::numbers_cas::CasNumbersLib::new(),
154 "core runtime should install the default numbers/cas domain",
155 );
156 #[cfg(feature = "numbers-cas-diff")]
157 install_function_lib(
158 cx,
159 Symbol::new("diff"),
160 crate::numbers_cas_diff::CasDiffLib::new(),
161 "core runtime should install CAS differentiation helpers",
162 );
163 #[cfg(feature = "numbers-cas-eval")]
164 install_function_lib(
165 cx,
166 Symbol::new("eval-cas"),
167 crate::numbers_cas_eval::CasEvalLib::new(),
168 "core runtime should install CAS evaluation helpers",
169 );
170 #[cfg(feature = "numbers-complex")]
171 install_number_domain(
172 cx,
173 Symbol::qualified("numbers", "complex"),
174 crate::numbers_complex::ComplexNumbersLib::new(),
175 "core runtime should install the default numbers/complex domain",
176 );
177 #[cfg(feature = "numbers-exotic")]
178 install_number_domain(
179 cx,
180 Symbol::qualified("numbers", "cf"),
181 crate::numbers_exotic::ExoticNumbersLib::new(),
182 "core runtime should install the default numbers/cf domain",
183 );
184 #[cfg(feature = "numbers-func")]
185 install_number_domain(
186 cx,
187 Symbol::qualified("numbers", "func"),
188 crate::numbers_func::FuncNumbersLib::new(),
189 "core runtime should install the default numbers/func domain",
190 );
191 #[cfg(feature = "numbers-arith")]
192 install_function_lib(
193 cx,
194 Symbol::qualified("math", "add"),
195 crate::numbers_arith::NumbersArithmeticLib::new(),
196 "core runtime should install generic numeric arithmetic functions",
197 );
198 #[cfg(feature = "numbers-numeric")]
199 install_function_lib(
200 cx,
201 Symbol::new("numeric-diff"),
202 crate::numbers_numeric::NumericNumbersLib::new(),
203 "core runtime should install numeric method registry functions",
204 );
205 #[cfg(feature = "numbers-quad")]
206 install_registered_lib(
207 cx,
208 Symbol::qualified("numbers", "quad"),
209 crate::numbers_quad::QuadNumbersLib::new(),
210 "core runtime should install standard quadrature and finite-difference plugins",
211 );
212 #[cfg(feature = "numbers-rk")]
213 install_registered_lib(
214 cx,
215 Symbol::qualified("numbers", "rk"),
216 crate::numbers_rk::RkNumbersLib::new(),
217 "core runtime should install standard ODE solver plugins",
218 );
219 #[cfg(feature = "numbers-tensor-bcast")]
220 install_registered_lib(
221 cx,
222 Symbol::qualified("numbers", "tensor-bcast"),
223 crate::numbers_tensor_bcast::TensorBroadcastLib::new(),
224 "core runtime should install tensor broadcasting rules",
225 );
226 #[cfg(feature = "numbers-tensor-linalg")]
227 install_function_lib(
228 cx,
229 Symbol::new("dot"),
230 crate::numbers_tensor_linalg::TensorLinalgLib::new(),
231 "core runtime should install tensor linear algebra helpers",
232 );
233
234 install_optional_runtime_libs(cx);
235 install_schema_examples(cx).expect("core runtime should install browse schema examples");
236}
237
238#[cfg(any(
239 feature = "numbers-f64",
240 feature = "numbers-i64",
241 feature = "numbers-bool",
242 feature = "numbers-float",
243 feature = "numbers-bigint",
244 feature = "numbers-rational",
245 feature = "numbers-tensor",
246 feature = "numbers-cas",
247 feature = "numbers-complex",
248 feature = "numbers-exotic",
249 feature = "numbers-func"
250))]
251fn install_number_domain<L: Lib>(cx: &mut Cx, symbol: Symbol, lib: L, message: &'static str) {
252 if cx.registry().number_domain_by_symbol(&symbol).is_none() {
253 cx.load_lib(&lib).expect(message);
254 }
255}
256
257#[cfg(any(
258 feature = "numbers-fixed",
259 feature = "numbers-tensor-bcast",
260 feature = "numbers-tensor-bit",
261 feature = "numbers-tensor-cmplxf",
262 feature = "numbers-tensor-f64",
263 feature = "numbers-tensor-i64",
264 feature = "numbers-tensor-rat64",
265 feature = "numbers-quad",
266 feature = "numbers-rk"
267))]
268fn install_registered_lib<L: Lib>(cx: &mut Cx, symbol: Symbol, lib: L, message: &'static str) {
269 let _ = symbol;
270 sim_lib_core::install_once(cx, &lib).expect(message);
271}
272
273#[cfg(any(
274 feature = "numbers-cas-diff",
275 feature = "numbers-cas-eval",
276 feature = "numbers-arith",
277 feature = "numbers-numeric",
278 feature = "numbers-tensor-linalg"
279))]
280fn install_function_lib<L: Lib>(cx: &mut Cx, symbol: Symbol, lib: L, message: &'static str) {
281 if cx.registry().function_by_symbol(&symbol).is_none() {
282 cx.load_lib(&lib).expect(message);
283 }
284}