diff --git a/src/instruction.rs b/src/instruction.rs index 134bd15..3cca3c1 100644 --- a/src/instruction.rs +++ b/src/instruction.rs @@ -6,6 +6,8 @@ pub enum Instruction { Call (u8, u8, u8), Closure (u8, u32), + Div (u8, u8, u8), + EqI (u8, i8, bool), // Equals Constant? @@ -90,5 +92,7 @@ pub enum Instruction { Test (u8, bool), + UnM (u8, u8), + VarArgPrep (i32), } diff --git a/src/loader.rs b/src/loader.rs index d9b056c..a3241a8 100644 --- a/src/loader.rs +++ b/src/loader.rs @@ -115,9 +115,11 @@ pub fn parse_inst (buf: [u8; 4]) -> Option 0x22 => Inst::Add (a, b, c), 0x23 => Inst::Sub (a, b, c), 0x24 => Inst::Mul (a, b, c), + 0x27 => Inst::Div (a, b, c), 0x2e => Inst::MmBin (a, b, c), 0x2f => Inst::MmBinI (a, i_sb (buf)?, c, k), 0x30 => Inst::MmBinK (a, b, c, k), + 0x31 => Inst::UnM (a, b), 0x33 => Inst::Not (a, b), 0x34 => Inst::Len (a, b), 0x3c => Inst::EqK (a, b, k), diff --git a/src/state.rs b/src/state.rs index b9c854a..c947318 100644 --- a/src/state.rs +++ b/src/state.rs @@ -283,6 +283,22 @@ impl <'a> State <'a> { upvalues: new_upvalues, }); }, + Instruction::Div (a, b, c) => { + let v_b = self.reg (*b); + let v_c = self.reg (*c); + + let x = if let (Some (v_b), Some (v_c)) = (v_b.as_int (), v_c.as_int ()) + { + Value::from (v_b / v_c) + } + else { + let v_b = v_b.as_float ().unwrap_or_else (|| panic! ("{v_b}")); + let v_c = v_c.as_float ().unwrap_or_else (|| panic! ("{v_c}")); + Value::from (v_b / v_c) + }; + + *self.reg_mut (*a) = x; + }, Instruction::EqI (a, sb, k_flag) => { if (self.reg (*a).as_int ().unwrap () == *sb as i64) != *k_flag { @@ -687,6 +703,20 @@ impl <'a> State <'a> { next_pc += 1; } }, + Instruction::UnM (a, b) => { + let v_b = self.reg (*b); + + let x = if let Some (v_b) = v_b.as_int () + { + Value::from (-v_b) + } + else { + let v_b = v_b.as_float ().unwrap_or_else (|| panic! ("{v_b}")); + Value::from (-v_b) + }; + + *self.reg_mut (*a) = x; + }, Instruction::VarArgPrep (_) => (), }