use crate::runtime::bytecode::OpCode::*;
use std::fmt;
use std::fmt::Display;
#[derive(Debug)]
#[rustfmt::skip]
pub enum OpCode {
OpNone, OpPop,
OpConst, OpTrue,
OpFalse,
OpMktuple, OpAdd,
OpSubtract,
OpMultiply,
OpDivide,
OpNegate,
OpAnd,
OpOr,
OpNot,
OpEquals,
OpGt,
OpLt,
OpReturn,
OpSetGlobal, OpGetGlobal, OpSetLocal, OpGetLocal, OpSetFunt, OpCall, OpJump, OpJumpIfFalse, OpLoop, OpPull, OpProduce, OpOpenCursor, OpCloseCursor, OpTupleGet,
OpNewInstance, OpSetField, OpGetField, }
impl From<u8> for OpCode {
fn from(value: u8) -> OpCode {
OpCode::from_byte(value)
}
}
impl From<OpCode> for u8 {
fn from(value: OpCode) -> Self {
value as u8
}
}
impl OpCode {
pub fn from_byte(value: u8) -> OpCode {
match value {
x if x == OpNone as u8 => OpNone,
x if x == OpPop as u8 => OpPop,
x if x == OpConst as u8 => OpConst,
x if x == OpTrue as u8 => OpTrue,
x if x == OpFalse as u8 => OpFalse,
x if x == OpMktuple as u8 => OpMktuple,
x if x == OpAdd as u8 => OpAdd,
x if x == OpSubtract as u8 => OpSubtract,
x if x == OpMultiply as u8 => OpMultiply,
x if x == OpDivide as u8 => OpDivide,
x if x == OpNegate as u8 => OpNegate,
x if x == OpAnd as u8 => OpAnd,
x if x == OpOr as u8 => OpOr,
x if x == OpNot as u8 => OpNot,
x if x == OpEquals as u8 => OpEquals,
x if x == OpGt as u8 => OpGt,
x if x == OpLt as u8 => OpLt,
x if x == OpReturn as u8 => OpReturn,
x if x == OpSetGlobal as u8 => OpSetGlobal,
x if x == OpGetGlobal as u8 => OpGetGlobal,
x if x == OpSetLocal as u8 => OpSetLocal,
x if x == OpGetLocal as u8 => OpGetLocal,
x if x == OpSetFunt as u8 => OpSetFunt,
x if x == OpCall as u8 => OpCall,
x if x == OpJump as u8 => OpJump,
x if x == OpJumpIfFalse as u8 => OpJumpIfFalse,
x if x == OpLoop as u8 => OpLoop,
x if x == OpPull as u8 => OpPull,
x if x == OpProduce as u8 => OpProduce,
x if x == OpOpenCursor as u8 => OpOpenCursor,
x if x == OpCloseCursor as u8 => OpCloseCursor,
x if x == OpTupleGet as u8 => OpTupleGet,
x if x == OpNewInstance as u8 => OpNewInstance,
x if x == OpSetField as u8 => OpSetField,
x if x == OpGetField as u8 => OpGetField,
_ => {
panic!("value {} does not correspond to an opcode", value)
}
}
}
}
pub(crate) fn instruction_length(instruction: OpCode) -> usize {
match instruction {
OpNone => 1,
OpPop => 1,
OpConst => 2,
OpTrue => 1,
OpFalse => 1,
OpMktuple => 2,
OpAdd => 1,
OpSubtract => 1,
OpMultiply => 1,
OpDivide => 1,
OpNegate => 1,
OpAnd => 1,
OpOr => 1,
OpNot => 1,
OpEquals => 1,
OpGt => 1,
OpLt => 1,
OpReturn => 1,
OpSetGlobal => 2,
OpGetGlobal => 2,
OpSetLocal => 2,
OpGetLocal => 2,
OpSetFunt => 2,
OpCall => 2,
OpJump => 2,
OpJumpIfFalse => 2,
OpLoop => 2,
OpPull => 2,
OpProduce => 2,
OpOpenCursor => 2,
OpCloseCursor => 2,
OpTupleGet => 2,
OpNewInstance => 2,
OpSetField => 2,
OpGetField => 2,
}
}
impl Display for OpCode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self)
}
}