diff --git a/src/instruction.rs b/src/instruction.rs index cedb35d..2746faf 100644 --- a/src/instruction.rs +++ b/src/instruction.rs @@ -1,6 +1,7 @@ #[derive (Debug, PartialEq)] pub enum Instruction { Add (u8, u8, u8), + AddI (u8, u8, i8), Call (u8, u8, u8), Closure (u8, u32), diff --git a/src/loader.rs b/src/loader.rs index 712527b..a0fad1a 100644 --- a/src/loader.rs +++ b/src/loader.rs @@ -71,6 +71,11 @@ fn i_sb (buf: [u8; 4]) -> Option { i8::try_from (i32::try_from (b).ok ()? - 127).ok () } +fn i_sc (buf: [u8; 4]) -> Option { + let c = buf [3]; + i8::try_from (i32::try_from (c).ok ()? - 127).ok () +} + pub fn parse_inst (buf: [u8; 4]) -> Option { let opcode = buf [0] & 0x7f; @@ -79,6 +84,7 @@ pub fn parse_inst (buf: [u8; 4]) -> Option let b = buf [2]; let ax = a as u32 + ((b as u32) << 8); let c = buf [3]; + let s_c = c - 0x80; let bx = (((buf [1] >> 7) as u32) << 0) | ((buf [2] as u32) << 1) | @@ -104,6 +110,7 @@ pub fn parse_inst (buf: [u8; 4]) -> Option 0x11 => Inst::SetI (a, b, c, k), 0x12 => Inst::SetField (a, b, c, k), 0x13 => Inst::NewTable (a), + 0x15 => Inst::AddI (a, b, i_sc (buf)?), 0x18 => Inst::MulK (a, b, c), 0x19 => Inst::ModK (a, b, c), 0x22 => Inst::Add (a, b, c), diff --git a/src/state.rs b/src/state.rs index 40d85f8..563eee2 100644 --- a/src/state.rs +++ b/src/state.rs @@ -178,6 +178,20 @@ impl <'a> State <'a> { *self.reg_mut (*a) = x; }, + Instruction::AddI (a, b, s_c) => { + let v_b = self.reg (*b); + + let x = if let Some (v_b) = v_b.as_int () + { + Value::from (v_b + *s_c as i64) + } + else { + let v_b = v_b.as_float ().unwrap_or_else (|| panic! ("{v_b}")); + Value::from (v_b + f64::from (*s_c)) + }; + + *self.reg_mut (*a) = x; + }, Instruction::Call (a, b, _c) => { let b = usize::from (*b);