lift-export 0.2.0

LIFT-EXPORT: Backends — LLVM IR, OpenQASM 3, CUDA PTX (planned), XLA (planned)
Documentation
use lift_core::context::Context;
use thiserror::Error;
use std::fmt::Write;

#[derive(Debug, Error)]
pub enum LlvmExportError {
    #[error("Unsupported operation for LLVM export: {0}")]
    UnsupportedOp(String),
    #[error("Export error: {0}")]
    General(String),
}

#[derive(Debug)]
pub struct LlvmExporter;

impl LlvmExporter {
    pub fn new() -> Self { Self }

    pub fn export(&self, ctx: &Context) -> Result<String, LlvmExportError> {
        let mut output = String::new();

        let _ = writeln!(output, "; LIFT IR -> LLVM IR export");
        let _ = writeln!(output, "; Generated by LIFT framework");
        let _ = writeln!(output);

        for module in &ctx.modules {
            let name = ctx.strings.resolve(module.name);
            let _ = writeln!(output, "; Module: {}", name);

            for func in &module.functions {
                let fname = ctx.strings.resolve(func.name);
                let _ = write!(output, "define void @{}(", fname);

                for (i, _param) in func.params.iter().enumerate() {
                    if i > 0 { let _ = write!(output, ", "); }
                    let _ = write!(output, "ptr %arg{}", i);
                }

                let _ = writeln!(output, ") {{");
                let _ = writeln!(output, "entry:");

                if let Some(region_key) = func.body {
                    if let Some(region) = ctx.get_region(region_key) {
                        for &block_key in &region.blocks {
                            if let Some(block) = ctx.get_block(block_key) {
                                for &op_key in &block.ops {
                                    if let Some(op) = ctx.get_op(op_key) {
                                        let op_name = ctx.strings.resolve(op.name);
                                        let _ = writeln!(output, "  ; {}", op_name);
                                    }
                                }
                            }
                        }
                    }
                }

                let _ = writeln!(output, "  ret void");
                let _ = writeln!(output, "}}");
                let _ = writeln!(output);
            }
        }

        Ok(output)
    }
}

impl Default for LlvmExporter {
    fn default() -> Self { Self::new() }
}