Krolyxon
Tag v0.3.0

Branches

Tags

Refs →

bench51cratesbench51-guisrcpanessymbols.rs

90 lines · 3.6 KB · Rust

1//! Symbol table of the build, with live values for memory symbols.
2
3use bench51_core::asm::SymKind;
4use eframe::egui::{self, CursorIcon, Sense, Ui};
5
6use crate::state::{Action, State};
7use crate::theme::{WARNING, palette};
8use crate::widgets;
9
10pub fn show(ui: &mut Ui, st: &mut State) {
11 let p = palette(ui.ctx());
12 let Some(doc) = st.docs.get(st.active) else {
13 widgets::empty_state(ui, "No program", "Open or create a source file.");
14 return;
15 };
16 let doc_id = doc.id;
17 let s = &doc.session;
18 let Some(build) = &s.build else {
19 widgets::empty_state(ui, "Not built", "Press F7 to assemble.");
20 return;
21 };
22 let mut goto = None;
23 if build.out.symbols.is_empty() {
24 widgets::empty_state(ui, "No symbols", "Labels and EQU names appear here.");
25 return;
26 }
27 egui::ScrollArea::vertical()
28 .auto_shrink([false; 2])
29 .show(ui, |ui| {
30 egui::Grid::new("symbols")
31 .num_columns(4)
32 .spacing([20.0, 6.0])
33 .show(ui, |ui| {
34 for h in ["Name", "Kind", "Value", "Now"] {
35 ui.label(p.label(h).color(p.text_disabled));
36 }
37 ui.end_row();
38 for (name, sym) in &build.out.symbols {
39 let v = sym.value;
40 let name_label = egui::Label::new(p.data(name).color(p.text_display))
41 .sense(Sense::click());
42 let resp = ui
43 .add(name_label)
44 .on_hover_cursor(CursorIcon::PointingHand)
45 .on_hover_text("Go to definition");
46 if resp.clicked() {
47 goto = Some(sym.line);
48 }
49 ui.label(p.label(sym.kind.name()));
50 let width = if (0..=0xFF).contains(&v) { 2 } else { 4 };
51 ui.label(
52 p.data(format!("{:0width$X}", v & 0xFFFF))
53 .color(p.text_secondary),
54 );
55 let now = match sym.kind {
56 SymKind::Data | SymKind::Idata if (0..=0xFF).contains(&v) => {
57 let a = v as usize;
58 Some((
59 format!("{:02X}", s.sim.iram[a]),
60 s.sim.iram[a] != s.prev_iram[a],
61 ))
62 }
63 SymKind::Xdata if (0..=0xFFFF).contains(&v) => {
64 Some((format!("{:02X}", s.sim.xram[v as usize]), false))
65 }
66 SymKind::Bit if (0..=0xFF).contains(&v) => {
67 Some((u8::from(s.sim.read_bit(v as u8, true)).to_string(), false))
68 }
69 _ => None,
70 };
71 match now {
72 Some((t, changed)) => ui.label(p.data(t).color(if changed {
73 WARNING
74 } else {
75 p.text_primary
76 })),
77 None => ui.label(p.data("—").color(p.text_disabled)),
78 };
79 ui.end_row();
80 }
81 });
82 });
83 if let Some(line) = goto {
84 st.actions.push(Action::Goto {
85 doc: doc_id,
86 line,
87 col: 0,
88 });
89 }
90}