1use crate::entities::{AbiType, Block, Named, NamedProperty, Type, Value, ValueInfo};
4use crate::instruction::{InstBlock, InstructionInfo, Opcode};
5
6pub trait InstBuilder {
8
9 fn create_value(&mut self, value: ValueInfo) -> Value;
11
12 fn create_inst(&mut self, inst: InstructionInfo);
14
15 fn create_block(&mut self, block: InstBlock) -> Block;
18
19 fn use_block(&mut self, block: Block) -> &mut InstBlock;
21
22 fn require_import(&mut self, name: String);
24
25 fn iconst_int(&mut self, value: u64) -> Value {
27 self.create_value(ValueInfo::IntegerConstant(value))
28 }
29
30 fn iconst_float(&mut self, value: f64) -> Value {
32 self.create_value(ValueInfo::FloatConstant(value))
33 }
34
35 fn iconst_double(&mut self, value: f64) -> Value {
37 self.create_value(ValueInfo::DoubleConstant(value))
38 }
39
40 fn iconst_bool(&mut self, value: bool) -> Value {
42 self.create_value(ValueInfo::BooleanConstant(value))
43 }
44
45 fn iconst_str(&mut self, value: String) -> Value {
47 self.create_value(ValueInfo::StringConstant(value))
48 }
49
50 fn iconst_named(&mut self, name: String) -> Value {
52 self.create_value(ValueInfo::Named(Named::new(name)))
53 }
54
55 fn iconst_named_props(&mut self, name: String, props: Vec<NamedProperty>) -> Value {
57 self.create_value(ValueInfo::Named(Named::new_props(name, props)))
58 }
59
60 fn iconst_named_property(&self, name: String) -> NamedProperty {
62 NamedProperty::Basic(name)
63 }
64
65 fn iconst_named_static(&self, name: String) -> NamedProperty {
67 NamedProperty::Static(name)
68 }
69
70 fn iconst_named_pointer(&self, name: String) -> NamedProperty {
72 NamedProperty::Pointer(name)
73 }
74
75 fn iconst_named_index(&self, name: Value) -> NamedProperty {
77 NamedProperty::Index(name)
78 }
79
80 fn ctype_bool(&mut self) -> AbiType {
83 self.require_import("stdbool.h".into());
85 AbiType("bool".into(), Type::Plain)
86 }
87
88 fn ctype_uint8(&mut self) -> AbiType {
91 self.require_import("stdint.h".into());
92 AbiType("uint8_t".into(), Type::Plain)
93 }
94
95 fn ctype_uint16(&mut self) -> AbiType {
98 self.require_import("stdint.h".into());
99 AbiType("uint16_t".into(), Type::Plain)
100 }
101
102 fn ctype_uint32(&mut self) -> AbiType {
105 self.require_import("stdint.h".into());
106 AbiType("uint32_t".into(), Type::Plain)
107 }
108
109 fn ctype_uint64(&mut self) -> AbiType {
112 self.require_import("stdint.h".into());
113 AbiType("uint64_t".into(), Type::Plain)
114 }
115
116 fn ctype_usize(&mut self) -> AbiType {
120 self.require_import("stdint.h".into());
121 AbiType("uintptr".into(), Type::Plain)
122 }
123
124 fn ctype_int8(&mut self) -> AbiType {
127 self.require_import("stdint.h".into());
128 AbiType("int8_t".into(), Type::Plain)
129 }
130
131 fn ctype_int16(&mut self) -> AbiType {
134 self.require_import("stdint.h".into());
135 AbiType("uint16_t".into(), Type::Plain)
136 }
137
138 fn ctype_int32(&mut self) -> AbiType {
141 self.require_import("stdint.h".into());
142 AbiType("int32_t".into(), Type::Plain)
143 }
144
145 fn ctype_int64(&mut self) -> AbiType {
148 self.require_import("stdint.h".into());
149 AbiType("int64_t".into(), Type::Plain)
150 }
151
152 fn ctype_isize(&mut self) -> AbiType {
156 self.require_import("stdint.h".into());
157 AbiType("intptr".into(), Type::Plain)
158 }
159
160 fn ctype_char(&mut self) -> AbiType {
162 AbiType("char".into(), Type::Plain)
163 }
164
165 fn iadd(&mut self, l: Value, r: Value) -> Value {
167 self.create_value(ValueInfo::Instruction(InstructionInfo {
168 opcode: Opcode::Add,
169 arguments: vec![l, r]
170 }))
171 }
172
173 fn isub(&mut self, l: Value, r: Value) -> Value {
175 self.create_value(ValueInfo::Instruction(InstructionInfo {
176 opcode: Opcode::Sub,
177 arguments: vec![l, r]
178 }))
179 }
180
181 fn imul(&mut self, l: Value, r: Value) -> Value {
183 self.create_value(ValueInfo::Instruction(InstructionInfo {
184 opcode: Opcode::Mul,
185 arguments: vec![l, r]
186 }))
187 }
188
189 fn idiv(&mut self, l: Value, r: Value) -> Value {
191 self.create_value(ValueInfo::Instruction(InstructionInfo {
192 opcode: Opcode::Div,
193 arguments: vec![l, r]
194 }))
195 }
196
197 fn imod(&mut self, l: Value, r: Value) -> Value {
200 self.create_value(ValueInfo::Instruction(InstructionInfo {
201 opcode: Opcode::Mod,
202 arguments: vec![l, r]
203 }))
204 }
205
206 fn ibit_and(&mut self, l: Value, r: Value) -> Value {
208 self.create_value(ValueInfo::Instruction(InstructionInfo {
209 opcode: Opcode::BitAnd,
210 arguments: vec![l, r]
211 }))
212 }
213
214 fn ibit_or(&mut self, l: Value, r: Value) -> Value {
216 self.create_value(ValueInfo::Instruction(InstructionInfo {
217 opcode: Opcode::BitOr,
218 arguments: vec![l, r]
219 }))
220 }
221
222 fn ibit_xor(&mut self, l: Value, r: Value) -> Value {
224 self.create_value(ValueInfo::Instruction(InstructionInfo {
225 opcode: Opcode::BitXor,
226 arguments: vec![l, r]
227 }))
228 }
229
230 fn ibit_not(&mut self, l: Value) -> Value {
232 self.create_value(ValueInfo::Instruction(InstructionInfo {
233 opcode: Opcode::BitNot,
234 arguments: vec![l]
235 }))
236 }
237
238 fn ibit_left(&mut self, l: Value, r: Value) -> Value {
240 self.create_value(ValueInfo::Instruction(InstructionInfo {
241 opcode: Opcode::BitLeft,
242 arguments: vec![l, r]
243 }))
244 }
245
246 fn ibit_right(&mut self, l: Value, r: Value) -> Value {
248 self.create_value(ValueInfo::Instruction(InstructionInfo {
249 opcode: Opcode::BitRight,
250 arguments: vec![l, r]
251 }))
252 }
253
254 fn itest_eq(&mut self, l: Value, r: Value) -> Value {
257 self.create_value(ValueInfo::Instruction(InstructionInfo {
258 opcode: Opcode::TestEq,
259 arguments: vec![l, r]
260 }))
261 }
262
263 fn itest_neq(&mut self, l: Value, r: Value) -> Value {
266 self.create_value(ValueInfo::Instruction(InstructionInfo {
267 opcode: Opcode::TestNeq,
268 arguments: vec![l, r]
269 }))
270 }
271
272 fn itest_gt(&mut self, l: Value, r: Value) -> Value {
275 self.create_value(ValueInfo::Instruction(InstructionInfo {
276 opcode: Opcode::TestGt,
277 arguments: vec![l, r]
278 }))
279 }
280
281 fn itest_gt_eq(&mut self, l: Value, r: Value) -> Value {
284 self.create_value(ValueInfo::Instruction(InstructionInfo {
285 opcode: Opcode::TestGtEq,
286 arguments: vec![l, r]
287 }))
288 }
289
290 fn itest_lt(&mut self, l: Value, r: Value) -> Value {
293 self.create_value(ValueInfo::Instruction(InstructionInfo {
294 opcode: Opcode::TestLt,
295 arguments: vec![l, r]
296 }))
297 }
298
299 fn itest_lt_eq(&mut self, l: Value, r: Value) -> Value {
302 self.create_value(ValueInfo::Instruction(InstructionInfo {
303 opcode: Opcode::TestLtEq,
304 arguments: vec![l, r]
305 }))
306 }
307
308 fn inot(&mut self, l: Value) -> Value {
310 self.create_value(ValueInfo::Instruction(InstructionInfo {
311 opcode: Opcode::Not,
312 arguments: vec![l]
313 }))
314 }
315
316 fn ior(&mut self, l: Value, r: Value) -> Value {
318 self.create_value(ValueInfo::Instruction(InstructionInfo {
319 opcode: Opcode::Or,
320 arguments: vec![l, r]
321 }))
322 }
323
324 fn iand(&mut self, l: Value, r: Value) -> Value {
326 self.create_value(ValueInfo::Instruction(InstructionInfo {
327 opcode: Opcode::And,
328 arguments: vec![l, r]
329 }))
330 }
331
332 fn jmp(&mut self, block: Block) {
334 let b = self.create_value(ValueInfo::Block(block));
335 self.create_inst(InstructionInfo {
336 opcode: Opcode::Jmp,
337 arguments: vec![b]
338 });
339 }
340
341 fn iuse(&mut self, named: Named) -> Value {
343 self.create_value(ValueInfo::Named(named))
344 }
345
346 fn set(&mut self, k: Value, v: Value) {
348 self.create_inst(InstructionInfo {
349 opcode: Opcode::Set,
350 arguments: vec![k, v]
351 });
352 }
353
354 fn call(&mut self, k: Value, args: Vec<Value>) {
356 let mut v = vec![k];
357 v.append(&mut args.clone());
358 self.create_inst(InstructionInfo {
359 opcode: Opcode::Call,
360 arguments: v
361 });
362 }
363
364 fn icall(&mut self, k: Value, args: Vec<Value>) -> Value {
366 let mut v = vec![k];
367 v.append(&mut args.clone());
368 self.create_value(ValueInfo::Instruction(InstructionInfo {
369 opcode: Opcode::Call,
370 arguments: v
371 }))
372 }
373
374 fn return_(&mut self, v: Value) {
376 self.create_inst(InstructionInfo {
377 opcode: Opcode::Ret,
378 arguments: vec![v]
379 });
380 }
381
382 fn return_none(&mut self) {
385 self.create_inst(InstructionInfo {
386 opcode: Opcode::Ret,
387 arguments: vec![]
388 });
389 }
390
391}