diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs index 93bc563..8ab19d8 100644 --- a/src/interpreter/mod.rs +++ b/src/interpreter/mod.rs @@ -8,6 +8,9 @@ use crate::{ repr::mlog::*, }; +#[cfg(test)] +mod test; + /// Represents the instruction pointer #[derive(Clone, Copy, PartialEq, PartialOrd, Ord, Eq, Debug)] pub struct Counter(pub usize); @@ -88,6 +91,7 @@ pub struct ProgramState { pub rng: RefCell, pub ended: bool, + // TODO: add errors array } #[non_exhaustive] @@ -145,6 +149,7 @@ pub fn run(program: &MindustryProgram, stop_condition: StopCondition) -> HashMap let mut steps = 0; while !stop_condition.should_stop(steps, &state) { + println!("{:?}", state); let _ = step(&compiled, &mut state); steps = steps.saturating_add(1); } @@ -248,6 +253,8 @@ pub fn step( _ => unimplemented!(), } + state.counter.inc(); + Ok(()) } diff --git a/src/interpreter/test.rs b/src/interpreter/test.rs new file mode 100644 index 0000000..ef8abe7 --- /dev/null +++ b/src/interpreter/test.rs @@ -0,0 +1,126 @@ +use super::*; + +#[test] +fn test_interpret_operation() { + fn run_test( + instructions: impl IntoIterator, + ) -> HashMap { + let program = MindustryProgram::from(instructions.into_iter().collect::>()); + + let end_state = run(&program, StopCondition::End); + + end_state + } + + assert_eq!( + run_test([MindustryOperation::Operator( + String::from("x"), + Operator::Add, + Operand::Integer(1), + Operand::Float(2.0) + )]) + .get("x"), + Some(&Value::Number(3.0)) + ); + + assert_eq!( + run_test([ + MindustryOperation::Set(String::from("a"), Operand::Integer(2)), + MindustryOperation::Operator( + String::from("x"), + Operator::Add, + Operand::Variable(String::from("a")), + Operand::Integer(1) + ) + ]) + .get("x"), + Some(&Value::Number(3.0)) + ); + + assert_eq!( + run_test([ + MindustryOperation::Set(String::from("a"), Operand::Float(-1.5)), + MindustryOperation::Set(String::from("b"), Operand::Float(0.25)), + MindustryOperation::Operator( + String::from("x"), + Operator::Add, + Operand::Variable(String::from("a")), + Operand::Variable(String::from("b")) + ) + ]) + .get("x"), + Some(&Value::Number(-1.25)) + ); + + assert_eq!( + run_test([MindustryOperation::Operator( + String::from("x"), + Operator::Add, + Operand::Integer(7), + Operand::String(String::from("2")) + )]) + .get("x"), + Some(&Value::Number(8.0)), + "7 + \"2\" should equal 8" + ); + + assert_eq!( + run_test([MindustryOperation::Operator( + String::from("x"), + Operator::Add, + Operand::Integer(7), + Operand::String(String::from("")) + )]) + .get("x"), + Some(&Value::Number(8.0)), + "7 + \"\" should equal 8" + ); + + assert_eq!( + run_test([MindustryOperation::Operator( + String::from("x"), + Operator::Sub, + Operand::Integer(7), + Operand::Integer(3) + )]) + .get("x"), + Some(&Value::Number(4.0)), + "7 - 3 should equal 4" + ); + + assert_eq!( + run_test([MindustryOperation::Operator( + String::from("x"), + Operator::Eq, + Operand::Integer(7), + Operand::Integer(3) + )]) + .get("x"), + Some(&Value::Number(0.0)), + "7 == 3 should equal 0" + ); + + assert_eq!( + run_test([MindustryOperation::Operator( + String::from("x"), + Operator::Eq, + Operand::Integer(7), + Operand::Integer(7) + )]) + .get("x"), + Some(&Value::Number(1.0)), + "7 == 7 should equal 1" + ); + + assert_eq!( + run_test([MindustryOperation::Operator( + String::from("x"), + Operator::Neq, + Operand::Integer(7), + Operand::Integer(3) + )]) + .get("x"), + Some(&Value::Number(1.0)), + "7 != 3 should equal 1" + ); +}