#[derive(Clone)] pub struct Chip8Stack { items: Vec } impl Default for Chip8Stack { fn default() -> Self { Chip8Stack { items: vec![], } } } impl Chip8Stack { pub fn push(&mut self, new_value: &u16) { if self.depth() == 16 { // println!("Deep deep stack?"); panic!("Stack Overflow"); } self.items.push(*new_value ); } pub fn pop(&mut self) -> u16 { if self.items.is_empty() { panic!("Stack Underflow"); } self.items.pop().unwrap() } pub fn depth(&self) -> u16 { self.items.len() as u16 } pub fn new() -> Self { Chip8Stack { items: vec![] } } } #[cfg(test)] mod test { use rand::random; use super::*; #[test] fn smoke() { assert!(true) } #[test] fn push_pop_test() { let mut x = Chip8Stack::new(); // lets see if we can push and pop a bunch x.push(&0xabcu16); x.push(&0xcdeu16); x.pop(); assert_eq!(x.depth(), 1); } #[test] #[should_panic] fn stack_overflow_test() { let mut x = Chip8Stack::new(); for i in 0..17 { x.push(&i); } } #[test] #[should_panic] fn stack_underflow_test() { let mut x = Chip8Stack::new(); x.pop(); } #[test] fn lots_of_subs() { let mut x = Chip8Stack::new(); let stack_contents = [0x123, 0x321, 0xabc, 0xdef, 0xbad, 0xbef, 0xfed, 0xcab, 0xbed, 0xcad, 0xfeb, 0xcab, 0xfff, 0x000, 0x001]; for i in stack_contents { x.push(&i); } assert_eq!(x.depth(), 15); // up to 50 random loops let num_loops: u8 = random::() % 50; for i in 0..num_loops { let start_count = x.depth(); let num_pop = random::() % x.depth() as u8; for current_pop in 0..num_pop { x.pop(); } let post_pop_count = x.depth(); assert_eq!(post_pop_count as u8, start_count as u8 - num_pop); for current_push in 0..num_pop { x.push(&stack_contents[(current_push + post_pop_count as u8) as usize]); } assert_eq!(x.depth(), 15); } } }