1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4
5use crate::resolver::{Resolver, UpValue};
6use crate::scanner::{Scanner, Token};
7use crate::value::Value;
8
9#[derive(PartialEq, PartialOrd, Debug, Clone, Copy, Serialize, Deserialize)]
11pub enum OpCode {
12 OpReturn,
13 OpPop,
14
15 OpDefineGlobal(usize),
17 OpGetGlobal(usize),
19 OpSetGlobal(usize),
21 OpGetSuper(usize),
23 OpCallGlobal(usize, usize, usize), OpGetModuleVar(usize, usize),
27
28 OpGetLocal(usize),
30
31 OpSetLocal(usize),
32 OpInvoke(usize, usize, usize),
35
36 OpImport(usize),
38 OpGetProperty(usize),
39 OpSetProperty(usize),
41 OpGetUpvalue(usize),
44 OpSetUpvalue(usize),
46 OpClosure,
48
49 OpJump(usize),
51 OpJumpIfFalse(usize),
52 OpLoop(usize),
54 OpCall(usize, usize),
56 OpClass(usize),
58 OpConstant(usize),
60
61 OpNil,
62 OpTrue,
63 OpFalse,
64
65 OpNegate,
66 OpNot,
67
68 OpAdd,
69 OpSubtract,
70 OpMultiply,
71 OpDivide,
72 OpEqual,
73 OpGreater,
74 OpLess,
75
76 OpPrint,
77 OpGetIndex,
79 OpSetIndex,
81 OpCreateList(usize),
83 OpCreateString,
85 OpCreateHashMap(usize),
87 OpWait,
89}
90
91#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
92pub struct Instr {
93 pub op_code: OpCode,
94 pub line_num: usize,
95}
96
97#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
98pub struct Chunk {
99 pub code: Vec<Instr>,
100}
101
102impl Default for Chunk {
103 fn default() -> Self {
104 Self::new()
105 }
106}
107
108impl Chunk {
109 pub fn write_instruction(&mut self, instruction: Instr) {
110 self.code.push(instruction);
111 }
112
113 pub fn new() -> Chunk {
114 Chunk { code: Vec::new() }
115 }
116}
117
118#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
119pub enum FunctionType {
120 Function,
121 Script,
122 Method,
123 Initializer,
124}
125
126#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
128pub struct FunctionChunk {
129 pub chunk: Chunk,
130 pub name: Option<String>,
131 pub arity: usize,
133 pub fn_type: FunctionType,
134 pub upvalues: Option<Vec<UpValue>>, }
136
137impl FunctionChunk {
138 pub fn new(name: Option<String>, arity: usize, fn_type: FunctionType) -> FunctionChunk {
139 FunctionChunk {
140 chunk: Chunk::new(),
141 name,
142 arity,
143 fn_type,
144 upvalues: None,
145 }
146 }
147
148 pub fn set_upvalues(&mut self, upvalues: Vec<UpValue>) {
149 self.upvalues = Some(upvalues);
150 }
151}
152
153#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
155pub struct ClassChunk {
156 pub name: String,
157 pub methods: HashMap<usize, usize>,
158 pub superclass: Option<usize>,
159 pub has_init: bool,
160}
161
162impl ClassChunk {
163 pub fn new(name: String) -> ClassChunk {
164 ClassChunk {
165 name,
166 methods: HashMap::new(),
167 superclass: None,
168 has_init: false,
169 }
170 }
171}
172
173#[derive(Debug, Clone)]
175pub struct CompilerModuleChunk {
176 pub name: String,
178 pub main: bool,
180 pub chunk: Chunk,
182 pub scanner: Scanner,
183 pub tokens: Vec<Token>,
184 pub constants: Vec<Value>,
185 pub functions: Vec<FunctionChunk>,
186 pub classes: Vec<ClassChunk>,
187 pub(crate) current_function: usize,
188 pub current_class: Option<usize>,
189 pub parent_functions: Vec<usize>,
191 pub resolver: Resolver,
193 pub identifier_constants: Vec<String>,
194 pub has_init: bool,
196}
197
198impl CompilerModuleChunk {
199 pub fn new(main: bool, name: String, file: String, code: String) -> CompilerModuleChunk {
200 CompilerModuleChunk {
201 main,
202 name,
203 chunk: Chunk::new(),
204 functions: Vec::new(),
205 constants: Vec::new(),
206 classes: Vec::new(),
207 current_function: 0,
208 current_class: None,
209 parent_functions: vec![],
210 resolver: Resolver::new(),
211 identifier_constants: vec![],
212 has_init: false,
213 scanner: Scanner::new(file, code, 0),
214 tokens: vec![],
215 }
216 }
217}
218
219#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
221pub struct ModuleChunk {
222 pub name: String,
224 pub main: bool,
226 pub file: String,
228 pub constants: Vec<Value>,
229 pub identifiers: Vec<String>,
230 pub functions: Vec<FunctionChunk>,
231 pub classes: Vec<ClassChunk>,
232 pub has_init: bool,
234}
235
236impl ModuleChunk {
237 pub fn new(main: bool, name: String, file: String) -> ModuleChunk {
238 ModuleChunk {
239 main,
240 name,
241 functions: Vec::new(),
242 constants: Vec::new(),
243 classes: Vec::new(),
244 has_init: false,
245 file,
246 identifiers: vec![],
247 }
248 }
249
250 pub fn from(module: CompilerModuleChunk) -> ModuleChunk {
251 ModuleChunk {
252 main: module.main,
253 name: module.name,
254 functions: module.functions,
255 constants: module.constants,
256 classes: module.classes,
257 has_init: module.has_init,
258 file: module.scanner.file,
259 identifiers: module.identifier_constants,
260 }
261 }
262}