use anyhow::Result;
use serde::{Deserialize, Serialize};
use spydecy_hir::{c::CHIR, python::PythonHIR, unified::UnifiedHIR};
use std::path::PathBuf;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum TranspilationPhase {
Start,
PythonParsed,
PythonHIR,
CParsed,
CHIR,
UnifiedHIR,
Optimized,
RustGenerated,
Complete,
}
impl TranspilationPhase {
#[must_use]
pub const fn name(self) -> &'static str {
match self {
Self::Start => "Start",
Self::PythonParsed => "Python Parsed",
Self::PythonHIR => "Python HIR",
Self::CParsed => "C Parsed",
Self::CHIR => "C HIR",
Self::UnifiedHIR => "Unified HIR",
Self::Optimized => "Optimized",
Self::RustGenerated => "Rust Generated",
Self::Complete => "Complete",
}
}
#[must_use]
pub const fn next(self) -> Option<Self> {
match self {
Self::Start => Some(Self::PythonParsed),
Self::PythonParsed => Some(Self::PythonHIR),
Self::PythonHIR => Some(Self::CParsed),
Self::CParsed => Some(Self::CHIR),
Self::CHIR => Some(Self::UnifiedHIR),
Self::UnifiedHIR => Some(Self::Optimized),
Self::Optimized => Some(Self::RustGenerated),
Self::RustGenerated => Some(Self::Complete),
Self::Complete => None,
}
}
}
#[derive(Debug, Clone)]
pub struct TranspilationState {
pub phase: TranspilationPhase,
pub step_count: usize,
pub python_file: Option<PathBuf>,
pub c_file: Option<PathBuf>,
pub python_source: Option<String>,
pub c_source: Option<String>,
pub python_hir: Option<PythonHIR>,
pub c_hir: Option<CHIR>,
pub unified_hir: Option<UnifiedHIR>,
pub optimized_hir: Option<UnifiedHIR>,
pub rust_code: Option<String>,
}
impl TranspilationState {
#[must_use]
pub fn new(python_file: PathBuf, c_file: PathBuf) -> Self {
Self {
phase: TranspilationPhase::Start,
step_count: 0,
python_file: Some(python_file),
c_file: Some(c_file),
python_source: None,
c_source: None,
python_hir: None,
c_hir: None,
unified_hir: None,
optimized_hir: None,
rust_code: None,
}
}
pub fn advance(&mut self) -> Result<TranspilationPhase> {
if let Some(next) = self.phase.next() {
self.phase = next;
self.step_count += 1;
Ok(next)
} else {
anyhow::bail!("Already at final phase");
}
}
#[must_use]
pub const fn is_complete(&self) -> bool {
matches!(self.phase, TranspilationPhase::Complete)
}
}