Skip to main content

spydecy_debugger/
lib.rs

1//! Spydecy Interactive Debugger
2//!
3//! This module implements the introspective debugger that allows stepping through
4//! the transpilation process to identify issues. Built incrementally alongside
5//! the transpiler (per Gemini's recommendation).
6//!
7//! # Sprint 2 Feature
8//!
9//! `visualize python-ast` - Display Python AST and HIR conversion
10
11#![warn(missing_docs, clippy::all, clippy::pedantic)]
12#![deny(unsafe_code)]
13#![allow(
14    clippy::module_name_repetitions,
15    clippy::format_push_string,
16    clippy::str_to_string,
17    clippy::unwrap_used,
18    clippy::uninlined_format_args
19)]
20
21pub mod commands;
22pub mod repl;
23pub mod state;
24pub mod stepper;
25pub mod visualize;
26
27use anyhow::Result;
28use state::TranspilationState;
29use std::path::{Path, PathBuf};
30
31/// Visualize Python AST for debugging
32///
33/// # Errors
34///
35/// Returns an error if the file cannot be read or parsed
36pub fn visualize_python_ast(file_path: &Path) -> Result<String> {
37    visualize::visualize_python(file_path)
38}
39
40/// Visualize C AST with `CPython` API annotations for debugging
41///
42/// # Errors
43///
44/// Returns an error if the file cannot be read or parsed
45pub fn visualize_c_ast(file_path: &Path) -> Result<String> {
46    visualize::visualize_c(file_path)
47}
48
49/// Start interactive step-through debugging session
50///
51/// # Errors
52///
53/// Returns an error if files cannot be read or REPL fails
54pub fn start_interactive_debugger(python_file: PathBuf, c_file: PathBuf) -> Result<()> {
55    let state = TranspilationState::new(python_file, c_file);
56    let stepper = stepper::Stepper::new(state);
57    repl::run_repl(stepper)
58}
59
60#[cfg(test)]
61mod tests {
62    use super::*;
63    use std::io::Write;
64    use tempfile::NamedTempFile;
65
66    #[test]
67    fn test_visualize_simple_function() {
68        let mut temp_file = NamedTempFile::new().unwrap();
69        writeln!(temp_file, "def my_len(x):\n    return len(x)").unwrap();
70
71        let result = visualize_python_ast(temp_file.path());
72        assert!(result.is_ok());
73        let output = result.unwrap();
74        assert!(output.contains("Module"));
75        assert!(output.contains("FunctionDef"));
76    }
77
78    #[test]
79    fn test_visualize_invalid_syntax() {
80        let mut temp_file = NamedTempFile::new().unwrap();
81        writeln!(temp_file, "def invalid syntax here").unwrap();
82
83        let result = visualize_python_ast(temp_file.path());
84        assert!(result.is_err());
85    }
86
87    #[test]
88    fn test_visualize_c_simple_function() {
89        use std::io::Write;
90        use tempfile::Builder;
91
92        let mut temp_file = Builder::new().suffix(".c").tempfile().unwrap();
93        writeln!(temp_file, "int add(int a, int b) {{\n    return a + b;\n}}").unwrap();
94        temp_file.flush().unwrap(); // Ensure content is written
95
96        let result = visualize_c_ast(temp_file.path());
97        assert!(
98            result.is_ok(),
99            "Failed to visualize C: {:?}",
100            result.as_ref().err()
101        );
102        let output = result.unwrap();
103        assert!(output.contains("C AST Visualization"));
104        assert!(output.contains("FunctionDecl"));
105    }
106}