comprehensive_demo/
comprehensive_demo.rs1use std::{fs, io::BufRead};
2use uxn_tal::{assemble_directory, assemble_file_with_symbols, Assembler};
3
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5 println!("šØ UXN TAL Assembler Demo");
6 println!("========================\n");
7
8 create_demo_files()?;
10
11 println!("š Demo 1: Single File Assembly");
13 let (rom_path, sym_path, size) = assemble_file_with_symbols("demo_hello.tal")?;
14 println!("ā
Assembled {} bytes to {}", size, rom_path.display());
15 println!("š Generated symbols to {}", sym_path.display());
16
17 let symbols = fs::read_to_string(&sym_path)?;
18 println!("Symbols:");
19 for line in symbols.lines() {
20 println!(" {:?}", line);
21 }
22 println!();
23
24 println!("š Demo 2: Batch Assembly");
26 let results = assemble_directory(".", true)?;
27
28 for (tal_path, rom_path, sym_path, size) in &results {
29 if tal_path
30 .file_name()
31 .unwrap()
32 .to_string_lossy()
33 .starts_with("demo_")
34 {
35 println!(
36 "ā
{} -> {} ({} bytes)",
37 tal_path.file_name().unwrap().to_string_lossy(),
38 rom_path.file_name().unwrap().to_string_lossy(),
39 size
40 );
41 if let Some(sym_path) = sym_path {
42 println!(" + {}", sym_path.file_name().unwrap().to_string_lossy());
43 }
44 }
45 }
46
47 println!("\nš§ Demo 3: Manual Assembly");
49 let tal_code = r#"
50( Counter example with $ padding )
51|0100 @main
52 #00
53 &loop
54 INC DUP
55 #0a EQU ,end JCN
56 ,loop JMP
57 &end BRK
58
59@data $1
60"#;
61
62 let mut assembler = Assembler::new();
63 let rom = assembler.assemble(tal_code, None)?;
64 println!("Generated {} bytes from inline TAL code", rom.len());
65
66 let symbols = assembler.generate_symbol_file();
67 println!("Extracted symbols:");
68 for line in symbols.lines() {
69 println!(" {:?}", line);
70 }
71
72 let binary_symbols = assembler.generate_symbol_file_binary();
74 println!("Binary symbol data: {} bytes", binary_symbols.len());
75 if let Ok(symbols_str) = String::from_utf8(binary_symbols.clone()) {
77 println!("Binary symbol lines:");
78 for line in symbols_str.lines() {
79 println!(" {}", line);
80 }
81 } else {
82 println!("Binary symbol data is not valid UTF-8, cannot print lines.");
83 }
84
85 cleanup_demo_files()?;
87
88 println!("\nš Demo complete! The assembler supports:");
89 println!(" ā
All UXN opcodes with mode flags (2, r, k)");
90 println!(" ā
Hex literals (#12, #1234)");
91 println!(" ā
Character literals ('A')");
92 println!(" ā
Labels (@main) and sublabels (&loop)");
93 println!(" ā
Label references (;main, ,loop)");
94 println!(" ā
Padding directives (|0100) and skip bytes ($10)");
95 println!(" ā
Symbol file generation (text and binary formats)");
96 println!(" ā
Batch processing with ergonomic API");
97
98 Ok(())
99}
100
101fn create_demo_files() -> Result<(), Box<dyn std::error::Error>> {
102 let hello_tal = r#"
103( Hello World Example )
104|0100 @main
105 #48 #65 #6c #6c #6f #20 #57 #6f #72 #6c #64
106 BRK
107
108@data $10
109"#;
110
111 let counter_tal = r#"
112( Simple Counter with Skip )
113|0100 @main
114 #00
115 &loop
116 INC DUP
117 #05 EQU
118 ,done JCN
119 ,loop JMP
120 &done BRK
121
122@value $1
123@buffer $10
124"#;
125
126 let echo_tal = r#"
127( Echo example with character literals )
128|0100 @main
129 'H 'e 'l 'l 'o
130 BRK
131"#;
132
133 fs::write("demo_hello.tal", hello_tal)?;
134 fs::write("demo_counter.tal", counter_tal)?;
135 fs::write("demo_echo.tal", echo_tal)?;
136
137 Ok(())
138}
139
140fn cleanup_demo_files() -> Result<(), Box<dyn std::error::Error>> {
141 let patterns = ["demo_hello", "demo_counter", "demo_echo"];
142
143 for pattern in &patterns {
144 if let Ok(entries) = fs::read_dir(".") {
145 for entry in entries.flatten() {
146 let name = entry.file_name();
147 let name_str = name.to_string_lossy();
148 if name_str.starts_with(pattern) {
149 let _ = fs::remove_file(entry.path());
150 }
151 }
152 }
153 }
154
155 Ok(())
156}