use crate::obj::ObjPtr; use crate::vm::name::Name; #[derive(Debug, Clone)] pub enum JumpCondition { False, True, Always, } #[derive(Debug, Clone)] pub enum Inst { /// Pushes an object to the stack. Push(ObjPtr), /// Loads a local value in a name and pushes it to the stack. Load(Name), /// Pops the top item off of the stack and stores it in a name. Store(Name), /// Get an attribute from the top item of the stack. GetAttr(String), /// Pops the top item off of the stack, discarding it. Pop, /// Pops the top N function arguments off the stack, and attempt to call the /// next stack item. Call(usize), /// Exits the current function stack frame and returns control to the /// calling function. /// /// This will take the last value on top of the stack (the return value), /// resize the stack to its last size (pre-call), and push the return value /// back to the top of the stack. Return, /// Adds the given value to the current program counter (positive or /// negative) when the given condition holds.. /// /// `Inst::JumpRelative(1)` functions as a no-op. /// `Inst::JumpRelative(0)` functions as a "hang" /// `Inst::JumpRelative(-1)` jumps to the previous instruction. JumpRelative(isize, JumpCondition), /// Pops the top value off of the stack and sets the condition flag to /// "true" or "false". Compare, Comment(String), } impl Inst { pub fn disassemble_string(&self) -> String { match self { Inst::Push(ptr) => format!("push <{:#x}>", (ptr as *const _ as usize)), Inst::Load(name) => format!("load {name:?}"), Inst::Store(name) => format!("store {name:?}"), Inst::GetAttr(attr) => format!("getattr {attr}"), Inst::Pop => format!("pop"), Inst::Call(argc) => format!("call {argc}"), Inst::Return => format!("return"), Inst::JumpRelative(distance, condition) => { format!("jump {:+} (when condition is {:?})", distance, condition) } Inst::Compare => format!("compare"), Inst::Comment(comment) => format!("# {comment}"), } } }