From a94d4313b7ad638acae4644ba2fefaf25cbed42e Mon Sep 17 00:00:00 2001 From: Andrew Morris Date: Wed, 4 May 2022 11:33:12 +1000 Subject: [PATCH] Simplify with apply_binary_op, add more operations --- src/vstc/virtual_machine/operations.rs | 24 +++++ src/vstc/virtual_machine/virtual_machine.rs | 97 ++++++--------------- 2 files changed, 50 insertions(+), 71 deletions(-) diff --git a/src/vstc/virtual_machine/operations.rs b/src/vstc/virtual_machine/operations.rs index c737dfb..95f7ca8 100644 --- a/src/vstc/virtual_machine/operations.rs +++ b/src/vstc/virtual_machine/operations.rs @@ -23,6 +23,14 @@ pub fn op_mul(left: Val, right: Val) -> Val { return Val::Number(left.to_number() * right.to_number()); } +pub fn op_div(left: Val, right: Val) -> Val { + return Val::Number(left.to_number() / right.to_number()); +} + +pub fn op_exp(left: Val, right: Val) -> Val { + return Val::Number(left.to_number().powf(right.to_number())); +} + pub fn op_mod(left: Val, right: Val) -> Val { return Val::Number(left.to_number() % right.to_number()); } @@ -42,3 +50,19 @@ pub fn op_triple_ne(left: Val, right: Val) -> Val { return Val::Bool(left.to_number() != right.to_number()); } + +pub fn op_and(left: Val, right: Val) -> Val { + return if left.is_truthy() { + right + } else { + left + }; +} + +pub fn op_or(left: Val, right: Val) -> Val { + return if left.is_truthy() { + left + } else { + right + }; +} diff --git a/src/vstc/virtual_machine/virtual_machine.rs b/src/vstc/virtual_machine/virtual_machine.rs index e23b391..d01c950 100644 --- a/src/vstc/virtual_machine/virtual_machine.rs +++ b/src/vstc/virtual_machine/virtual_machine.rs @@ -20,6 +20,22 @@ pub struct StackFrame { pub return_target: Option, } +impl StackFrame { + pub fn apply_binary_op( + &mut self, + op: fn(left: Val, right: Val) -> Val, + ) { + let left = self.decoder.decode_val(&self.registers); + let right = self.decoder.decode_val(&self.registers); + + let register_index = self.decoder.decode_register_index(); + + if register_index.is_some() { + self.registers[register_index.unwrap()] = op(left, right); + } + } +} + impl VirtualMachine { pub fn run(&mut self, bytecode: &Rc>) -> Val { let mut bd = BytecodeDecoder { @@ -102,53 +118,12 @@ impl VirtualMachine { frame.registers[register_index] = val; }, - OpPlus => { - let left = frame.decoder.decode_val(&frame.registers); - let right = frame.decoder.decode_val(&frame.registers); - - let register_index = frame.decoder.decode_register_index(); - - if register_index.is_some() { - frame.registers[register_index.unwrap()] = operations::op_plus(left, right); - } - }, - - OpMinus => { - let left = frame.decoder.decode_val(&frame.registers); - let right = frame.decoder.decode_val(&frame.registers); - - let register_index = frame.decoder.decode_register_index(); - - if register_index.is_some() { - frame.registers[register_index.unwrap()] = operations::op_minus(left, right); - } - }, - - OpMul => { - let left = frame.decoder.decode_val(&frame.registers); - let right = frame.decoder.decode_val(&frame.registers); - - let register_index = frame.decoder.decode_register_index(); - - if register_index.is_some() { - frame.registers[register_index.unwrap()] = operations::op_mul(left, right); - } - }, - - OpDiv => std::panic!("Instruction not implemented: OpDiv"), - - OpMod => { - let left = frame.decoder.decode_val(&frame.registers); - let right = frame.decoder.decode_val(&frame.registers); - - let register_index = frame.decoder.decode_register_index(); - - if register_index.is_some() { - frame.registers[register_index.unwrap()] = operations::op_mod(left, right); - } - }, - - OpExp => std::panic!("Instruction not implemented: OpExp"), + OpPlus => frame.apply_binary_op(operations::op_plus), + OpMinus => frame.apply_binary_op(operations::op_minus), + OpMul => frame.apply_binary_op(operations::op_mul), + OpDiv => frame.apply_binary_op(operations::op_div), + OpMod => frame.apply_binary_op(operations::op_mod), + OpExp => frame.apply_binary_op(operations::op_exp), OpEq => std::panic!("Instruction not implemented: OpEq"), @@ -156,33 +131,13 @@ impl VirtualMachine { OpTripleEq => std::panic!("Instruction not implemented: OpTripleEq"), - OpTripleNe => { - let left = frame.decoder.decode_val(&frame.registers); - let right = frame.decoder.decode_val(&frame.registers); - - let register_index = frame.decoder.decode_register_index(); - - if register_index.is_some() { - frame.registers[register_index.unwrap()] = operations::op_triple_ne(left, right); - } - } - - OpAnd => std::panic!("Instruction not implemented: OpAnd"), - - OpOr => std::panic!("Instruction not implemented: OpOr"), + OpTripleNe => frame.apply_binary_op(operations::op_triple_ne), + OpAnd => frame.apply_binary_op(operations::op_and), + OpOr => frame.apply_binary_op(operations::op_or), OpNot => std::panic!("Instruction not implemented: OpNot"), - OpLess => { - let left = frame.decoder.decode_val(&frame.registers); - let right = frame.decoder.decode_val(&frame.registers); - - let register_index = frame.decoder.decode_register_index(); - - if register_index.is_some() { - frame.registers[register_index.unwrap()] = operations::op_less(left, right); - } - } + OpLess => frame.apply_binary_op(operations::op_less), OpLessEq => std::panic!("Instruction not implemented: OpLessEq"),