use super::Stack; use crate::{Byte, Short, Trap}; pub trait Push { fn push(self, stack: &mut Stack) -> Result<(), Trap>; } impl Push for () { fn push(self, _stack: &mut Stack) -> Result<(), Trap> { Ok(()) } } impl Push for Byte { fn push(self, stack: &mut Stack) -> Result<(), Trap> { if stack.ptr >= 255 { return Err(Trap::StackOverflow); } { stack.data[stack.ptr as usize] = u8::from(self); stack.ptr += 1; } Ok(()) } } impl Push for bool { fn push(self, stack: &mut Stack) -> Result<(), Trap> { Byte::from(self).push(stack) } } impl Push for Short { fn push(self, stack: &mut Stack) -> Result<(), Trap> { if stack.ptr >= 254 { return Err(Trap::StackOverflow); } { let [msb, lsb] = u16::from(self).to_be_bytes(); stack.data[stack.ptr as usize] = msb; stack.data[(stack.ptr + 1) as usize] = lsb; stack.ptr += 2; } Ok(()) } } impl Push for (Byte, Byte) { fn push(self, stack: &mut Stack) -> Result<(), Trap> { if stack.ptr >= 254 { return Err(Trap::StackOverflow); } { stack.data[stack.ptr as usize] = u8::from(self.0); stack.ptr += 1; } { stack.data[stack.ptr as usize] = u8::from(self.1); stack.ptr += 1; } Ok(()) } } impl Push for (bool, Byte) { fn push(self, stack: &mut Stack) -> Result<(), Trap> { (Byte::from(self.0), self.1).push(stack) } } impl Push for (Byte, Byte, Byte) { fn push(self, stack: &mut Stack) -> Result<(), Trap> { if stack.ptr >= 253 { return Err(Trap::StackOverflow); } { stack.data[stack.ptr as usize] = u8::from(self.0); stack.ptr += 1; } { stack.data[stack.ptr as usize] = u8::from(self.1); stack.ptr += 1; } { stack.data[stack.ptr as usize] = u8::from(self.2); stack.ptr += 1; } Ok(()) } } impl Push for (Byte, Short) { fn push(self, stack: &mut Stack) -> Result<(), Trap> { if stack.ptr >= 253 { return Err(Trap::StackOverflow); } { stack.data[stack.ptr as usize] = u8::from(self.0); stack.ptr += 1; } { let [msb, lsb] = u16::from(self.1).to_be_bytes(); stack.data[stack.ptr as usize] = msb; stack.data[(stack.ptr + 1) as usize] = lsb; stack.ptr += 2; } Ok(()) } } impl Push for (bool, Short) { fn push(self, stack: &mut Stack) -> Result<(), Trap> { (Byte::from(self.0), self.1).push(stack) } } impl Push for (Short, Byte) { fn push(self, stack: &mut Stack) -> Result<(), Trap> { if stack.ptr >= 253 { return Err(Trap::StackOverflow); } { let [msb, lsb] = u16::from(self.0).to_be_bytes(); stack.data[stack.ptr as usize] = msb; stack.data[(stack.ptr + 1) as usize] = lsb; stack.ptr += 2; } { stack.data[stack.ptr as usize] = u8::from(self.1); stack.ptr += 1; } Ok(()) } } impl Push for (Short, Short) { fn push(self, stack: &mut Stack) -> Result<(), Trap> { if stack.ptr >= 252 { return Err(Trap::StackOverflow); } { let [msb, lsb] = u16::from(self.0).to_be_bytes(); stack.data[stack.ptr as usize] = msb; stack.data[(stack.ptr + 1) as usize] = lsb; stack.ptr += 2; } { let [msb, lsb] = u16::from(self.1).to_be_bytes(); stack.data[stack.ptr as usize] = msb; stack.data[(stack.ptr + 1) as usize] = lsb; stack.ptr += 2; } Ok(()) } } impl Push for (Short, Short, Short) { fn push(self, stack: &mut Stack) -> Result<(), Trap> { if stack.ptr >= 250 { return Err(Trap::StackOverflow); } { let [msb, lsb] = u16::from(self.0).to_be_bytes(); stack.data[stack.ptr as usize] = msb; stack.data[(stack.ptr + 1) as usize] = lsb; stack.ptr += 2; } { let [msb, lsb] = u16::from(self.1).to_be_bytes(); stack.data[stack.ptr as usize] = msb; stack.data[(stack.ptr + 1) as usize] = lsb; stack.ptr += 2; } { let [msb, lsb] = u16::from(self.2).to_be_bytes(); stack.data[stack.ptr as usize] = msb; stack.data[(stack.ptr + 1) as usize] = lsb; stack.ptr += 2; } Ok(()) } }