From 4e505bd979e50e989fb3788d707e854add67d8ef Mon Sep 17 00:00:00 2001 From: Alek Ratzloff Date: Fri, 7 Apr 2023 02:34:53 -0700 Subject: [PATCH] Add Inst::Dupe Duplicates the top of the stack. Signed-off-by: Alek Ratzloff --- src/vm/inst.rs | 4 ++++ src/vm/mod.rs | 14 +++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/vm/inst.rs b/src/vm/inst.rs index 904f3d4..197ea88 100644 --- a/src/vm/inst.rs +++ b/src/vm/inst.rs @@ -21,6 +21,9 @@ pub enum Inst { /// Pops the top item off of the stack and stores it in a name. Store(Name), + /// Duplicate the top of the stack. + Dupe, + /// Get an attribute from the top item of the stack. GetAttr(Arc), @@ -60,6 +63,7 @@ impl Inst { Inst::Push(ptr) => format!("push <{:#x}>", (ptr as *const _ as usize)), Inst::Load(name) => format!("load {name:?}"), Inst::Store(name) => format!("store {name:?}"), + Inst::Dupe => format!("dupe"), Inst::GetAttr(name) => format!("getattr {name}"), Inst::Pop => format!("pop"), Inst::Call(argc) => format!("call {argc}"), diff --git a/src/vm/mod.rs b/src/vm/mod.rs index e35060e..34e5448 100644 --- a/src/vm/mod.rs +++ b/src/vm/mod.rs @@ -75,6 +75,11 @@ impl Vm { self.stack_mut().pop() } + /// Peek at the top value of the stack. + pub fn peek_stack(&self) -> Option<&ObjPtr> { + self.stack().last() + } + pub fn condition(&self) -> bool { self.condition } @@ -163,11 +168,18 @@ impl Vm { let value = self.pop_stack().expect("Stack underflow"); self.store(name, Some(value)); } + Inst::Dupe => { + let obj = self + .peek_stack() + .cloned() + .expect("Inst::Dupe executed, but there was no value on top of the stack."); + self.push_stack(obj); + } Inst::GetAttr(name) => { let name = std::sync::Arc::clone(name); let obj = self .pop_stack() - .expect("Inst::GetAttr, but there was no value on top of the stack."); + .expect("Inst::GetAttr executed, but there was no value on top of the stack."); let value = obj.get(&name); if let Some(value) = value { self.push_stack(value);