diff options
Diffstat (limited to 'src/forth/vm.rs')
| -rw-r--r-- | src/forth/vm.rs | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/src/forth/vm.rs b/src/forth/vm.rs index e7c3794..564a647 100644 --- a/src/forth/vm.rs +++ b/src/forth/vm.rs @@ -4,6 +4,10 @@ use std::ops::Index; pub type DataStackType = isize; +const MIN_SPEED: DataStackType = 0; +const MAX_SPEED: DataStackType = 10; +const UNITS_PER_ROTATION: DataStackType = 360; + #[derive(Clone, Debug, Eq, PartialEq)] pub enum OpCode { Num(DataStackType), @@ -41,8 +45,8 @@ pub enum OpCode { Say, Heading, SetHeading, - Velocity, - SetVelocity, + Speed, + SetSpeed, Doppler, } @@ -124,7 +128,7 @@ pub struct VM { pub out: Vec<String>, pub heading: DataStackType, - pub velocity: DataStackType, + pub speed: DataStackType, pub doppler: DataStackType, } @@ -151,7 +155,7 @@ impl VM { out: vec![], heading: 0, - velocity: 0, + speed: 0, doppler: 0, } } @@ -315,13 +319,21 @@ impl VM { self.stack.0.push(self.heading); } OpCode::SetHeading => { - self.heading = self.stack.0.pop().ok_or(RuntimeError::StackUnderflow)?; + let v = self.stack.0.pop().ok_or(RuntimeError::StackUnderflow)?; + self.heading = (UNITS_PER_ROTATION + (v % UNITS_PER_ROTATION)) % UNITS_PER_ROTATION; } - OpCode::Velocity => { - self.stack.0.push(self.velocity); + OpCode::Speed => { + self.stack.0.push(self.speed); } - OpCode::SetVelocity => { - self.velocity = self.stack.0.pop().ok_or(RuntimeError::StackUnderflow)?; + OpCode::SetSpeed => { + let v = self.stack.0.pop().ok_or(RuntimeError::StackUnderflow)?; + self.speed = if v < MIN_SPEED { + MIN_SPEED + } else if v > MAX_SPEED { + MAX_SPEED + } else { + v + }; } OpCode::Doppler => { self.stack.0.push(self.doppler); @@ -845,26 +857,26 @@ mod tests { } #[test] - fn opcode_velocity() { + fn opcode_speed() { let wordlist = wl_for(vec![vec![ - OpCode::Velocity + OpCode::Speed ]]); let mut vm = VM::new(wordlist); - vm.velocity = 12; + vm.speed = 12; vm.run().expect("should run to completion"); assert_eq!(vm.stack.0.len(), 1, "stack size"); - assert_eq!(vm.stack.0[0], 12, "velocity value"); + assert_eq!(vm.stack.0[0], 12, "speed value"); } #[test] - fn opcode_setvelocity() { + fn opcode_setspeed() { let wordlist = wl_for(vec![vec![ - OpCode::Num(3), OpCode::SetVelocity + OpCode::Num(3), OpCode::SetSpeed ]]); let mut vm = VM::new(wordlist); vm.run().expect("should run to completion"); assert_eq!(vm.stack.0.len(), 0, "empty stack"); - assert_eq!(vm.velocity, 3, "velocity value"); + assert_eq!(vm.speed, 3, "speed value"); } #[test] |
