Skip to main content

i8051_disassembler/
labels.rs

1use std::{
2    collections::{BTreeMap, HashMap},
3    ops,
4};
5
6use crate::address::{AddressSpace, AddressValue, PhysicalAddr};
7
8#[derive(Default)]
9pub(crate) struct ImplicitLabels {
10    labels: BTreeMap<AddressSpace, Labels>,
11}
12
13impl ops::Deref for ImplicitLabels {
14    type Target = BTreeMap<AddressSpace, Labels>;
15
16    fn deref(&self) -> &Self::Target {
17        &self.labels
18    }
19}
20
21#[derive(Default)]
22pub(crate) struct Labels {
23    labels: BTreeMap<AddressValue, String>,
24}
25
26impl ops::Deref for Labels {
27    type Target = BTreeMap<AddressValue, String>;
28
29    fn deref(&self) -> &Self::Target {
30        &self.labels
31    }
32}
33
34#[derive(Default)]
35pub(crate) struct LabelCollector {
36    labels: HashMap<PhysicalAddr, Option<String>>,
37}
38
39impl LabelCollector {
40    pub fn collect(&mut self, space: AddressSpace, addr: AddressValue, label: Option<String>) {
41        self.labels.insert(
42            PhysicalAddr {
43                space,
44                offset: addr,
45            },
46            label,
47        );
48    }
49
50    pub fn into_implicit_labels(self) -> ImplicitLabels {
51        let mut implicit_labels = BTreeMap::new();
52        for (addr, ref_name) in self.labels {
53            if let Some(ref_name) = ref_name {
54                implicit_labels
55                    .entry(addr.space)
56                    .or_insert_with(Labels::default)
57                    .labels
58                    .insert(addr.offset, ref_name);
59            } else {
60                implicit_labels
61                    .entry(addr.space)
62                    .or_insert_with(Labels::default)
63                    .labels
64                    .insert(addr.offset, format!("loc_{addr:04X}", addr = addr.offset));
65            }
66        }
67        ImplicitLabels {
68            labels: implicit_labels,
69        }
70    }
71}