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 Box::new(JvmBackend {}),
19 Box::new(PeBackend {}),
20 Box::new(WasiBackend {}),
21 Box::new(X86Backend {}),
22 Box::new(GcnBackend::new()),
23 Box::new(SassBackend::new()),
24 ];
25
26 #[cfg(feature = "clr")]
27 backends.push(Box::new(ClrBackend {}));
28
29 Self { backends }
30 }
31
32 pub fn compile(&self, program: &GaiaModule, target: &CompilationTarget) -> Result<GeneratedFiles> {
34 let mut best_backend: Option<&Box<dyn Backend>> = None;
36 let mut best_score = 0.0;
37
38 if let Some(candidate) = self.backends.iter().find(|b| {
40 let pt = b.primary_target();
41 pt.host == target.host && pt.build == target.build
42 }) {
43 best_backend = Some(candidate);
44 best_score = 100.0; }
46
47 if best_backend.is_none() {
49 for backend in &self.backends {
50 let score = backend.match_score(target);
51 if score > best_score {
52 best_score = score;
53 best_backend = Some(backend);
54 }
55 }
56 }
57
58 if best_backend.is_none() || best_score <= 0.0 {
59 return Err(GaiaErrorKind::UnsupportedTarget { target: target.clone() }.into());
60 }
61
62 let mut config = crate::config::GaiaConfig::default();
64 config.target = target.clone();
65
66 best_backend.unwrap().generate(program, &config)
68 }
69
70 pub fn backends(&self) -> &[Box<dyn Backend>] {
72 &self.backends
73 }
74}
75
76pub fn compile_to_platform(program: &GaiaModule, target: CompilationTarget) -> Result<Vec<u8>> {
78 let compiler = GaiaAssembler::new();
79 let generated_files = compiler.compile(program, &target)?;
80
81 if let Some((_, bytes)) = generated_files.files.iter().next() {
84 Ok(bytes.clone())
85 }
86 else {
87 Err(GaiaError::invalid_data("No output files generated"))
88 }
89}