Skip to main content

batch_test/
batch_test.rs

1use std::fs;
2use std::path::Path;
3use uxn_tal::{Assembler, AssemblerError};
4
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6    println!("šŸ”Ø UXN TAL Batch Assembler Test");
7    println!("Testing all TAL files in the project");
8    println!("====================================");
9
10    let tal_files = find_tal_files(".")?;
11    let mut successful = 0;
12    let mut failed = 0;
13    let mut total_size = 0;
14
15    for file_path in &tal_files {
16        print!("Assembling {}... ", file_path);
17
18        match assemble_file(file_path) {
19            Ok(size) => {
20                println!("āœ… Success ({} bytes)", size);
21                successful += 1;
22                total_size += size;
23            }
24            Err(e) => {
25                println!("āŒ Failed: {}", e);
26                failed += 1;
27            }
28        }
29    }
30
31    println!("\nšŸ“Š Summary:");
32    println!("===========");
33    println!("Total files: {}", tal_files.len());
34    println!(
35        "Successful: {} ({:.1}%)",
36        successful,
37        (successful as f64 / tal_files.len() as f64) * 100.0
38    );
39    println!(
40        "Failed: {} ({:.1}%)",
41        failed,
42        (failed as f64 / tal_files.len() as f64) * 100.0
43    );
44    println!("Total ROM size: {} bytes", total_size);
45
46    if failed > 0 {
47        println!("\nāš ļø  Failed files may need additional TAL features or contain syntax errors.");
48    } else {
49        println!("\nšŸŽ‰ All TAL files assembled successfully!");
50    }
51
52    Ok(())
53}
54
55fn find_tal_files(dir: &str) -> Result<Vec<String>, Box<dyn std::error::Error>> {
56    let mut tal_files = Vec::new();
57    find_tal_files_recursive(Path::new(dir), &mut tal_files)?;
58    tal_files.sort();
59    Ok(tal_files)
60}
61
62fn find_tal_files_recursive(
63    dir: &Path,
64    tal_files: &mut Vec<String>,
65) -> Result<(), Box<dyn std::error::Error>> {
66    if dir.is_dir() {
67        for entry in fs::read_dir(dir)? {
68            let entry = entry?;
69            let path = entry.path();
70
71            if path.is_dir() {
72                // Skip target directories and hidden directories
73                if let Some(dir_name) = path.file_name().and_then(|n| n.to_str()) {
74                    if dir_name.starts_with('.') || dir_name == "target" {
75                        continue;
76                    }
77                }
78                find_tal_files_recursive(&path, tal_files)?;
79            } else if let Some(extension) = path.extension() {
80                if extension == "tal" {
81                    if let Some(path_str) = path.to_str() {
82                        tal_files.push(path_str.to_string());
83                    }
84                }
85            }
86        }
87    }
88    Ok(())
89}
90
91fn assemble_file(file_path: &str) -> Result<usize, String> {
92    let source =
93        fs::read_to_string(file_path).map_err(|e| format!("Failed to read file: {}", e))?;
94
95    let mut assembler = Assembler::new();
96    match assembler.assemble(&source, Some(file_path.to_string())) {
97        Ok(rom) => {
98            // Save the ROM file
99            let rom_path = file_path.replace(".tal", ".rom");
100            if let Err(e) = fs::write(&rom_path, &rom) {
101                return Err(format!("Failed to write ROM: {}", e));
102            }
103            Ok(rom.len())
104        }
105        Err(e) => {
106            // Extract line information from the error if available
107            let error_msg = match &e {
108                AssemblerError::SyntaxError {
109                    line,
110                    message,
111                    path,
112                    position,
113                    source_line,
114                } => {
115                    format!(
116                        "{}:{}:{}: {}\n    {}",
117                        path, line, position, message, source_line
118                    )
119                }
120                _ => {
121                    format!("{}: {}", file_path, e)
122                }
123            };
124            Err(error_msg)
125        }
126    }
127}