1#[cfg(all(feature = "compiler", any(target_arch = "wasm32", feature = "embed")))]
16use crate::compiler::compile;
17#[cfg(feature = "compiler")]
21use crate::errors::BOLD;
22#[cfg(feature = "compiler")]
23use crate::errors::ErrorCtx;
24#[cfg(feature = "compiler")]
25use crate::errors::RED;
26#[cfg(feature = "compiler")]
27use crate::errors::RESET;
28use crate::vm::RegisterFile;
29#[cfg(all(feature = "embed", feature = "compiler"))]
30use std::ffi::{CStr, CString, c_char};
31#[cfg(feature = "compiler")]
32use std::hint::cold_path;
33#[cfg(all(feature = "embed", feature = "compiler"))]
34use std::panic::catch_unwind;
35#[cfg(target_arch = "wasm32")]
36use wasm_bindgen::prelude::*;
37
38pub(crate) use candela_vm::data;
42pub(crate) use candela_vm::errors;
43pub(crate) use candela_vm::instr;
44pub(crate) use candela_vm::rt;
45pub(crate) use candela_vm::vm;
46
47#[cfg(feature = "compiler")]
51#[path = "./compiler/compiler.rs"]
52pub mod compiler;
53#[cfg(feature = "compiler")]
56mod engine;
57#[cfg(feature = "compiler")]
59mod build;
60#[cfg(all(feature = "native", not(target_arch = "wasm32")))]
62pub mod native;
63#[cfg(all(feature = "compiler", not(target_arch = "wasm32")))]
65mod cli;
66#[cfg(all(feature = "compiler", not(target_arch = "wasm32")))]
68mod lpm;
69#[cfg(all(feature = "compiler", not(target_arch = "wasm32")))]
71mod manifest;
72#[cfg(feature = "compiler")]
74pub mod cfg;
75#[cfg(feature = "compiler")]
79pub mod macros;
80#[cfg(feature = "compiler")]
83#[path = "./parser/parser.rs"]
84pub mod parser;
85#[cfg(feature = "compiler")]
86mod repl;
87#[path = "./tests.rs"]
88#[cfg(all(test, feature = "compiler"))]
89mod tests;
90#[cfg(feature = "compiler")]
93mod trampoline;
94#[cfg(feature = "compiler")]
97mod update;
98#[path = "./util/util.rs"]
99mod util;
100#[cfg(feature = "compiler")]
103mod warnings;
104
105pub use candela_vm::Diagnostic;
106pub use candela_vm::collect_diagnostic;
107
108pub use candela_vm::FromHostValue;
109pub use candela_vm::HostError;
110pub use candela_vm::HostType;
111pub use candela_vm::IntoHostFn;
112pub use candela_vm::IntoHostResult;
113pub use candela_vm::IntoHostValue;
114pub use candela_vm::Value;
115#[cfg(feature = "compiler")]
116pub use cfg::Cfg;
117#[cfg(feature = "compiler")]
118pub use engine::Engine;
119#[cfg(feature = "compiler")]
120pub use engine::Program;
121#[cfg(feature = "compiler")]
124pub use compiler::imports::ImportResolver;
125
126pub use candela_vm::CallError;
128pub use candela_vm::HostBindError;
129pub use candela_vm::HostRegistry;
130pub use candela_vm::LoadError;
131pub use candela_vm::RuntimeProgram;
132pub use candela_vm::load_program;
133pub use candela_vm::GcStats;
135pub use candela_vm::PoolStats;
136pub use candela_vm::dylib_dirs;
140pub use candela_vm::set_dylib_dirs;
141#[cfg(feature = "compiler")]
144pub use build::build_bytecode;
145#[cfg(feature = "compiler")]
147pub use build::BuildOptions;
148#[cfg(feature = "compiler")]
149pub use build::NativeCode;
150#[cfg(feature = "compiler")]
151pub use build::build_artifact;
152#[cfg(feature = "compiler")]
157pub use trampoline::compile_checked;
158#[cfg(feature = "compiler")]
161pub use trampoline::check_only;
162#[cfg(feature = "compiler")]
164pub use warnings::collect_warnings;
165#[cfg(feature = "compiler")]
170pub use compiler::compiler_data::TypeNames;
171
172#[cfg(feature = "compiler")]
176pub(crate) fn execute_compiled(out: compiler::CompileOutput) {
177 out.require_main();
179 let compiler::CompileOutput {
180 instructions,
181 registers,
182 mut pools,
183 instr_src,
184 callsite_registers,
185 dyn_lib_fns,
186 structs,
187 enums,
188 allocated_arg_count,
189 allocated_call_depth,
190 sources,
191 ..
192 } = out;
193 let err_ctx = ErrorCtx {
194 instr_src: &instr_src,
195 sources: &sources,
196 };
197 if let Err(error) = vm::execute(
198 &instructions,
199 &mut RegisterFile(registers),
200 &mut pools,
201 &err_ctx,
202 &callsite_registers,
203 &dyn_lib_fns,
204 &structs,
205 &enums,
206 allocated_arg_count,
207 allocated_call_depth,
208 &[],
209 &[],
210 0,
211 None,
212 ) {
213 error.report(&err_ctx);
214 }
215}
216
217#[cfg(target_arch = "wasm32")]
218#[wasm_bindgen]
219pub fn get_output() -> String {
220 candela_vm::captured_output::CAPTURED_OUTPUT.with(|o| o.take())
221}
222
223#[cfg(all(target_arch = "wasm32", feature = "compiler"))]
224#[wasm_bindgen]
225pub fn run(code: String) {
226 candela_vm::captured_output::CAPTURED_OUTPUT.with(|o| o.borrow_mut().clear());
227 execute_compiled(compile(
228 code,
229 "playground.cdl",
230 false,
231 &ImportResolver::new(),
232 ));
233}
234
235#[cfg(all(feature = "embed", feature = "compiler"))]
236#[unsafe(no_mangle)]
237#[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn candela_run(code: *const c_char) -> *mut c_char {
239 std::panic::set_hook(Box::new(|_| {}));
240 let code = unsafe { CStr::from_ptr(code) }
241 .to_string_lossy()
242 .to_string();
243 candela_vm::captured_output::CAPTURED_OUTPUT.with(|o| o.borrow_mut().clear());
244 let was_capturing = candela_vm::captured_output::set_capturing(true);
247 let _ = catch_unwind(|| {
248 execute_compiled(compile(code, "embedded.cdl", false, &ImportResolver::new()));
249 });
250 candela_vm::captured_output::set_capturing(was_capturing);
251 let output = candela_vm::captured_output::CAPTURED_OUTPUT.with(|o| o.take());
252 CString::new(output).unwrap_or_default().into_raw()
253}
254
255#[cfg(all(feature = "embed", feature = "compiler"))]
256#[unsafe(no_mangle)]
257#[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn candela_free_output(output: *mut c_char) {
259 if !output.is_null() {
260 #[allow(unused_must_use)]
261 unsafe {
262 CString::from_raw(output)
263 };
264 }
265}
266
267#[cfg(all(feature = "compiler", not(target_arch = "wasm32")))]
269#[must_use]
270pub fn main() -> std::process::ExitCode {
271 #[cfg(not(debug_assertions))]
272 std::panic::set_hook(Box::new(|info| {
273 eprintln!("{RED}CANDELA ERROR{RESET}\n{info}");
274 }));
275
276 cli::main()
277}