Skip to main content

spydecy_debugger/
state.rs

1//! Transpilation State Tracking
2//!
3//! Tracks the state of transpilation through all phases for step-through debugging.
4
5use anyhow::Result;
6use serde::{Deserialize, Serialize};
7use spydecy_hir::{c::CHIR, python::PythonHIR, unified::UnifiedHIR};
8use std::path::PathBuf;
9
10/// Current phase of transpilation
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
12pub enum TranspilationPhase {
13    /// Initial state
14    Start,
15    /// Python source parsed to AST
16    PythonParsed,
17    /// Python AST converted to HIR
18    PythonHIR,
19    /// C source parsed to AST
20    CParsed,
21    /// C AST converted to HIR
22    CHIR,
23    /// Python + C unified
24    UnifiedHIR,
25    /// HIR optimized
26    Optimized,
27    /// Rust code generated
28    RustGenerated,
29    /// Complete
30    Complete,
31}
32
33impl TranspilationPhase {
34    /// Get human-readable name
35    #[must_use]
36    pub const fn name(self) -> &'static str {
37        match self {
38            Self::Start => "Start",
39            Self::PythonParsed => "Python Parsed",
40            Self::PythonHIR => "Python HIR",
41            Self::CParsed => "C Parsed",
42            Self::CHIR => "C HIR",
43            Self::UnifiedHIR => "Unified HIR",
44            Self::Optimized => "Optimized",
45            Self::RustGenerated => "Rust Generated",
46            Self::Complete => "Complete",
47        }
48    }
49
50    /// Get the next phase
51    #[must_use]
52    pub const fn next(self) -> Option<Self> {
53        match self {
54            Self::Start => Some(Self::PythonParsed),
55            Self::PythonParsed => Some(Self::PythonHIR),
56            Self::PythonHIR => Some(Self::CParsed),
57            Self::CParsed => Some(Self::CHIR),
58            Self::CHIR => Some(Self::UnifiedHIR),
59            Self::UnifiedHIR => Some(Self::Optimized),
60            Self::Optimized => Some(Self::RustGenerated),
61            Self::RustGenerated => Some(Self::Complete),
62            Self::Complete => None,
63        }
64    }
65}
66
67/// Transpilation state snapshot
68#[derive(Debug, Clone)]
69pub struct TranspilationState {
70    /// Current phase
71    pub phase: TranspilationPhase,
72    /// Step count
73    pub step_count: usize,
74    /// Python source file
75    pub python_file: Option<PathBuf>,
76    /// C source file
77    pub c_file: Option<PathBuf>,
78    /// Python source code
79    pub python_source: Option<String>,
80    /// C source code
81    pub c_source: Option<String>,
82    /// Python HIR
83    pub python_hir: Option<PythonHIR>,
84    /// C HIR
85    pub c_hir: Option<CHIR>,
86    /// Unified HIR
87    pub unified_hir: Option<UnifiedHIR>,
88    /// Optimized HIR
89    pub optimized_hir: Option<UnifiedHIR>,
90    /// Generated Rust code
91    pub rust_code: Option<String>,
92}
93
94impl TranspilationState {
95    /// Create new state
96    #[must_use]
97    pub fn new(python_file: PathBuf, c_file: PathBuf) -> Self {
98        Self {
99            phase: TranspilationPhase::Start,
100            step_count: 0,
101            python_file: Some(python_file),
102            c_file: Some(c_file),
103            python_source: None,
104            c_source: None,
105            python_hir: None,
106            c_hir: None,
107            unified_hir: None,
108            optimized_hir: None,
109            rust_code: None,
110        }
111    }
112
113    /// Advance to next phase
114    ///
115    /// # Errors
116    ///
117    /// Returns error if already at final phase
118    pub fn advance(&mut self) -> Result<TranspilationPhase> {
119        if let Some(next) = self.phase.next() {
120            self.phase = next;
121            self.step_count += 1;
122            Ok(next)
123        } else {
124            anyhow::bail!("Already at final phase");
125        }
126    }
127
128    /// Check if transpilation is complete
129    #[must_use]
130    pub const fn is_complete(&self) -> bool {
131        matches!(self.phase, TranspilationPhase::Complete)
132    }
133}