Krolyxon
Commit 88f3865

Branches

Tags

Refs →

bench51cratesbench51-coresrcasmlisting.rs

53 lines · 1.8 KB · Rust

1use std::fmt::Write;
2
3use super::AsmOutput;
4
5const BYTES_PER_ROW: usize = 4;
6
7/// Keil A51-style listing: location, object bytes, line number, source,
8/// with errors inline and a symbol table at the end.
9pub fn render(out: &AsmOutput, source: &str) -> String {
10 let mut s = String::new();
11 let _ = writeln!(s, "LOC OBJ LINE SOURCE");
12 let _ = writeln!(s);
13 let mut diags = out.diagnostics.iter().peekable();
14 for (i, text) in source.lines().enumerate() {
15 let line = out.lines.get(i).cloned().unwrap_or_default();
16 let loc = line.addr.map_or(" ".to_string(), |a| format!("{a:04X}"));
17 let mut chunks = line.bytes.chunks(BYTES_PER_ROW);
18 let obj = chunks.next().map(hex_bytes).unwrap_or_default();
19 let _ = writeln!(s, "{loc} {obj:<12} {:>5} {}", i + 1, text.trim_end());
20 let mut addr = line.addr.unwrap_or(0) as usize;
21 for c in chunks {
22 addr += BYTES_PER_ROW;
23 let _ = writeln!(s, "{:04X} {}", addr & 0xFFFF, hex_bytes(c));
24 }
25 while let Some(d) = diags.next_if(|d| d.line == i) {
26 let _ = writeln!(s, "*** ERROR at column {}: {}", d.col + 1, d.msg);
27 }
28 }
29
30 let _ = writeln!(s);
31 let _ = writeln!(s, "SYMBOL TABLE");
32 let _ = writeln!(s, "NAME TYPE VALUE");
33 for (name, sym) in &out.symbols {
34 let _ = writeln!(
35 s,
36 "{name:<19} {:<7} {:04X}h",
37 sym.kind.name(),
38 sym.value & 0xFFFF
39 );
40 }
41 let _ = writeln!(s);
42 let _ = writeln!(
43 s,
44 "ASSEMBLY COMPLETE: {} ERROR(S), {} BYTE(S) OF CODE",
45 out.diagnostics.len(),
46 out.code_size()
47 );
48 s
49}
50
51fn hex_bytes(b: &[u8]) -> String {
52 b.iter().map(|x| format!("{x:02X}")).collect()
53}