use super::instruction::{CLOSURE, CONST, JUMP, NO_ARG};
#[derive(Debug)]
pub enum OpCode {
PUSH,
POP,
CONST,
DEFGLB,
GETGLB,
DEFLCL,
GETLCL,
GETFREE,
ADD,
SUB,
PRODUCT,
DIVIDE,
MOD,
BANG,
NEG,
CGT,
CGTE,
CLT,
CLTE,
CEQ,
CNEQ,
AND,
OR,
BAND,
BOR,
JMP,
JIS,
JNS,
JEQ,
JNEQ,
ARRAY,
INDEX,
CALL,
RETN,
RETV,
CLOSURE,
GETCUR,
}
impl OpCode {
pub fn arg_len(&self) -> &'static [usize] {
match self {
OpCode::PUSH
| OpCode::POP
| OpCode::ADD
| OpCode::SUB
| OpCode::PRODUCT
| OpCode::DIVIDE
| OpCode::MOD
| OpCode::BANG
| OpCode::NEG
| OpCode::CGT
| OpCode::CGTE
| OpCode::CLT
| OpCode::CLTE
| OpCode::CEQ
| OpCode::CNEQ
| OpCode::AND
| OpCode::OR
| OpCode::BAND
| OpCode::BOR
| OpCode::RETN
| OpCode::RETV
| OpCode::GETCUR => NO_ARG.arg_size,
OpCode::CONST
| OpCode::DEFGLB
| OpCode::GETGLB
| OpCode::DEFLCL
| OpCode::GETLCL
| OpCode::GETFREE
| OpCode::CALL
| OpCode::ARRAY
| OpCode::INDEX => CONST.arg_size,
OpCode::JMP
| OpCode::JIS
| OpCode::JNS
| OpCode::JEQ
| OpCode::JNEQ => JUMP.arg_size,
OpCode::CLOSURE => CLOSURE.arg_size,
}
}
pub fn length(&self) -> usize {
match self {
OpCode::PUSH
| OpCode::POP
| OpCode::ADD
| OpCode::SUB
| OpCode::PRODUCT
| OpCode::DIVIDE
| OpCode::MOD
| OpCode::BANG
| OpCode::NEG
| OpCode::CGT
| OpCode::CGTE
| OpCode::CLT
| OpCode::CLTE
| OpCode::CEQ
| OpCode::CNEQ
| OpCode::AND
| OpCode::OR
| OpCode::BAND
| OpCode::BOR
| OpCode::RETN
| OpCode::RETV
| OpCode::GETCUR => NO_ARG.length,
OpCode::CONST
| OpCode::DEFGLB
| OpCode::GETGLB
| OpCode::DEFLCL
| OpCode::GETLCL
| OpCode::GETFREE
| OpCode::CALL
| OpCode::ARRAY
| OpCode::INDEX => CONST.length,
OpCode::JMP
| OpCode::JIS
| OpCode::JNS
| OpCode::JEQ
| OpCode::JNEQ => JUMP.length,
OpCode::CLOSURE => CLOSURE.length,
}
}
}