1use std::fmt;
4
5use gc_arena::Collect;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
9pub struct JumpTarget(pub usize);
10
11#[derive(Debug, Clone, Copy, Collect, PartialEq, Eq, PartialOrd, Ord, Hash)]
13#[collect(require_static)]
14pub enum OpCode {
15    Pop,
17    Copy(usize),
19    Swap(usize),
21    LoadLocal(usize),
23    LoadGlobal(usize),
25    LoadUpvalue(usize),
27    LoadConst(usize),
29    StoreLocal(usize),
31    StoreGlobal(usize),
33    StoreUpvalue(usize),
35
36    Import(usize),
38    ImportFrom(usize),
40    ImportGlob,
42
43    BuildTable(usize),
45    BuildList(usize),
47    GetAttr,
49    GetItem,
51    GetMeta,
53    SetAttr,
55    SetItem,
57    SetMeta,
59
60    Neg,
62    Not,
64
65    Add,
67    Sub,
69    Mul,
71    Div,
73    Mod,
75
76    Eq,
78    Ne,
80    Gt,
82    Ge,
84    Lt,
86    Le,
88    Is,
90
91    Iter,
93    Jump(JumpTarget),
95    JumpIfNull(JumpTarget),
97    JumpPopIfFalse(JumpTarget),
99    JumpIfTrueOrPop(JumpTarget),
101    JumpIfFalseOrPop(JumpTarget),
103
104    Call(usize),
106    TryCall(usize),
108    Return,
110    Throw,
112    ReturnCall(usize),
114
115    JumpTarget(JumpTarget),
117}
118
119impl fmt::Display for OpCode {
120    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
121        let width = 20;
122        match self {
123            Self::Pop => write!(f, "Pop"),
124            Self::Copy(i) => write!(f, "{:width$}{}", "Copy", i),
125            Self::Swap(i) => write!(f, "{:width$}{}", "Swap", i),
126            Self::LoadLocal(i) => write!(f, "{:width$}{}", "LoadLocal", i),
127            Self::LoadGlobal(i) => write!(f, "{:width$}{}", "LoadGlobal", i),
128            Self::LoadUpvalue(i) => write!(f, "{:width$}{}", "LoadUpvalue", i),
129            Self::LoadConst(i) => write!(f, "{:width$}{}", "LoadConst", i),
130            Self::StoreLocal(i) => write!(f, "{:width$}{}", "StoreLocal", i),
131            Self::StoreGlobal(i) => write!(f, "{:width$}{}", "StoreGlobal", i),
132            Self::StoreUpvalue(i) => write!(f, "{:width$}{}", "StoreUpvalue", i),
133            Self::Import(i) => write!(f, "{:width$}{}", "Import", i),
134            Self::ImportFrom(i) => write!(f, "{:width$}{}", "ImportFrom", i),
135            Self::ImportGlob => write!(f, "ImportGlob"),
136            Self::BuildTable(i) => write!(f, "{:width$}{}", "BuildTable", i),
137            Self::BuildList(i) => write!(f, "{:width$}{}", "BuildList", i),
138            Self::GetAttr => write!(f, "GetAttr"),
139            Self::GetItem => write!(f, "GetItem"),
140            Self::GetMeta => write!(f, "GetMeta"),
141            Self::SetAttr => write!(f, "SetAttr"),
142            Self::SetItem => write!(f, "SetItem"),
143            Self::SetMeta => write!(f, "SetMeta"),
144            Self::Neg => write!(f, "Neg"),
145            Self::Not => write!(f, "Not"),
146            Self::Add => write!(f, "Add"),
147            Self::Sub => write!(f, "Sub"),
148            Self::Mul => write!(f, "Mul"),
149            Self::Div => write!(f, "Div"),
150            Self::Mod => write!(f, "Mod"),
151            Self::Eq => write!(f, "Eq"),
152            Self::Ne => write!(f, "Ne"),
153            Self::Gt => write!(f, "Gt"),
154            Self::Ge => write!(f, "Ge"),
155            Self::Lt => write!(f, "Lt"),
156            Self::Le => write!(f, "Le"),
157            Self::Is => write!(f, "Is"),
158            Self::Iter => write!(f, "Iter"),
159            Self::Jump(JumpTarget(i)) => write!(f, "{:width$}{}", "Jump", i),
160            Self::JumpIfNull(JumpTarget(i)) => write!(f, "{:width$}{}", "JumpIfNull", i),
161            Self::JumpPopIfFalse(JumpTarget(i)) => write!(f, "{:width$}{}", "JumpPopIfFalse", i),
162            Self::JumpIfTrueOrPop(JumpTarget(i)) => write!(f, "{:width$}{}", "JumpIfTrueOrPop", i),
163            Self::JumpIfFalseOrPop(JumpTarget(i)) => {
164                write!(f, "{:width$}{}", "JumpIfFalseOrPop", i)
165            }
166            Self::Call(i) => write!(f, "{:width$}{}", "Call", i),
167            Self::TryCall(i) => write!(f, "{:width$}{}", "TryCall", i),
168            Self::Return => write!(f, "Return"),
169            Self::Throw => write!(f, "Throw"),
170            Self::ReturnCall(i) => write!(f, "{:width$}{}", "ReturnCall", i),
171            Self::JumpTarget(JumpTarget(i)) => write!(f, "{:width$}{}", "JumpTarget", i),
172        }
173    }
174}