use std::convert::TryFrom;
use std::rc::Rc;
use crate::ast::*;
#[allow(non_camel_case_types)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum OpcodeType {
OP_NOP = 0,
OP_POP = 1,
OP_DUP,
OP_DUP2,
OP_ROT2,
OP_ROT3,
OP_ROT4,
OP_INTEGER,
OP_NUMBER,
OP_STRING,
OP_CLOSURE,
OP_NEWARRAY,
OP_NEWOBJECT,
OP_UNDEF,
OP_NULL,
OP_TRUE,
OP_FALSE,
OP_THIS,
OP_CURRENT,
OP_HASVAR,
OP_GETVAR,
OP_SETVAR,
OP_DELVAR,
OP_INITPROP,
OP_INITGETTER,
OP_INITSETTER,
OP_GETPROP,
OP_GETPROP_S,
OP_SETPROP,
OP_SETPROP_S,
OP_DELPROP,
OP_DELPROP_S,
OP_ITERATOR,
OP_NEXTITER,
OP_EVAL,
OP_CALL,
OP_NEW,
OP_TYPEOF,
OP_POS,
OP_NEG,
OP_BITNOT,
OP_LOGNOT,
OP_INC,
OP_DEC,
OP_POSTINC,
OP_POSTDEC,
OP_MUL,
OP_DIV,
OP_MOD,
OP_ADD,
OP_SUB,
OP_SHL,
OP_SHR,
OP_USHR,
OP_LT,
OP_GT,
OP_LE,
OP_GE,
OP_EQ,
OP_NE,
OP_STRICTEQ,
OP_STRICTNE,
OP_JCASE,
OP_BITAND,
OP_BITXOR,
OP_BITOR,
OP_IN,
OP_INSTANCEOF,
OP_THROW,
OP_TRY,
OP_ENDTRY,
OP_CATCH,
OP_ENDCATCH,
OP_JUMP,
OP_JTRUE,
OP_JFALSE,
OP_RETURN,
OP_DEBUG,
OP_LAST,
}
impl TryFrom<u16> for OpcodeType {
type Error = ();
fn try_from(v: u16) -> Result<Self, Self::Error> {
match v {
x if x == OpcodeType::OP_NOP as u16 => Ok(OpcodeType::OP_NOP),
x if x == OpcodeType::OP_POP as u16 => Ok(OpcodeType::OP_POP),
x if x == OpcodeType::OP_DUP as u16 => Ok(OpcodeType::OP_DUP),
x if x == OpcodeType::OP_DUP2 as u16 => Ok(OpcodeType::OP_DUP2),
x if x == OpcodeType::OP_ROT2 as u16 => Ok(OpcodeType::OP_ROT2),
x if x == OpcodeType::OP_ROT3 as u16 => Ok(OpcodeType::OP_ROT3),
x if x == OpcodeType::OP_ROT4 as u16 => Ok(OpcodeType::OP_ROT4),
x if x == OpcodeType::OP_INTEGER as u16 => Ok(OpcodeType::OP_INTEGER),
x if x == OpcodeType::OP_NUMBER as u16 => Ok(OpcodeType::OP_NUMBER),
x if x == OpcodeType::OP_STRING as u16 => Ok(OpcodeType::OP_STRING),
x if x == OpcodeType::OP_CLOSURE as u16 => Ok(OpcodeType::OP_CLOSURE),
x if x == OpcodeType::OP_NEWARRAY as u16 => Ok(OpcodeType::OP_NEWARRAY),
x if x == OpcodeType::OP_NEWOBJECT as u16 => Ok(OpcodeType::OP_NEWOBJECT),
x if x == OpcodeType::OP_UNDEF as u16 => Ok(OpcodeType::OP_UNDEF),
x if x == OpcodeType::OP_NULL as u16 => Ok(OpcodeType::OP_NULL),
x if x == OpcodeType::OP_TRUE as u16 => Ok(OpcodeType::OP_TRUE),
x if x == OpcodeType::OP_FALSE as u16 => Ok(OpcodeType::OP_FALSE),
x if x == OpcodeType::OP_THIS as u16 => Ok(OpcodeType::OP_THIS),
x if x == OpcodeType::OP_CURRENT as u16 => Ok(OpcodeType::OP_CURRENT),
x if x == OpcodeType::OP_HASVAR as u16 => Ok(OpcodeType::OP_HASVAR),
x if x == OpcodeType::OP_GETVAR as u16 => Ok(OpcodeType::OP_GETVAR),
x if x == OpcodeType::OP_SETVAR as u16 => Ok(OpcodeType::OP_SETVAR),
x if x == OpcodeType::OP_DELVAR as u16 => Ok(OpcodeType::OP_DELVAR),
x if x == OpcodeType::OP_INITPROP as u16 => Ok(OpcodeType::OP_INITPROP),
x if x == OpcodeType::OP_INITGETTER as u16 => Ok(OpcodeType::OP_INITGETTER),
x if x == OpcodeType::OP_INITSETTER as u16 => Ok(OpcodeType::OP_INITSETTER),
x if x == OpcodeType::OP_GETPROP as u16 => Ok(OpcodeType::OP_GETPROP),
x if x == OpcodeType::OP_GETPROP_S as u16 => Ok(OpcodeType::OP_GETPROP_S),
x if x == OpcodeType::OP_SETPROP as u16 => Ok(OpcodeType::OP_SETPROP),
x if x == OpcodeType::OP_SETPROP_S as u16 => Ok(OpcodeType::OP_SETPROP_S),
x if x == OpcodeType::OP_DELPROP as u16 => Ok(OpcodeType::OP_DELPROP),
x if x == OpcodeType::OP_DELPROP_S as u16 => Ok(OpcodeType::OP_DELPROP_S),
x if x == OpcodeType::OP_ITERATOR as u16 => Ok(OpcodeType::OP_ITERATOR),
x if x == OpcodeType::OP_NEXTITER as u16 => Ok(OpcodeType::OP_NEXTITER),
x if x == OpcodeType::OP_EVAL as u16 => Ok(OpcodeType::OP_EVAL),
x if x == OpcodeType::OP_CALL as u16 => Ok(OpcodeType::OP_CALL),
x if x == OpcodeType::OP_NEW as u16 => Ok(OpcodeType::OP_NEW),
x if x == OpcodeType::OP_TYPEOF as u16 => Ok(OpcodeType::OP_TYPEOF),
x if x == OpcodeType::OP_POS as u16 => Ok(OpcodeType::OP_POS),
x if x == OpcodeType::OP_NEG as u16 => Ok(OpcodeType::OP_NEG),
x if x == OpcodeType::OP_BITNOT as u16 => Ok(OpcodeType::OP_BITNOT),
x if x == OpcodeType::OP_LOGNOT as u16 => Ok(OpcodeType::OP_LOGNOT),
x if x == OpcodeType::OP_INC as u16 => Ok(OpcodeType::OP_INC),
x if x == OpcodeType::OP_DEC as u16 => Ok(OpcodeType::OP_DEC),
x if x == OpcodeType::OP_POSTINC as u16 => Ok(OpcodeType::OP_POSTINC),
x if x == OpcodeType::OP_POSTDEC as u16 => Ok(OpcodeType::OP_POSTDEC),
x if x == OpcodeType::OP_MUL as u16 => Ok(OpcodeType::OP_MUL),
x if x == OpcodeType::OP_DIV as u16 => Ok(OpcodeType::OP_DIV),
x if x == OpcodeType::OP_MOD as u16 => Ok(OpcodeType::OP_MOD),
x if x == OpcodeType::OP_ADD as u16 => Ok(OpcodeType::OP_ADD),
x if x == OpcodeType::OP_SUB as u16 => Ok(OpcodeType::OP_SUB),
x if x == OpcodeType::OP_SHL as u16 => Ok(OpcodeType::OP_SHL),
x if x == OpcodeType::OP_SHR as u16 => Ok(OpcodeType::OP_SHR),
x if x == OpcodeType::OP_USHR as u16 => Ok(OpcodeType::OP_USHR),
x if x == OpcodeType::OP_LT as u16 => Ok(OpcodeType::OP_LT),
x if x == OpcodeType::OP_GT as u16 => Ok(OpcodeType::OP_GT),
x if x == OpcodeType::OP_LE as u16 => Ok(OpcodeType::OP_LE),
x if x == OpcodeType::OP_GE as u16 => Ok(OpcodeType::OP_GE),
x if x == OpcodeType::OP_EQ as u16 => Ok(OpcodeType::OP_EQ),
x if x == OpcodeType::OP_NE as u16 => Ok(OpcodeType::OP_NE),
x if x == OpcodeType::OP_STRICTEQ as u16 => Ok(OpcodeType::OP_STRICTEQ),
x if x == OpcodeType::OP_STRICTNE as u16 => Ok(OpcodeType::OP_STRICTNE),
x if x == OpcodeType::OP_JCASE as u16 => Ok(OpcodeType::OP_JCASE),
x if x == OpcodeType::OP_BITAND as u16 => Ok(OpcodeType::OP_BITAND),
x if x == OpcodeType::OP_BITXOR as u16 => Ok(OpcodeType::OP_BITXOR),
x if x == OpcodeType::OP_BITOR as u16 => Ok(OpcodeType::OP_BITOR),
x if x == OpcodeType::OP_IN as u16 => Ok(OpcodeType::OP_IN),
x if x == OpcodeType::OP_INSTANCEOF as u16 => Ok(OpcodeType::OP_INSTANCEOF),
x if x == OpcodeType::OP_THROW as u16 => Ok(OpcodeType::OP_THROW),
x if x == OpcodeType::OP_TRY as u16 => Ok(OpcodeType::OP_TRY),
x if x == OpcodeType::OP_ENDTRY as u16 => Ok(OpcodeType::OP_ENDTRY),
x if x == OpcodeType::OP_CATCH as u16 => Ok(OpcodeType::OP_CATCH),
x if x == OpcodeType::OP_ENDCATCH as u16 => Ok(OpcodeType::OP_ENDCATCH),
x if x == OpcodeType::OP_JUMP as u16 => Ok(OpcodeType::OP_JUMP),
x if x == OpcodeType::OP_JTRUE as u16 => Ok(OpcodeType::OP_JTRUE),
x if x == OpcodeType::OP_JFALSE as u16 => Ok(OpcodeType::OP_JFALSE),
x if x == OpcodeType::OP_RETURN as u16 => Ok(OpcodeType::OP_RETURN),
x if x == OpcodeType::OP_DEBUG as u16 => Ok(OpcodeType::OP_DEBUG),
x if x == OpcodeType::OP_LAST as u16 => Err(()),
_ => Err(()),
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Copy, Clone)]
pub enum VMJumpType {
BreakJump(usize),
ContinueJump(usize),
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone)]
pub enum VMJumpScope {
TryScope(Option<AstNode>),
CatchScope,
SwitchScope,
ForLoop,
ForInLoop,
DoLoop,
WhileLoop,
LabelSection(String),
}
#[allow(non_camel_case_types)]
pub struct VMJumpTable {
pub scope: VMJumpScope,
pub lst: Vec<VMJumpType>
}
#[allow(non_camel_case_types)]
pub struct VMFunction {
pub name: Option<String>,
pub script: bool,
pub numparams: usize,
pub numvars: usize,
pub code: Vec<u16>,
pub num_tab: Vec<f64>,
pub str_tab: Vec<String>,
pub func_tab: Vec<Rc<Box<VMFunction>>>,
pub jumps: Vec<VMJumpTable>,
}