a2kit/lang/merlin/hovers/
hovers_statements.rs

1use crate::lang::merlin::handbook::{operations::OperationHandbook, pseudo_ops::PseudoOperationHandbook};
2use crate::lang::merlin::ProcessorType;
3
4pub struct StatementHovers {
5	op_book: OperationHandbook,
6	psop_book: PseudoOperationHandbook
7}
8
9impl StatementHovers {
10    pub fn new() -> Self {
11        let op_book = OperationHandbook::new();
12        let psop_book = PseudoOperationHandbook::new();
13        Self {
14            op_book,
15            psop_book
16        }
17    }
18    pub fn get_op(&self,node_kind: &str) -> Option<String> {
19        if node_kind.starts_with("op_") && node_kind.len() > 3 {
20            if let Some(op) = self.op_book.get(&node_kind[3..]) {
21                let mut ans = format!("`{}`\n",node_kind[3..].to_uppercase());
22                ans += "\n\n---\n\n";
23                ans += &op.desc;
24                ans += "\n\n---\n\n";
25                let mut table = "addr|cyc|op|xc\n---|---:|---|---\n".to_string();
26                for mode in op.modes {
27                    table += &format!("{:8}",mode.mnemonic);
28                    table += "|";
29                    table += &format!("{}",mode.cycles);
30                    table += "|";
31                    table += &format!("${:02X}",mode.code);
32                    table += "|";
33                    let mut xc = String::new();
34                    if !mode.processors.contains(&ProcessorType::_6502) {
35                        xc += "*";
36                    }
37                    if !mode.processors.contains(&ProcessorType::_65c02) {
38                        xc += "*";
39                    }
40                    table += &xc;
41                    table += "\n";
42                }
43                ans += &table;
44                ans += "\n\n---\n\n";
45                ans += "status register";
46                let mut status = "N|V|M|X|D|I|Z|C\n---|---|---|---|---|---|---|---\n".to_string();
47                for i in 0..8 {
48                    status += &op.status[i..i+1];
49                    status += "|";
50                }
51                ans += "\n\n---\n\n";
52                ans += &status;
53                return Some(ans);
54            }
55        }
56        None
57    }
58    pub fn get_psop(&self,node_kind: &str) -> Option<String> {
59        if node_kind.starts_with("psop_") && node_kind.len() > 5 {
60            // handle end_lup specially
61            let key = match node_kind {
62                "psop_end_lup" => "--^",
63                _ => &node_kind[5..]
64            };
65            if let Some(psop) = self.psop_book.get(key) {
66                let mut ans = format!("`{}`",key.to_uppercase());
67                for alt in psop.alt {
68                    ans += &format!(" or `{}`",alt.to_uppercase());
69                }
70                ans += "\n\n---\n\n";
71                ans += &psop.desc;
72                if psop.eg.len() > 0 {
73                    ans += "\n\n---\n\n";
74                    ans += "#### examples\n\n    ";
75                    for eg in psop.eg {
76                        ans += "\n";
77                        ans += &format!("    {}",eg);
78                    }
79                }
80                if let Some(cav) = psop.caveat {
81                    ans += "\n\n---\n\n";
82                    ans += &format!("n.b. {}",cav);
83                }
84                ans += "\n\n---\n\n";
85                ans += "Merlin versions: ";
86                for vit in psop.version {
87                    ans += &format!("{}, ",vit);
88                }
89                if ans.ends_with(", ") {
90                    ans.pop();
91                    ans.pop();
92                }
93                return Some(ans)
94            }
95        }
96        None
97    }
98}