Add Inst::Dupe

Duplicates the top of the stack.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2023-04-07 02:34:53 -07:00
parent c450e07e08
commit 4e505bd979
2 changed files with 17 additions and 1 deletions

View File

@@ -21,6 +21,9 @@ pub enum Inst {
/// Pops the top item off of the stack and stores it in a name. /// Pops the top item off of the stack and stores it in a name.
Store(Name), Store(Name),
/// Duplicate the top of the stack.
Dupe,
/// Get an attribute from the top item of the stack. /// Get an attribute from the top item of the stack.
GetAttr(Arc<String>), GetAttr(Arc<String>),
@@ -60,6 +63,7 @@ impl Inst {
Inst::Push(ptr) => format!("push <{:#x}>", (ptr as *const _ as usize)), Inst::Push(ptr) => format!("push <{:#x}>", (ptr as *const _ as usize)),
Inst::Load(name) => format!("load {name:?}"), Inst::Load(name) => format!("load {name:?}"),
Inst::Store(name) => format!("store {name:?}"), Inst::Store(name) => format!("store {name:?}"),
Inst::Dupe => format!("dupe"),
Inst::GetAttr(name) => format!("getattr {name}"), Inst::GetAttr(name) => format!("getattr {name}"),
Inst::Pop => format!("pop"), Inst::Pop => format!("pop"),
Inst::Call(argc) => format!("call {argc}"), Inst::Call(argc) => format!("call {argc}"),

View File

@@ -75,6 +75,11 @@ impl Vm {
self.stack_mut().pop() 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 { pub fn condition(&self) -> bool {
self.condition self.condition
} }
@@ -163,11 +168,18 @@ impl Vm {
let value = self.pop_stack().expect("Stack underflow"); let value = self.pop_stack().expect("Stack underflow");
self.store(name, Some(value)); 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) => { Inst::GetAttr(name) => {
let name = std::sync::Arc::clone(name); let name = std::sync::Arc::clone(name);
let obj = self let obj = self
.pop_stack() .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); let value = obj.get(&name);
if let Some(value) = value { if let Some(value) = value {
self.push_stack(value); self.push_stack(value);