oxur_comp/
codegen.rs

1//! Stage 4: Generate
2//!
3//! Converts Rust AST into formatted Rust source code.
4
5use crate::Result;
6
7/// Code generator produces formatted Rust source
8pub struct CodeGenerator;
9
10impl CodeGenerator {
11    pub fn new() -> Self {
12        Self
13    }
14
15    /// Generate formatted Rust source from AST
16    pub fn generate(&self, file: &syn::File) -> Result<String> {
17        // Use prettyplease for formatting
18        Ok(prettyplease::unparse(file))
19    }
20}
21
22impl Default for CodeGenerator {
23    fn default() -> Self {
24        Self::new()
25    }
26}
27
28#[cfg(test)]
29mod tests {
30    use super::*;
31
32    #[test]
33    fn test_codegen_empty_file() {
34        let gen = CodeGenerator::new();
35        let file = syn::File { shebang: None, attrs: vec![], items: vec![] };
36        let result = gen.generate(&file);
37        assert!(result.is_ok());
38    }
39
40    #[test]
41    fn test_codegen_default() {
42        let gen = CodeGenerator;
43        let file = syn::File { shebang: None, attrs: vec![], items: vec![] };
44        let result = gen.generate(&file);
45        assert!(result.is_ok());
46    }
47
48    #[test]
49    fn test_generate_returns_string() {
50        let gen = CodeGenerator::new();
51        let file = syn::File { shebang: None, attrs: vec![], items: vec![] };
52        let result = gen.generate(&file).unwrap();
53        assert!(result.is_empty() || !result.is_empty()); // Just check it's a string
54    }
55
56    #[test]
57    fn test_generate_hello_world() {
58        use crate::lowering::Lowerer;
59        use oxur_lang::{Expander, Parser};
60
61        // Parse, expand, and lower
62        let source = r#"(deffn main ()
63  (println! "Hello, world!"))"#;
64
65        let mut parser = Parser::new(source.to_string());
66        let surface_forms = parser.parse().unwrap();
67
68        let mut expander = Expander::new();
69        let core_forms = expander.expand(surface_forms).unwrap();
70
71        let source_map = expander.source_map().clone();
72        let mut lowerer = Lowerer::new(source_map);
73        let (file, _source_map) = lowerer.lower(core_forms).unwrap();
74
75        // Generate Rust source
76        let gen = CodeGenerator::new();
77        let rust_code = gen.generate(&file).unwrap();
78
79        // Print for verification
80        eprintln!("Generated Rust code:\n{}", rust_code);
81
82        // Check the generated code
83        assert!(rust_code.contains("fn main"));
84        assert!(rust_code.contains("println!"));
85        assert!(rust_code.contains("Hello, world!"));
86    }
87}