pub struct Assembler {Show 18 fields
pub rom: Rom,
pub opcodes: Opcodes,
pub symbols: HashMap<String, Symbol>,
pub symbol_order: Vec<String>,
pub macros: HashMap<String, Macro>,
pub current_label: Option<String>,
pub references: Vec<Reference>,
pub device_map: HashMap<String, Device>,
pub line_number: usize,
pub position_in_line: usize,
pub effective_length: usize,
pub lambda_counter: usize,
pub lambda_stack: Vec<usize>,
pub last_top_label: Option<String>,
pub macro_expansion_stack: Vec<String>,
pub drif_mode: bool,
pub after_unreferenced_sublabel: bool,
pub verbose: u8,
}Expand description
TAL assembler
Fields§
§rom: Rom§opcodes: Opcodes§symbols: HashMap<String, Symbol>§symbol_order: Vec<String>§macros: HashMap<String, Macro>§current_label: Option<String>§references: Vec<Reference>§device_map: HashMap<String, Device>§line_number: usize§position_in_line: usize§effective_length: usize§lambda_counter: usize§lambda_stack: Vec<usize>§last_top_label: Option<String>§macro_expansion_stack: Vec<String>§drif_mode: bool§after_unreferenced_sublabel: bool§verbose: u8Implementations§
Source§impl Assembler
impl Assembler
Sourcepub fn generate_symbol_file(&self) -> Vec<u8> ⓘ
pub fn generate_symbol_file(&self) -> Vec<u8> ⓘ
Generate symbol file content in binary format Format: [address:u16][name:null-terminated string] repeating
Examples found in repository?
examples/batch_assembler.rs (line 43)
31fn assemble_file_with_symbols(
32 path: &Path,
33) -> Result<(std::path::PathBuf, std::path::PathBuf, usize), AssemblerError> {
34 let source = std::fs::read_to_string(path)?;
35 let mut assembler = Assembler::new();
36 let canonical = std::fs::canonicalize(path)
37 .map(|p| p.to_string_lossy().to_string())
38 .unwrap_or_else(|_| path.to_string_lossy().to_string());
39 let rom = assembler.assemble(&source, Some(canonical))?;
40 let rom_path = path.with_extension("rom");
41 let sym_path = path.with_extension("sym");
42 std::fs::write(&rom_path, &rom)?;
43 let sym_txt = assembler.generate_symbol_file();
44 std::fs::write(&sym_path, sym_txt)?;
45 Ok((rom_path, sym_path, rom.len()))
46}More examples
examples/comprehensive_demo.rs (line 66)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5 println!("🔨 UXN TAL Assembler Demo");
6 println!("========================\n");
7
8 // Create some demo TAL files to show our assembler in action
9 create_demo_files()?;
10
11 // Demo 1: Single file assembly with symbols
12 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 // Demo 2: Batch assembly
25 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 // Demo 3: Show assembler flexibility
48 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 // Show binary symbol format too
73 let binary_symbols = assembler.generate_symbol_file_binary();
74 println!("Binary symbol data: {} bytes", binary_symbols.len());
75 // If you want to print lines, try converting to String (if valid UTF-8)
76 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 // Clean up demo files
86 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}examples/debug_assemble.rs (line 43)
12fn main() -> Result<(), AssemblerError> {
13 let args: Vec<String> = env::args().collect();
14 if args.len() != 2 {
15 eprintln!("Usage: {} <file.tal>", args[0]);
16 std::process::exit(1);
17 }
18 let tal_path = &args[1];
19 let source = fs::read_to_string(tal_path).map_err(|e| serr(tal_path, &format!("read: {e}")))?;
20
21 println!("== Source: {} ==", tal_path);
22 for (i, line) in source.lines().enumerate() {
23 println!("{:4}: {}", i + 1, line);
24 }
25
26 // 1. Internal assembler (non-fatal on error now)
27 let mut internal_rom: Option<Vec<u8>> = None;
28 let mut internal_err: Option<String> = None;
29 let internal_out_path = format!("{tal_path}.uxntal.rom");
30
31 let mut asm = Assembler::new();
32 match asm.assemble(&source, Some(tal_path.to_string())) {
33 Ok(bytes) => {
34 fs::write(&internal_out_path, &bytes).ok();
35 println!(
36 "\n[uxntal] OK -> {} ({} bytes)",
37 internal_out_path,
38 bytes.len()
39 );
40 internal_rom = Some(bytes);
41 // Emit symbol file from the same assembler instance.
42 let sym_path = format!("{}.sym", &internal_out_path);
43 let sym_bytes = asm.generate_symbol_file();
44 let _ = fs::write(&sym_path, &sym_bytes);
45 if have_uxncli() && Path::new("uxndis.rom").exists() {
46 dump_disassembly(&internal_out_path);
47 }
48 }
49 Err(e) => {
50 println!("\n[uxntal] FAIL: {e}");
51 internal_err = Some(format!("{e}"));
52 }
53 }
54
55 // 2. External backends (always attempted)
56 println!("\nRunning external backends...");
57 let uxna = run_uxnasm(tal_path);
58 let drif = run_drifblim(tal_path); // optional
59 if have_uxncli() && Path::new("uxndis.rom").exists() {
60 if internal_rom.is_some() {
61 dump_disassembly(&internal_out_path);
62 }
63 for r in [&uxna, &drif] {
64 if r.ok {
65 if let Some(ref rp) = r.rom_path {
66 dump_disassembly(rp);
67 }
68 }
69 }
70 }
71
72 // 3. Summary
73 println!("\n== Backend Summary ==");
74 println!(
75 " {:<9} {:<5} {:>8} output/summary",
76 "backend", "stat", "bytes"
77 );
78 if let Some(ref rom) = internal_rom {
79 println!(
80 " {:<9} {:<5} {:>8} {}",
81 "uxntal",
82 "OK",
83 rom.len(),
84 internal_out_path
85 );
86 } else {
87 // Show last 3 non-empty lines of internal error (previously only last 1)
88 let summary = internal_err
89 .as_ref()
90 .map(|e| last_n_lines(e, 3))
91 .unwrap_or_else(|| "-".into());
92 println!(" {:<9} {:<5} {:>8} {}", "uxntal", "FAIL", 0, summary);
93 }
94 for r in [&uxna, &drif] {
95 let summary = if r.ok {
96 r.rom_path.as_deref().unwrap_or("-").to_string()
97 } else {
98 let combined = if !r.stderr.trim().is_empty() {
99 r.stderr.trim().to_string()
100 } else {
101 r.stdout.trim().to_string()
102 };
103 if combined.is_empty() {
104 r.error.as_deref().unwrap_or("-").to_string()
105 } else {
106 last_n_lines(&combined, 3)
107 }
108 };
109 println!(
110 " {:<9} {:<5} {:>8} {}",
111 r.name,
112 if r.ok { "OK" } else { "FAIL" },
113 r.bytes.len(),
114 summary
115 );
116 }
117
118 // 4. Detailed output (stdout/stderr trimmed)
119 for r in [&uxna, &drif] {
120 println!("\n== {} ==", r.name);
121 if r.ok {
122 println!(
123 "{}: OK, {} bytes{}",
124 r.name,
125 r.bytes.len(),
126 r.rom_path
127 .as_ref()
128 .map(|p| format!(", rom={}", p))
129 .unwrap_or_default()
130 );
131 } else {
132 println!("{}: FAIL: {}", r.name, r.error.as_deref().unwrap_or("-"));
133 }
134 if !r.stdout.trim().is_empty() {
135 println!("-- stdout --");
136 if r.name == "uxnasm" {
137 println!("{}", tail_block(&r.stdout, 4000));
138 } else {
139 println!("{}", trim_block(&r.stdout, 4000));
140 }
141 }
142 if !r.stderr.trim().is_empty() {
143 println!("-- stderr --");
144 if r.name == "uxnasm" {
145 println!("{}", tail_block(&r.stderr, 4000));
146 } else {
147 println!("{}", trim_block(&r.stderr, 4000));
148 }
149 }
150 }
151
152 // 5. Diffs (only if internal succeeded and external ok)
153 if let Some(ref int_rom) = internal_rom {
154 println!("\n== Byte Diffs vs uxntal ==");
155 for r in [&uxna, &drif] {
156 if r.ok {
157 print!("uxntal vs {:<9}: ", r.name);
158 if let Some(d) = first_byte_diff(int_rom, &r.bytes) {
159 println!(
160 "first diff at 0x{:04X}: {:02X} != {:02X}",
161 d.index, d.a, d.b
162 );
163 } else {
164 println!("identical");
165 }
166 } else {
167 println!("uxntal vs {:<9}: skipped ({} failed)", r.name, r.name);
168 }
169 }
170
171 // Optional disassembly diff (needs uxndis.rom & uxncli)
172 if have_uxncli() && Path::new("uxndis.rom").exists() {
173 println!("\n== Disassembly Diffs (first differing line) ==");
174 if dis_ok(&internal_out_path) {
175 let uxntal_dis = disassemble(&internal_out_path).unwrap_or_default();
176 // Print the internal ROM path for clarity
177 println!("(disassemble) backend=uxntal rom={}", internal_out_path);
178 for r in [&uxna, &drif] {
179 if r.ok {
180 if let Some(ref rp) = r.rom_path {
181 if dis_ok(rp) {
182 // NOTE: This is where each external backend (including 'drifblim') is disassembled.
183 // The next call to disassemble(rp) produces the B side of the diff.
184 println!("(disassemble) backend={} rom={}", r.name, rp);
185 match disassemble(rp) {
186 Some(other_dis) => {
187 match first_line_diff(&uxntal_dis, &other_dis) {
188 Some((ln, a, b)) => {
189 println!(
190 "uxntal vs {:<9} line {}:\n uxntal: {}\n {:<9}: {}",
191 r.name, ln, a, r.name, b
192 );
193 }
194 None => println!("uxntal vs {:<9} identical", r.name),
195 }
196 }
197 None => {
198 println!("uxntal vs {:<9} disassembly unavailable (empty output)", r.name);
199 }
200 }
201 } else {
202 println!("uxntal vs {:<9} disassembly unavailable", r.name);
203 }
204 }
205 }
206 }
207 } else {
208 println!("(uxntal disassembly unavailable, skipping)");
209 }
210 } else {
211 println!("\n(disassembly skipped: need uxndis.rom + uxncli)");
212 }
213 } else {
214 println!("\nSkipping diffs (internal uxntal failed).");
215 }
216
217 // 6. Explicit note if user expected relative $label support (internal failure hint)
218 if internal_err
219 .as_ref()
220 .map(|e| e.contains("Skip directive requires hex value"))
221 .unwrap_or(false)
222 {
223 println!("\nNOTE: Internal assembler currently rejects $label (relative padding) which uxnasm accepts.");
224 }
225
226 Ok(())
227}Sourcepub fn generate_symbol_file_binary(&self) -> Vec<u8> ⓘ
pub fn generate_symbol_file_binary(&self) -> Vec<u8> ⓘ
Generate symbol file content in binary format Format: [address:u16][name:null-terminated string] repeating
Examples found in repository?
examples/comprehensive_demo.rs (line 73)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5 println!("🔨 UXN TAL Assembler Demo");
6 println!("========================\n");
7
8 // Create some demo TAL files to show our assembler in action
9 create_demo_files()?;
10
11 // Demo 1: Single file assembly with symbols
12 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 // Demo 2: Batch assembly
25 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 // Demo 3: Show assembler flexibility
48 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 // Show binary symbol format too
73 let binary_symbols = assembler.generate_symbol_file_binary();
74 println!("Binary symbol data: {} bytes", binary_symbols.len());
75 // If you want to print lines, try converting to String (if valid UTF-8)
76 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 // Clean up demo files
86 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}Sourcepub fn generate_symbol_file_txt(&self) -> String
pub fn generate_symbol_file_txt(&self) -> String
Generate symbol file content in textual format (address and name per line)
Sourcepub fn new() -> Self
pub fn new() -> Self
Create a new assembler instance
Examples found in repository?
examples/test_blank.rs (line 9)
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 println!("Testing blank.tal specifically...");
5
6 let content = std::fs::read_to_string("../tal/blank.tal")?;
7
8 // Assemble
9 let mut assembler = Assembler::new();
10 let rom = assembler.assemble(&content, Some("test_blank.rs".to_owned()))?;
11
12 println!("Assembly successful! ROM size: {} bytes", rom.len());
13
14 Ok(())
15}More examples
examples/test_include.rs (line 10)
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 println!("Testing include functionality...");
5
6 let content = std::fs::read_to_string("../tal/test_include.tal")?;
7 println!("Source content:\n{}", content);
8
9 // Assemble
10 let mut assembler = Assembler::new();
11 let rom = assembler.assemble(&content, Some("test_include.rs".to_owned()))?;
12
13 println!("Assembly successful! ROM size: {} bytes", rom.len());
14
15 Ok(())
16}examples/batch_assembler.rs (line 21)
19fn assemble_file(file_path: &str) -> Result<usize, AssemblerError> {
20 let source = std::fs::read_to_string(file_path)?;
21 let mut assembler = Assembler::new();
22 // Always use the canonical path for error context
23 let path = std::fs::canonicalize(file_path)
24 .map(|p| p.to_string_lossy().to_string())
25 .unwrap_or_else(|_| file_path.to_string());
26 let rom = assembler.assemble(&source, Some(path))?;
27 Ok(rom.len())
28}
29
30// Assemble a TAL file and write symbol file, returning ROM and symbol file paths and size
31fn assemble_file_with_symbols(
32 path: &Path,
33) -> Result<(std::path::PathBuf, std::path::PathBuf, usize), AssemblerError> {
34 let source = std::fs::read_to_string(path)?;
35 let mut assembler = Assembler::new();
36 let canonical = std::fs::canonicalize(path)
37 .map(|p| p.to_string_lossy().to_string())
38 .unwrap_or_else(|_| path.to_string_lossy().to_string());
39 let rom = assembler.assemble(&source, Some(canonical))?;
40 let rom_path = path.with_extension("rom");
41 let sym_path = path.with_extension("sym");
42 std::fs::write(&rom_path, &rom)?;
43 let sym_txt = assembler.generate_symbol_file();
44 std::fs::write(&sym_path, sym_txt)?;
45 Ok((rom_path, sym_path, rom.len()))
46}
47
48// Assemble a TAL file and write ROM, returning ROM path and size
49fn assemble_file_auto(path: &Path) -> Result<(std::path::PathBuf, usize), AssemblerError> {
50 let source = std::fs::read_to_string(path)?;
51 let mut assembler = Assembler::new();
52 let canonical = std::fs::canonicalize(path)
53 .map(|p| p.to_string_lossy().to_string())
54 .unwrap_or_else(|_| path.to_string_lossy().to_string());
55 let rom = assembler.assemble(&source, Some(canonical))?;
56 let rom_path = path.with_extension("rom");
57 std::fs::write(&rom_path, &rom)?;
58 Ok((rom_path, rom.len()))
59}examples/test_macro_call.rs (line 10)
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 println!("Testing macro call functionality...");
5
6 let content = std::fs::read_to_string("../tal/test_macro_call.tal")?;
7 println!("Source content:\n{}", content);
8
9 // Assemble
10 let mut assembler = Assembler::new();
11 let rom = assembler.assemble(&content, Some("test_macro_call.rs".to_owned()))?;
12
13 println!("Assembly successful! ROM size: {} bytes", rom.len());
14
15 Ok(())
16}examples/test_fixes.rs (line 10)
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 println!("Testing fixes for device access and comments...");
5
6 let content = std::fs::read_to_string("../tal/test_fixes.tal")?;
7 println!("Source content:\n{}", content);
8
9 // Assemble
10 let mut assembler = Assembler::new();
11 let rom = assembler.assemble(&content, Some("test_fixes.rs".to_owned()))?;
12
13 println!("Assembly successful! ROM size: {} bytes", rom.len());
14
15 Ok(())
16}examples/test_hyphen.rs (line 10)
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 println!("Testing hyphen identifiers and raw address refs...");
5
6 let content = std::fs::read_to_string("../tal/test_hyphen.tal")?;
7 println!("Source content:\n{}", content);
8
9 // Assemble
10 let mut assembler = Assembler::new();
11 let rom = assembler.assemble(&content, Some("test_hyphen.rs".to_owned()))?;
12
13 println!("Assembly successful! ROM size: {} bytes", rom.len());
14
15 Ok(())
16}Additional examples can be found in:
- examples/test_relative_sublabel.rs
- examples/test_hex_values.rs
- examples/debug_cond.rs
- examples/minimal_test.rs
- examples/counter.rs
- examples/label_debug.rs
- examples/minimal.rs
- examples/hello_world.rs
- examples/batch_test.rs
- examples/device_test.rs
- examples/debug_devices.rs
- examples/console_debug.rs
- examples/debug_test.rs
- examples/comprehensive_demo.rs
- examples/working_hello.rs
- examples/debug_assemble.rs
- examples/working_roms.rs
pub fn with_drif_mode(drif_mode: bool) -> Self
pub fn with_verbose(verbose: u8) -> Self
pub fn with_drif_mode_verbose(drif_mode: bool, verbose: u8) -> Self
Sourcepub fn assemble(
&mut self,
source: &str,
path: Option<String>,
) -> Result<Vec<u8>>
pub fn assemble( &mut self, source: &str, path: Option<String>, ) -> Result<Vec<u8>>
Assemble TAL source code into a ROM
Examples found in repository?
examples/test_blank.rs (line 10)
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 println!("Testing blank.tal specifically...");
5
6 let content = std::fs::read_to_string("../tal/blank.tal")?;
7
8 // Assemble
9 let mut assembler = Assembler::new();
10 let rom = assembler.assemble(&content, Some("test_blank.rs".to_owned()))?;
11
12 println!("Assembly successful! ROM size: {} bytes", rom.len());
13
14 Ok(())
15}More examples
examples/test_include.rs (line 11)
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 println!("Testing include functionality...");
5
6 let content = std::fs::read_to_string("../tal/test_include.tal")?;
7 println!("Source content:\n{}", content);
8
9 // Assemble
10 let mut assembler = Assembler::new();
11 let rom = assembler.assemble(&content, Some("test_include.rs".to_owned()))?;
12
13 println!("Assembly successful! ROM size: {} bytes", rom.len());
14
15 Ok(())
16}examples/batch_assembler.rs (line 26)
19fn assemble_file(file_path: &str) -> Result<usize, AssemblerError> {
20 let source = std::fs::read_to_string(file_path)?;
21 let mut assembler = Assembler::new();
22 // Always use the canonical path for error context
23 let path = std::fs::canonicalize(file_path)
24 .map(|p| p.to_string_lossy().to_string())
25 .unwrap_or_else(|_| file_path.to_string());
26 let rom = assembler.assemble(&source, Some(path))?;
27 Ok(rom.len())
28}
29
30// Assemble a TAL file and write symbol file, returning ROM and symbol file paths and size
31fn assemble_file_with_symbols(
32 path: &Path,
33) -> Result<(std::path::PathBuf, std::path::PathBuf, usize), AssemblerError> {
34 let source = std::fs::read_to_string(path)?;
35 let mut assembler = Assembler::new();
36 let canonical = std::fs::canonicalize(path)
37 .map(|p| p.to_string_lossy().to_string())
38 .unwrap_or_else(|_| path.to_string_lossy().to_string());
39 let rom = assembler.assemble(&source, Some(canonical))?;
40 let rom_path = path.with_extension("rom");
41 let sym_path = path.with_extension("sym");
42 std::fs::write(&rom_path, &rom)?;
43 let sym_txt = assembler.generate_symbol_file();
44 std::fs::write(&sym_path, sym_txt)?;
45 Ok((rom_path, sym_path, rom.len()))
46}
47
48// Assemble a TAL file and write ROM, returning ROM path and size
49fn assemble_file_auto(path: &Path) -> Result<(std::path::PathBuf, usize), AssemblerError> {
50 let source = std::fs::read_to_string(path)?;
51 let mut assembler = Assembler::new();
52 let canonical = std::fs::canonicalize(path)
53 .map(|p| p.to_string_lossy().to_string())
54 .unwrap_or_else(|_| path.to_string_lossy().to_string());
55 let rom = assembler.assemble(&source, Some(canonical))?;
56 let rom_path = path.with_extension("rom");
57 std::fs::write(&rom_path, &rom)?;
58 Ok((rom_path, rom.len()))
59}examples/test_macro_call.rs (line 11)
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 println!("Testing macro call functionality...");
5
6 let content = std::fs::read_to_string("../tal/test_macro_call.tal")?;
7 println!("Source content:\n{}", content);
8
9 // Assemble
10 let mut assembler = Assembler::new();
11 let rom = assembler.assemble(&content, Some("test_macro_call.rs".to_owned()))?;
12
13 println!("Assembly successful! ROM size: {} bytes", rom.len());
14
15 Ok(())
16}examples/test_fixes.rs (line 11)
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 println!("Testing fixes for device access and comments...");
5
6 let content = std::fs::read_to_string("../tal/test_fixes.tal")?;
7 println!("Source content:\n{}", content);
8
9 // Assemble
10 let mut assembler = Assembler::new();
11 let rom = assembler.assemble(&content, Some("test_fixes.rs".to_owned()))?;
12
13 println!("Assembly successful! ROM size: {} bytes", rom.len());
14
15 Ok(())
16}examples/test_hyphen.rs (line 11)
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 println!("Testing hyphen identifiers and raw address refs...");
5
6 let content = std::fs::read_to_string("../tal/test_hyphen.tal")?;
7 println!("Source content:\n{}", content);
8
9 // Assemble
10 let mut assembler = Assembler::new();
11 let rom = assembler.assemble(&content, Some("test_hyphen.rs".to_owned()))?;
12
13 println!("Assembly successful! ROM size: {} bytes", rom.len());
14
15 Ok(())
16}Additional examples can be found in:
- examples/test_relative_sublabel.rs
- examples/test_hex_values.rs
- examples/debug_cond.rs
- examples/minimal_test.rs
- examples/counter.rs
- examples/label_debug.rs
- examples/minimal.rs
- examples/hello_world.rs
- examples/batch_test.rs
- examples/device_test.rs
- examples/debug_devices.rs
- examples/console_debug.rs
- examples/debug_test.rs
- examples/comprehensive_demo.rs
- examples/working_hello.rs
- examples/debug_assemble.rs
- examples/working_roms.rs
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Assembler
impl RefUnwindSafe for Assembler
impl Send for Assembler
impl Sync for Assembler
impl Unpin for Assembler
impl UnsafeUnpin for Assembler
impl UnwindSafe for Assembler
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more