stack_vm/
instruction_table.rs1use crate::instruction::Instruction;
7use std::collections::HashMap;
8use std::fmt;
9
10#[derive(Debug, Default)]
14pub struct InstructionTable<T: fmt::Debug>(HashMap<usize, Instruction<T>>);
15
16impl<T: fmt::Debug> InstructionTable<T> {
17 pub fn new() -> InstructionTable<T> {
19 InstructionTable(HashMap::new())
20 }
21
22 pub fn by_op_code(&self, op_code: usize) -> Option<&Instruction<T>> {
24 self.0.get(&op_code)
25 }
26
27 pub fn by_name(&self, name: &str) -> Option<&Instruction<T>> {
29 self.0.values().find(|ref instr| instr.name == name)
30 }
31
32 pub fn insert(&mut self, instr: Instruction<T>) {
34 self.0.insert(instr.op_code, instr);
35 }
36
37 pub fn is_empty(&self) -> bool {
39 self.0.is_empty()
40 }
41
42 pub fn symbols(&self) -> Vec<(usize, String)> {
47 let mut result = vec![];
48 self.0.keys().for_each(|ref key| {
49 let instr = &self.0[key];
50 result.push((instr.op_code, instr.name.clone()));
51 });
52 result.sort_by(|lhs, rhs| lhs.0.cmp(&rhs.0));
53 result
54 }
55}
56
57#[cfg(test)]
58mod test {
59 use super::*;
60 use crate::machine::Machine;
61
62 fn noop(_machine: &mut Machine<usize>, _args: &[usize]) {}
63
64 #[test]
65 fn new() {
66 let table: InstructionTable<usize> = InstructionTable::new();
67 assert!(table.is_empty())
68 }
69
70 #[test]
71 fn insert() {
72 let mut table: InstructionTable<usize> = InstructionTable::new();
73 assert!(table.is_empty());
74 table.insert(Instruction::new(0, "NOOP", 0, noop));
75 assert!(!table.is_empty());
76 }
77
78 #[test]
79 fn by_op_code() {
80 let mut table: InstructionTable<usize> = InstructionTable::new();
81 table.insert(Instruction::new(0, "NOOP", 0, noop));
82 let instr = table.by_op_code(0).unwrap();
83 assert_eq!(instr.name, "NOOP");
84 }
85
86 #[test]
87 fn by_name() {
88 let mut table: InstructionTable<usize> = InstructionTable::new();
89 table.insert(Instruction::new(0, "NOOP", 0, noop));
90 let instr = table.by_name("NOOP").unwrap();
91 assert_eq!(instr.op_code, 0);
92 }
93}