use super::super::*;
fn push(machine: &mut Machine<f64>, args: &[usize]) {
let arg = *machine.get_data(args[0]);
machine.operand_push(arg);
}
fn add(machine: &mut Machine<f64>, _args: &[usize]) {
let rhs = machine.operand_pop();
let lhs = machine.operand_pop();
machine.operand_push(lhs + rhs);
}
fn sub(machine: &mut Machine<f64>, _args: &[usize]) {
let rhs = machine.operand_pop();
let lhs = machine.operand_pop();
machine.operand_push(lhs - rhs);
}
fn div(machine: &mut Machine<f64>, _args: &[usize]) {
let rhs = machine.operand_pop();
let lhs = machine.operand_pop();
machine.operand_push(lhs / rhs);
}
fn mult(machine: &mut Machine<f64>, _args: &[usize]) {
let rhs = machine.operand_pop();
let lhs = machine.operand_pop();
machine.operand_push(lhs * rhs);
}
fn instruction_table() -> InstructionTable<f64> {
let mut it = InstructionTable::new();
it.insert(Instruction::new(0, "push", 1, push));
it.insert(Instruction::new(1, "add", 0, add));
it.insert(Instruction::new(2, "sub", 0, sub));
it.insert(Instruction::new(3, "div", 0, div));
it.insert(Instruction::new(4, "mult", 0, mult));
it
}
#[test]
fn addition_example() {
let it = instruction_table();
let mut builder: Builder<f64> = Builder::new(&it);
builder.push("push", vec![2.0]);
builder.push("push", vec![3.0]);
builder.push("add", vec![]);
builder.push("push", vec![4.0]);
builder.push("add", vec![]);
let constants: WriteManyTable<f64> = WriteManyTable::new();
let machine = Machine::from_builder(builder, &constants);
let mut machine = Machine::run(machine);
let result = machine.operand_pop();
assert_eq!(result, 9.0);
}
#[test]
fn subtraction_example() {
let it = instruction_table();
let mut builder: Builder<f64> = Builder::new(&it);
builder.push("push", vec![3.0]);
builder.push("push", vec![4.0]);
builder.push("add", vec![]);
builder.push("push", vec![2.0]);
builder.push("sub", vec![]);
let constants: WriteManyTable<f64> = WriteManyTable::new();
let machine = Machine::from_builder(builder, &constants);
let mut machine = Machine::run(machine);
let result = machine.operand_pop();
assert_eq!(result, 5.0);
}
#[test]
fn division_example() {
let it = instruction_table();
let mut builder: Builder<f64> = Builder::new(&it);
builder.push("push", vec![3.0]);
builder.push("push", vec![4.0]);
builder.push("div", vec![]);
let constants: WriteManyTable<f64> = WriteManyTable::new();
let machine = Machine::from_builder(builder, &constants);
let mut machine = Machine::run(machine);
let result = machine.operand_pop();
assert_eq!(result, 0.75);
}
#[test]
fn multiplication_example() {
let it = instruction_table();
let mut builder: Builder<f64> = Builder::new(&it);
builder.push("push", vec![3.0]);
builder.push("push", vec![4.0]);
builder.push("mult", vec![]);
let constants: WriteManyTable<f64> = WriteManyTable::new();
let machine = Machine::from_builder(builder, &constants);
let mut machine = Machine::run(machine);
let result = machine.operand_pop();
assert_eq!(result, 12.0);
}