gaia_assembler/assembler/
mod.rs1use crate::{backends::*, program::GaiaModule};
6use gaia_types::{helpers::CompilationTarget, GaiaErrorKind, *};
7
8pub struct GaiaAssembler {
10 backends: Vec<Box<dyn Backend>>,
11}
12
13impl GaiaAssembler {
14 pub fn new() -> Self {
16 #[allow(unused_mut)]
17 let mut backends: Vec<Box<dyn Backend>> = vec![];
18
19 #[cfg(feature = "jvm-assembler")]
20 backends.push(Box::new(JvmBackend {}));
21 #[cfg(feature = "pe-assembler")]
22 backends.push(Box::new(WindowsBackend {}));
23 #[cfg(feature = "wasi-assembler")]
24 backends.push(Box::new(WasiBackend {}));
25 #[cfg(feature = "x86_64-assembler")]
26 backends.push(Box::new(X64Backend {}));
27 #[cfg(feature = "gcn-assembler")]
28 backends.push(Box::new(GcnBackend::new()));
29 #[cfg(feature = "sass-assembler")]
30 backends.push(Box::new(SassBackend::new()));
31 #[cfg(feature = "clr-assembler")]
32 backends.push(Box::new(ClrBackend {}));
33 #[cfg(feature = "elf-assembler")]
34 backends.push(Box::new(ElfBackend {}));
35 #[cfg(feature = "macho-assembler")]
36 backends.push(Box::new(MachoBackend {}));
37 #[cfg(feature = "lua-assembler")]
38 backends.push(Box::new(LuaBackend {}));
39 #[cfg(feature = "llvm-assembler")]
40 backends.push(Box::new(LlvmBackend {}));
41 #[cfg(feature = "msl-assembler")]
42 backends.push(Box::new(MslBackend {}));
43 #[cfg(feature = "spirv-assembler")]
44 backends.push(Box::new(SpirvBackend {}));
45 #[cfg(feature = "python-assembler")]
46 backends.push(Box::new(PythonBackend {}));
47 #[cfg(feature = "nyar-assembler")]
48 backends.push(Box::new(NyarBackend {}));
49
50 Self { backends }
51 }
52
53 pub fn compile(&self, program: &GaiaModule, target: &CompilationTarget) -> Result<GeneratedFiles> {
55 let mut best_backend: Option<&Box<dyn Backend>> = None;
57 let mut best_score = 0.0;
58
59 if let Some(candidate) = self.backends.iter().find(|b| {
61 let pt = b.primary_target();
62 pt.host == target.host && pt.build == target.build
63 }) {
64 best_backend = Some(candidate);
65 best_score = 100.0; }
67
68 if best_backend.is_none() {
70 for backend in &self.backends {
71 let score = backend.match_score(target);
72 if score > best_score {
73 best_score = score;
74 best_backend = Some(backend);
75 }
76 }
77 }
78
79 if best_backend.is_none() || best_score <= 0.0 {
80 return Err(GaiaErrorKind::UnsupportedTarget { target: target.clone() }.into());
81 }
82
83 let mut config = crate::config::GaiaConfig::default();
85 config.target = target.clone();
86
87 best_backend.unwrap().generate(program, &config)
89 }
90
91 pub fn backends(&self) -> &[Box<dyn Backend>] {
93 &self.backends
94 }
95}
96
97pub fn compile_to_platform(program: &GaiaModule, target: CompilationTarget) -> Result<Vec<u8>> {
99 let compiler = GaiaAssembler::new();
100 let generated_files = compiler.compile(program, &target)?;
101
102 if let Some((_, bytes)) = generated_files.files.iter().next() {
105 Ok(bytes.clone())
106 }
107 else {
108 Err(GaiaError::invalid_data("No output files generated"))
109 }
110}