summaryrefslogtreecommitdiffstats
path: root/src/forth
diff options
context:
space:
mode:
authorBrian Cully <bjc@spork.org>2025-12-16 17:54:47 -0500
committerBrian Cully <bjc@spork.org>2025-12-16 17:54:47 -0500
commit45a2cfca666e5698462090399ff2db13be57a38c (patch)
treedf0a8d7371d68d88a48ebb2f755f9fbaadb5aa33 /src/forth
parent362569ade6de7cb4caf8ddd5e260ff397266c530 (diff)
downloadautomathon-45a2cfca666e5698462090399ff2db13be57a38c.tar.gz
automathon-45a2cfca666e5698462090399ff2db13be57a38c.zip
rename velocity to speed
mass is a scalar quantity
Diffstat (limited to 'src/forth')
-rw-r--r--src/forth/compiler.rs16
-rw-r--r--src/forth/vm.rs44
2 files changed, 36 insertions, 24 deletions
diff --git a/src/forth/compiler.rs b/src/forth/compiler.rs
index c9652d9..a8162f5 100644
--- a/src/forth/compiler.rs
+++ b/src/forth/compiler.rs
@@ -237,8 +237,8 @@ impl<'a> Compiler<'a> {
"say" => self.bc_push(OpCode::Say, anno),
"head" => self.bc_push(OpCode::Heading, anno),
"sethead" => self.bc_push(OpCode::SetHeading, anno),
- "vel" => self.bc_push(OpCode::Velocity, anno),
- "setvel" => self.bc_push(OpCode::SetVelocity, anno),
+ "speed" => self.bc_push(OpCode::Speed, anno),
+ "setspeed" => self.bc_push(OpCode::SetSpeed, anno),
"doppler" => self.bc_push(OpCode::Doppler, anno),
other => return Err(CompileError::UnknownWord(String::from(other))),
}
@@ -357,17 +357,17 @@ mod tests {
}
#[test]
- fn velocity_opcode() {
- let comp = compiler_for("vel\n");
+ fn speed_opcode() {
+ let comp = compiler_for("speed\n");
let main = &comp.wordlist.0[0];
- assert_eq!(main, vec![OpCode::Velocity]);
+ assert_eq!(main, vec![OpCode::Speed]);
}
#[test]
- fn setvelocity_opcode() {
- let comp = compiler_for("setvel\n");
+ fn setspeed_opcode() {
+ let comp = compiler_for("setspeed\n");
let main = &comp.wordlist.0[0];
- assert_eq!(main, vec![OpCode::SetVelocity]);
+ assert_eq!(main, vec![OpCode::SetSpeed]);
}
#[test]
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]