gaia_assembler/assembler/
mod.rs

1//! Gaia 统一编译器
2//!
3//! 提供统一的编译接口,支持编译到多个目标平台
4
5use crate::{backends::*, program::GaiaProgram};
6use gaia_types::{helpers::CompilationTarget, GaiaErrorKind, *};
7
8/// Gaia 编译器
9pub struct GaiaAssembler {
10    backends: Vec<Box<dyn Backend>>,
11}
12
13impl GaiaAssembler {
14    /// 创建新的编译器实例,包含所有可用的后端
15    pub fn new() -> Self {
16        let backends: Vec<Box<dyn Backend>> =
17            vec![Box::new(ClrBackend {}), Box::new(JvmBackend {}), Box::new(PeBackend {}), Box::new(WasiBackend {})];
18
19        Self { backends }
20    }
21
22    /// 编译 Gaia 程序到指定目标
23    pub fn compile(&self, program: &GaiaProgram, target: &CompilationTarget) -> Result<GeneratedFiles> {
24        // 计算每个后端的匹配度并找到最佳匹配
25        let mut best_backend: Option<&Box<dyn Backend>> = None;
26        let mut best_score = 0.0;
27
28        for backend in &self.backends {
29            let score = backend.match_score(target);
30            if score > best_score {
31                best_score = score;
32                best_backend = Some(backend);
33            }
34        }
35
36        if best_score == 0.0 || best_backend.is_none() {
37            return Err(GaiaErrorKind::UnsupportedTarget { target: target.clone() }.into());
38        }
39
40        // 创建默认配置
41        let config = crate::config::GaiaConfig::default();
42
43        // 使用最佳匹配的后端进行编译
44        best_backend.unwrap().generate(program, &config)
45    }
46
47    /// 获取所有可用的后端
48    pub fn backends(&self) -> &[Box<dyn Backend>] {
49        &self.backends
50    }
51}
52
53/// 编译到指定平台
54pub fn compile_to_platform(program: &GaiaProgram, target: CompilationTarget) -> Result<Vec<u8>> {
55    let compiler = GaiaAssembler::new();
56    let generated_files = compiler.compile(program, &target)?;
57
58    // 从生成的文件中提取主要的二进制文件
59    // 通常第一个文件是主要的输出文件
60    if let Some((_, bytes)) = generated_files.files.iter().next() {
61        Ok(bytes.clone())
62    }
63    else {
64        Err(GaiaError::invalid_data("No output files generated"))
65    }
66}