summaryrefslogtreecommitdiffstats
path: root/src/forth/vm.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/forth/vm.rs')
-rw-r--r--src/forth/vm.rs44
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]