#[derive(Debug, Clone, PartialEq)]
pub enum Op {
Const(usize),
Int(i64),
Nil,
True,
False,
LoadLocal(usize),
StoreLocal(usize),
LoadCaptured(usize),
StoreCaptured(usize),
LoadGlobal(usize),
StoreGlobal(usize),
Pop,
Dup,
Jmp(usize),
JmpNot(usize),
JmpIf(usize),
Call(usize),
TailCall(usize),
Return,
MakeClosure(usize),
MakeList(usize),
EvalSexp(usize),
PushHandler {
catch_ip: usize,
error_local: usize,
},
PopHandler,
Halt,
}
impl Op {
#[must_use]
pub fn stack_effect(&self) -> Option<i32> {
Some(match self {
Self::Const(_) | Self::Int(_) | Self::Nil | Self::True | Self::False => 1,
Self::LoadLocal(_) | Self::LoadGlobal(_) | Self::LoadCaptured(_) => 1,
Self::StoreLocal(_) | Self::StoreGlobal(_) | Self::StoreCaptured(_) => -1,
Self::Pop => -1,
Self::Dup => 1,
Self::Jmp(_) => 0,
Self::JmpNot(_) | Self::JmpIf(_) => -1,
Self::Call(arity) | Self::TailCall(arity) => -(*arity as i32),
Self::Return => -1,
Self::MakeClosure(_) => 1,
Self::MakeList(n) => 1 - *n as i32,
Self::EvalSexp(_) => 1,
Self::PushHandler { .. } | Self::PopHandler => 0,
Self::Halt => 0,
})
}
}