diff --git a/src/vm.rs b/src/vm.rs index bad2fe2..29eb95d 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -4,7 +4,7 @@ pub type VM_Word = i64; #[repr(u64)] pub enum VM_Instruction { Nop, Jmp, Call, Branch, Ret, - Lit, Dup, Drop, Swap, Rot, + Lit, Pick, Roll, Dup, Drop, Swap, Rot, Fetch, Store, Accept, Emit, Add, //Sub, Mul, Div, Rem, @@ -103,6 +103,23 @@ impl VM { let val = char::from(self.data_stack.pop().expect("emit expects value") as u8); print!("{}", val); } + VM_Instruction::Pick => { + let n = self.data_stack.pop().expect("pick requires index") as usize; + self.data_stack.push( *self.data_stack.get( self.data_stack.len() - n ).expect("pick invalid index") ); + } + VM_Instruction::Roll => { + let n = self.data_stack.pop().expect("pick requires index") as usize; + let l = self.data_stack.len(); + if n <= l { + if n > 1 { + let val = self.data_stack.remove( l-n ); + self.data_stack.push( val ); + } + } else { + eprintln!("stack = {:?}", self.data_stack); + eprintln!("roll invalid index"); + } + } VM_Instruction::Dup => { self.data_stack.push( *self.data_stack.last().expect("dup expect val") ); } @@ -114,7 +131,7 @@ impl VM { let b = self.data_stack.pop().expect("swap expects value"); self.data_stack.push(a); self.data_stack.push(b); - } + } VM_Instruction::Rot => { let a = self.data_stack.pop().expect("rot expects value"); let b = self.data_stack.pop().expect("rot expects value");