1use crate::entities::{Block, GlobalData, Symbol, Value};
4use crate::instruction::{ InstructionData, Opcode };
5use std::collections::HashMap;
6
7pub struct Module {
9
10 pub symbols: HashMap<String, Symbol>,
12
13 pub data: HashMap<String, GlobalData>
15
16}
17
18#[derive(Clone)]
20pub enum FunctionValue {
21
22 Boolean(bool),
24
25 Byte(u8),
27
28 Integer(i64),
30
31 Float(f64),
33
34 Block(Block),
36
37 Instruction(InstructionData),
39
40 Symbol(String),
42
43}
44
45#[derive(Clone)]
47pub struct Function {
48
49 pub blocks: Vec<FunctionBlock>,
51
52 pub values: Vec<FunctionValue>,
54
55 pub current_block: u32,
57
58}
59
60#[derive(Clone)]
62pub struct FunctionBlock {
63
64 pub instructions: Vec<InstructionData>,
66
67}
68
69impl Module {
70
71 pub fn new() -> Self {
73 Self {
74 symbols: HashMap::new(),
75 data: HashMap::new(),
76 }
77 }
78
79 pub fn declare_function(&mut self, name: String) {
81 self.symbols.insert(name, Symbol::External);
82 }
83
84 pub fn define_function(&mut self, name: String, f: Function) {
86 self.symbols.insert(name, Symbol::Local(f));
87 }
88
89}
90
91impl Function {
93
94 pub fn new() -> Self {
96 Function {
97 blocks: vec![],
98 values: vec![],
99 current_block: 0,
100 }
101 }
102
103 pub fn create_block(&mut self) -> Block {
106 let b = FunctionBlock {
107 instructions: vec![]
108 };
109 let block = Block(self.blocks.len() as u32);
110 self.blocks.push(b);
111
112 block
113 }
114
115 pub fn switch_to_block(&mut self, block: Block) {
117 self.current_block = block.0;
118 }
119
120 pub fn iconst_boolean(&mut self, val: bool) -> Value {
123 let id = self.values.len();
124 let v = Value(id as u32);
125
126 self.values.push(FunctionValue::Boolean(val));
127
128 v
129 }
130
131 pub fn iconst_integer(&mut self, val: i64) -> Value {
134 let id = self.values.len();
135 let v = Value(id as u32);
136
137 self.values.push(FunctionValue::Integer(val));
138
139 v
140 }
141
142 pub fn iconst_float(&mut self, val: f64) -> Value {
145 let id = self.values.len();
146 let v = Value(id as u32);
147
148 self.values.push(FunctionValue::Float(val));
149
150 v
151 }
152
153 pub fn ipop(&mut self) -> Value {
155 let id = self.values.len();
156 let v = Value(id as u32);
157
158 self.values.push(FunctionValue::Instruction(InstructionData {
159 opcode: Opcode::Pop,
160 args: vec![],
161 }));
162
163 v
164 }
165
166 pub fn pop(&mut self) {
168 self.blocks
169 .get_mut(self.current_block as usize).unwrap()
170 .instructions.push(InstructionData {
171 opcode: Opcode::Pop,
172 args: vec![],
173 });
174 }
175
176 pub fn iclone(&mut self) -> Value {
178 let id = self.values.len();
179 let v = Value(id as u32);
180
181 self.values.push(FunctionValue::Instruction(InstructionData {
182 opcode: Opcode::Pop,
183 args: vec![],
184 }));
185
186 v
187 }
188
189 pub fn clone(&mut self) {
191 self.blocks
192 .get_mut(self.current_block as usize).unwrap()
193 .instructions.push(InstructionData {
194 opcode: Opcode::Clone,
195 args: vec![],
196 });
197 }
198
199 pub fn clear(&mut self) {
201 self.blocks
202 .get_mut(self.current_block as usize).unwrap()
203 .instructions.push(InstructionData {
204 opcode: Opcode::Clear,
205 args: vec![],
206 });
207 }
208
209 pub fn iboolean_add(&mut self, l: Value, r: Value) -> Value {
215 let id = self.values.len();
216 let v = Value(id as u32);
217
218 self.values.push(FunctionValue::Instruction(InstructionData {
219 opcode: Opcode::BooleanAdd,
220 args: vec![l, r],
221 }));
222
223 v
224 }
225
226 pub fn boolean_add(&mut self, l: Value, r: Value) {
232 self.blocks
233 .get_mut(self.current_block as usize).unwrap()
234 .instructions.push(InstructionData {
235 opcode: Opcode::BooleanAdd,
236 args: vec![l, r],
237 });
238 }
239
240 pub fn iboolean_sub(&mut self, l: Value, r: Value) -> Value {
246 let id = self.values.len();
247 let v = Value(id as u32);
248
249 self.values.push(FunctionValue::Instruction(InstructionData {
250 opcode: Opcode::BooleanSubtract,
251 args: vec![l, r],
252 }));
253
254 v
255 }
256
257 pub fn boolean_sub(&mut self, l: Value, r: Value) {
263 self.blocks
264 .get_mut(self.current_block as usize).unwrap()
265 .instructions.push(InstructionData {
266 opcode: Opcode::BooleanSubtract,
267 args: vec![l, r],
268 });
269 }
270
271 pub fn ibyte_add(&mut self, l: Value, r: Value) -> Value {
277 let id = self.values.len();
278 let v = Value(id as u32);
279
280 self.values.push(FunctionValue::Instruction(InstructionData {
281 opcode: Opcode::ByteAdd,
282 args: vec![l, r],
283 }));
284
285 v
286 }
287
288 pub fn byte_add(&mut self, l: Value, r: Value) {
294 self.blocks
295 .get_mut(self.current_block as usize).unwrap()
296 .instructions.push(InstructionData {
297 opcode: Opcode::ByteAdd,
298 args: vec![l, r],
299 });
300 }
301
302 pub fn ibyte_sub(&mut self, l: Value, r: Value) -> Value {
308 let id = self.values.len();
309 let v = Value(id as u32);
310
311 self.values.push(FunctionValue::Instruction(InstructionData {
312 opcode: Opcode::ByteSubtract,
313 args: vec![l, r],
314 }));
315
316 v
317 }
318
319 pub fn byte_sub(&mut self, l: Value, r: Value) {
325 self.blocks
326 .get_mut(self.current_block as usize).unwrap()
327 .instructions.push(InstructionData {
328 opcode: Opcode::ByteSubtract,
329 args: vec![l, r],
330 });
331 }
332
333 pub fn ibyte_mul(&mut self, l: Value, r: Value) -> Value {
339 let id = self.values.len();
340 let v = Value(id as u32);
341
342 self.values.push(FunctionValue::Instruction(InstructionData {
343 opcode: Opcode::ByteMultiply,
344 args: vec![l, r],
345 }));
346
347 v
348 }
349
350 pub fn byte_mul(&mut self, l: Value, r: Value) {
356 self.blocks
357 .get_mut(self.current_block as usize).unwrap()
358 .instructions.push(InstructionData {
359 opcode: Opcode::ByteMultiply,
360 args: vec![l, r],
361 });
362 }
363
364 pub fn ibyte_div(&mut self, l: Value, r: Value) -> Value {
370 let id = self.values.len();
371 let v = Value(id as u32);
372
373 self.values.push(FunctionValue::Instruction(InstructionData {
374 opcode: Opcode::ByteDivide,
375 args: vec![l, r],
376 }));
377
378 v
379 }
380
381 pub fn byte_div(&mut self, l: Value, r: Value) {
387 self.blocks
388 .get_mut(self.current_block as usize).unwrap()
389 .instructions.push(InstructionData {
390 opcode: Opcode::ByteDivide,
391 args: vec![l, r],
392 });
393 }
394
395 pub fn ibyte_mod(&mut self, l: Value, r: Value) -> Value {
401 let id = self.values.len();
402 let v = Value(id as u32);
403
404 self.values.push(FunctionValue::Instruction(InstructionData {
405 opcode: Opcode::ByteRemainder,
406 args: vec![l, r],
407 }));
408
409 v
410 }
411
412 pub fn integer_mod(&mut self, l: Value, r: Value) {
418 self.blocks
419 .get_mut(self.current_block as usize).unwrap()
420 .instructions.push(InstructionData {
421 opcode: Opcode::ByteRemainder,
422 args: vec![l, r],
423 });
424 }
425
426 pub fn iint_add(&mut self, l: Value, r: Value) -> Value {
432 let id = self.values.len();
433 let v = Value(id as u32);
434
435 self.values.push(FunctionValue::Instruction(InstructionData {
436 opcode: Opcode::IntegerAdd,
437 args: vec![l, r],
438 }));
439
440 v
441 }
442
443 pub fn int_add(&mut self, l: Value, r: Value) {
449 self.blocks
450 .get_mut(self.current_block as usize).unwrap()
451 .instructions.push(InstructionData {
452 opcode: Opcode::IntegerAdd,
453 args: vec![l, r],
454 });
455 }
456
457 pub fn iint_sub(&mut self, l: Value, r: Value) -> Value {
463 let id = self.values.len();
464 let v = Value(id as u32);
465
466 self.values.push(FunctionValue::Instruction(InstructionData {
467 opcode: Opcode::IntegerSubtract,
468 args: vec![l, r],
469 }));
470
471 v
472 }
473
474 pub fn int_sub(&mut self, l: Value, r: Value) {
480 self.blocks
481 .get_mut(self.current_block as usize).unwrap()
482 .instructions.push(InstructionData {
483 opcode: Opcode::IntegerSubtract,
484 args: vec![l, r],
485 });
486 }
487
488 pub fn iint_mul(&mut self, l: Value, r: Value) -> Value {
494 let id = self.values.len();
495 let v = Value(id as u32);
496
497 self.values.push(FunctionValue::Instruction(InstructionData {
498 opcode: Opcode::IntegerMultiply,
499 args: vec![l, r],
500 }));
501
502 v
503 }
504
505 pub fn int_mul(&mut self, l: Value, r: Value) {
511 self.blocks
512 .get_mut(self.current_block as usize).unwrap()
513 .instructions.push(InstructionData {
514 opcode: Opcode::IntegerMultiply,
515 args: vec![l, r],
516 });
517 }
518
519 pub fn iint_div(&mut self, l: Value, r: Value) -> Value {
525 let id = self.values.len();
526 let v = Value(id as u32);
527
528 self.values.push(FunctionValue::Instruction(InstructionData {
529 opcode: Opcode::IntegerDivide,
530 args: vec![l, r],
531 }));
532
533 v
534 }
535
536 pub fn int_div(&mut self, l: Value, r: Value) {
542 self.blocks
543 .get_mut(self.current_block as usize).unwrap()
544 .instructions.push(InstructionData {
545 opcode: Opcode::IntegerDivide,
546 args: vec![l, r],
547 });
548 }
549
550 pub fn iint_mod(&mut self, l: Value, r: Value) -> Value {
556 let id = self.values.len();
557 let v = Value(id as u32);
558
559 self.values.push(FunctionValue::Instruction(InstructionData {
560 opcode: Opcode::IntegerRemainder,
561 args: vec![l, r],
562 }));
563
564 v
565 }
566
567 pub fn int_mod(&mut self, l: Value, r: Value) {
573 self.blocks
574 .get_mut(self.current_block as usize).unwrap()
575 .instructions.push(InstructionData {
576 opcode: Opcode::IntegerRemainder,
577 args: vec![l, r],
578 });
579 }
580
581 pub fn ifloat_add(&mut self, l: Value, r: Value) -> Value {
587 let id = self.values.len();
588 let v = Value(id as u32);
589
590 self.values.push(FunctionValue::Instruction(InstructionData {
591 opcode: Opcode::FloatAdd,
592 args: vec![l, r],
593 }));
594
595 v
596 }
597
598 pub fn float_add(&mut self, l: Value, r: Value) {
604 self.blocks
605 .get_mut(self.current_block as usize).unwrap()
606 .instructions.push(InstructionData {
607 opcode: Opcode::FloatAdd,
608 args: vec![l, r],
609 });
610 }
611
612 pub fn ifloat_sub(&mut self, l: Value, r: Value) -> Value {
618 let id = self.values.len();
619 let v = Value(id as u32);
620
621 self.values.push(FunctionValue::Instruction(InstructionData {
622 opcode: Opcode::FloatSubtract,
623 args: vec![l, r],
624 }));
625
626 v
627 }
628
629 pub fn float_sub(&mut self, l: Value, r: Value) {
635 self.blocks
636 .get_mut(self.current_block as usize).unwrap()
637 .instructions.push(InstructionData {
638 opcode: Opcode::FloatSubtract,
639 args: vec![l, r],
640 });
641 }
642
643 pub fn ifloat_mul(&mut self, l: Value, r: Value) -> Value {
649 let id = self.values.len();
650 let v = Value(id as u32);
651
652 self.values.push(FunctionValue::Instruction(InstructionData {
653 opcode: Opcode::FloatMultiply,
654 args: vec![l, r],
655 }));
656
657 v
658 }
659
660 pub fn float_mul(&mut self, l: Value, r: Value) {
666 self.blocks
667 .get_mut(self.current_block as usize).unwrap()
668 .instructions.push(InstructionData {
669 opcode: Opcode::FloatMultiply,
670 args: vec![l, r],
671 });
672 }
673
674 pub fn ifloat_div(&mut self, l: Value, r: Value) -> Value {
680 let id = self.values.len();
681 let v = Value(id as u32);
682
683 self.values.push(FunctionValue::Instruction(InstructionData {
684 opcode: Opcode::FloatDivide,
685 args: vec![l, r],
686 }));
687
688 v
689 }
690
691 pub fn float_div(&mut self, l: Value, r: Value) {
697 self.blocks
698 .get_mut(self.current_block as usize).unwrap()
699 .instructions.push(InstructionData {
700 opcode: Opcode::FloatDivide,
701 args: vec![l, r],
702 });
703 }
704
705 pub fn ifloat_mod(&mut self, l: Value, r: Value) -> Value {
711 let id = self.values.len();
712 let v = Value(id as u32);
713
714 self.values.push(FunctionValue::Instruction(InstructionData {
715 opcode: Opcode::FloatRemainder,
716 args: vec![l, r],
717 }));
718
719 v
720 }
721
722 pub fn float_mod(&mut self, l: Value, r: Value) {
728 self.blocks
729 .get_mut(self.current_block as usize).unwrap()
730 .instructions.push(InstructionData {
731 opcode: Opcode::FloatRemainder,
732 args: vec![l, r],
733 });
734 }
735
736 pub fn icast_boolean(&mut self, l: Value) -> Value {
741 let id = self.values.len();
742 let v = Value(id as u32);
743
744 self.values.push(FunctionValue::Instruction(InstructionData {
745 opcode: Opcode::CastBoolean,
746 args: vec![l],
747 }));
748
749 v
750 }
751
752 pub fn cast_boolean(&mut self, l: Value) {
757 self.blocks
758 .get_mut(self.current_block as usize).unwrap()
759 .instructions.push(InstructionData {
760 opcode: Opcode::CastBoolean,
761 args: vec![l],
762 });
763 }
764
765 pub fn icast_byte(&mut self, l: Value) -> Value {
770 let id = self.values.len();
771 let v = Value(id as u32);
772
773 self.values.push(FunctionValue::Instruction(InstructionData {
774 opcode: Opcode::CastByte,
775 args: vec![l],
776 }));
777
778 v
779 }
780
781 pub fn cast_byte(&mut self, l: Value) {
786 self.blocks
787 .get_mut(self.current_block as usize).unwrap()
788 .instructions.push(InstructionData {
789 opcode: Opcode::CastByte,
790 args: vec![l],
791 });
792 }
793
794 pub fn icast_int(&mut self, l: Value) -> Value {
799 let id = self.values.len();
800 let v = Value(id as u32);
801
802 self.values.push(FunctionValue::Instruction(InstructionData {
803 opcode: Opcode::CastInteger,
804 args: vec![l],
805 }));
806
807 v
808 }
809
810 pub fn cast_int(&mut self, l: Value) {
815 self.blocks
816 .get_mut(self.current_block as usize).unwrap()
817 .instructions.push(InstructionData {
818 opcode: Opcode::CastInteger,
819 args: vec![l],
820 });
821 }
822
823 pub fn icast_float(&mut self, l: Value) -> Value {
828 let id = self.values.len();
829 let v = Value(id as u32);
830
831 self.values.push(FunctionValue::Instruction(InstructionData {
832 opcode: Opcode::CastFloat,
833 args: vec![l],
834 }));
835
836 v
837 }
838
839 pub fn cast_float(&mut self, l: Value) {
844 self.blocks
845 .get_mut(self.current_block as usize).unwrap()
846 .instructions.push(InstructionData {
847 opcode: Opcode::CastFloat,
848 args: vec![l],
849 });
850 }
851
852 pub fn ineg_boolean(&mut self, l: Value) -> Value {
857 let id = self.values.len();
858 let v = Value(id as u32);
859
860 self.values.push(FunctionValue::Instruction(InstructionData {
861 opcode: Opcode::NegateBoolean,
862 args: vec![l],
863 }));
864
865 v
866 }
867
868 pub fn neg_boolean(&mut self, l: Value) {
873 self.blocks
874 .get_mut(self.current_block as usize).unwrap()
875 .instructions.push(InstructionData {
876 opcode: Opcode::NegateBoolean,
877 args: vec![l],
878 });
879 }
880
881 pub fn ineg_int(&mut self, l: Value) -> Value {
886 let id = self.values.len();
887 let v = Value(id as u32);
888
889 self.values.push(FunctionValue::Instruction(InstructionData {
890 opcode: Opcode::NegateInteger,
891 args: vec![l],
892 }));
893
894 v
895 }
896
897 pub fn neg_byte(&mut self, l: Value) {
902 self.blocks
903 .get_mut(self.current_block as usize).unwrap()
904 .instructions.push(InstructionData {
905 opcode: Opcode::NegateInteger,
906 args: vec![l],
907 });
908 }
909
910 pub fn ineg_float(&mut self, l: Value) -> Value {
915 let id = self.values.len();
916 let v = Value(id as u32);
917
918 self.values.push(FunctionValue::Instruction(InstructionData {
919 opcode: Opcode::NegateFloat,
920 args: vec![l],
921 }));
922
923 v
924 }
925
926 pub fn neg_float(&mut self, l: Value) {
931 self.blocks
932 .get_mut(self.current_block as usize).unwrap()
933 .instructions.push(InstructionData {
934 opcode: Opcode::NegateFloat,
935 args: vec![l],
936 });
937 }
938
939 pub fn iload(&mut self, l: Value, offset: i64) -> Value {
946 if offset > 0 {
947 let off = self.iconst_integer(offset);
948 let addr = self.iint_add(l, off);
949
950 let v = self.values.len();
951 let val = Value(v as u32);
952
953 self.values.push(FunctionValue::Instruction(InstructionData {
954 opcode: Opcode::Load,
955 args: vec![addr],
956 }));
957
958 val
959 } else if offset < 0 {
960 let off = self.iconst_integer(offset);
961 let addr = self.iint_sub(l, off);
962
963 let v = self.values.len();
964 let val = Value(v as u32);
965
966 self.values.push(FunctionValue::Instruction(InstructionData {
967 opcode: Opcode::Load,
968 args: vec![addr],
969 }));
970
971 val
972 } else {
973 let v = self.values.len();
974 let val = Value(v as u32);
975
976 self.values.push(FunctionValue::Instruction(InstructionData {
977 opcode: Opcode::Load,
978 args: vec![l],
979 }));
980
981 val
982 }
983 }
984
985 pub fn load(&mut self, l: Value, offset: i64) {
993 if offset > 0 {
994 let off = self.iconst_integer(offset);
995 let addr = self.iint_add(l, off);
996
997 self.blocks
998 .get_mut(self.current_block as usize).unwrap()
999 .instructions.push(InstructionData {
1000 opcode: Opcode::Load,
1001 args: vec![addr],
1002 });
1003 } else if offset < 0 {
1004 let off = self.iconst_integer(offset);
1005 let addr = self.iint_sub(l, off);
1006
1007 self.blocks
1008 .get_mut(self.current_block as usize).unwrap()
1009 .instructions.push(InstructionData {
1010 opcode: Opcode::Load,
1011 args: vec![addr],
1012 });
1013 } else {
1014 self.blocks
1015 .get_mut(self.current_block as usize).unwrap()
1016 .instructions.push(InstructionData {
1017 opcode: Opcode::Load,
1018 args: vec![l],
1019 });
1020 }
1021 }
1022
1023 pub fn store(&mut self, l: Value, r: Value, offset: i64) {
1031 if offset > 0 {
1032 let off = self.iconst_integer(offset);
1033 let addr = self.iint_add(l, off);
1034
1035 self.blocks
1036 .get_mut(self.current_block as usize).unwrap()
1037 .instructions.push(InstructionData {
1038 opcode: Opcode::Store,
1039 args: vec![addr, r],
1040 });
1041 } else if offset < 0 {
1042 let off = self.iconst_integer(offset);
1043 let addr = self.iint_sub(l, off);
1044
1045 self.blocks
1046 .get_mut(self.current_block as usize).unwrap()
1047 .instructions.push(InstructionData {
1048 opcode: Opcode::Store,
1049 args: vec![addr, r],
1050 });
1051 } else {
1052 self.blocks
1053 .get_mut(self.current_block as usize).unwrap()
1054 .instructions.push(InstructionData {
1055 opcode: Opcode::Store,
1056 args: vec![l, r],
1057 });
1058 }
1059 }
1060
1061 pub fn realloc(&mut self, l: Value) {
1066 self.blocks
1067 .get_mut(self.current_block as usize).unwrap()
1068 .instructions.push(InstructionData {
1069 opcode: Opcode::Realloc,
1070 args: vec![l],
1071 });
1072 }
1073
1074 pub fn iheap_size(&mut self) -> Value {
1076 let id = self.values.len();
1077 let v = Value(id as u32);
1078
1079 self.values.push(FunctionValue::Instruction(InstructionData {
1080 opcode: Opcode::HeapSize,
1081 args: vec![],
1082 }));
1083
1084 v
1085 }
1086
1087 pub fn heap_size(&mut self) {
1089 self.blocks
1090 .get_mut(self.current_block as usize).unwrap()
1091 .instructions.push(InstructionData {
1092 opcode: Opcode::HeapSize,
1093 args: vec![],
1094 });
1095 }
1096
1097 pub fn alloc(&mut self, l: Value) {
1102 self.blocks
1103 .get_mut(self.current_block as usize).unwrap()
1104 .instructions.push(InstructionData {
1105 opcode: Opcode::Alloc,
1106 args: vec![l],
1107 });
1108 }
1109
1110 pub fn realloc_section(&mut self, l: Value, r: Value) {
1116 self.blocks
1117 .get_mut(self.current_block as usize).unwrap()
1118 .instructions.push(InstructionData {
1119 opcode: Opcode::ReallocSection,
1120 args: vec![l, r],
1121 });
1122 }
1123
1124 pub fn isection_addr(&mut self, l: Value) -> Value {
1129 let id = self.values.len();
1130 let v = Value(id as u32);
1131
1132 self.values.push(FunctionValue::Instruction(InstructionData {
1133 opcode: Opcode::SectionAddr,
1134 args: vec![l],
1135 }));
1136
1137 v
1138 }
1139
1140 pub fn section_addr(&mut self, l: Value) {
1145 self.blocks
1146 .get_mut(self.current_block as usize).unwrap()
1147 .instructions.push(InstructionData {
1148 opcode: Opcode::SectionAddr,
1149 args: vec![l],
1150 });
1151 }
1152
1153 pub fn section_shift_left(&mut self, l: Value, r: Value) {
1159 self.blocks
1160 .get_mut(self.current_block as usize).unwrap()
1161 .instructions.push(InstructionData {
1162 opcode: Opcode::SectionShiftLeft,
1163 args: vec![l, r],
1164 });
1165 }
1166
1167 pub fn section_shift_right(&mut self, l: Value, r: Value) {
1173 self.blocks
1174 .get_mut(self.current_block as usize).unwrap()
1175 .instructions.push(InstructionData {
1176 opcode: Opcode::SectionShiftRight,
1177 args: vec![l, r],
1178 });
1179 }
1180
1181 pub fn free(&mut self, l: Value) {
1186 self.blocks
1187 .get_mut(self.current_block as usize).unwrap()
1188 .instructions.push(InstructionData {
1189 opcode: Opcode::Free,
1190 args: vec![l],
1191 });
1192 }
1193
1194 pub fn free_and_shift(&mut self, l: Value) {
1200 self.blocks
1201 .get_mut(self.current_block as usize).unwrap()
1202 .instructions.push(InstructionData {
1203 opcode: Opcode::FreeAndShift,
1204 args: vec![l],
1205 });
1206 }
1207
1208 pub fn branch(&mut self, l: Block) {
1213 let id = self.values.len();
1214 let v = Value(id as u32);
1215
1216 self.values.push(FunctionValue::Block(l));
1217
1218 self.blocks
1219 .get_mut(self.current_block as usize).unwrap()
1220 .instructions.push(InstructionData {
1221 opcode: Opcode::Branch,
1222 args: vec![v],
1223 });
1224 }
1225
1226 pub fn brz(&mut self, l: Value) {
1231 self.blocks
1232 .get_mut(self.current_block as usize).unwrap()
1233 .instructions.push(InstructionData {
1234 opcode: Opcode::BranchIfZero,
1235 args: vec![l],
1236 });
1237 }
1238
1239 pub fn brnz(&mut self, l: Value) {
1244 self.blocks
1245 .get_mut(self.current_block as usize).unwrap()
1246 .instructions.push(InstructionData {
1247 opcode: Opcode::BranchIfNotZero,
1248 args: vec![l],
1249 });
1250 }
1251
1252 pub fn iequal(&mut self, l: Value, r: Value) -> Value {
1258 let id = self.values.len();
1259 let v = Value(id as u32);
1260
1261 self.values.push(FunctionValue::Instruction(InstructionData {
1262 opcode: Opcode::Equal,
1263 args: vec![l, r],
1264 }));
1265
1266 v
1267 }
1268
1269 pub fn equal(&mut self, l: Value, r: Value) {
1276 self.blocks
1277 .get_mut(self.current_block as usize).unwrap()
1278 .instructions.push(InstructionData {
1279 opcode: Opcode::Equal,
1280 args: vec![l, r],
1281 });
1282 }
1283
1284 pub fn igreater(&mut self, l: Value, r: Value) -> Value {
1290 let id = self.values.len();
1291 let v = Value(id as u32);
1292
1293 self.values.push(FunctionValue::Instruction(InstructionData {
1294 opcode: Opcode::GreaterThan,
1295 args: vec![l, r],
1296 }));
1297
1298 v
1299 }
1300
1301 pub fn greater(&mut self, l: Value, r: Value) {
1308 self.blocks
1309 .get_mut(self.current_block as usize).unwrap()
1310 .instructions.push(InstructionData {
1311 opcode: Opcode::GreaterThan,
1312 args: vec![l, r],
1313 });
1314 }
1315
1316 pub fn iless(&mut self, l: Value, r: Value) -> Value {
1322 let id = self.values.len();
1323 let v = Value(id as u32);
1324
1325 self.values.push(FunctionValue::Instruction(InstructionData {
1326 opcode: Opcode::LessThan,
1327 args: vec![l, r],
1328 }));
1329
1330 v
1331 }
1332
1333 pub fn less(&mut self, l: Value, r: Value) {
1340 self.blocks
1341 .get_mut(self.current_block as usize).unwrap()
1342 .instructions.push(InstructionData {
1343 opcode: Opcode::LessThan,
1344 args: vec![l, r],
1345 });
1346 }
1347
1348 pub fn igreater_or_equal(&mut self, l: Value, r: Value) -> Value {
1354 let id = self.values.len();
1355 let v = Value(id as u32);
1356
1357 self.values.push(FunctionValue::Instruction(InstructionData {
1358 opcode: Opcode::GreaterThanOrEqual,
1359 args: vec![l, r],
1360 }));
1361
1362 v
1363 }
1364
1365 pub fn greater_or_eqal(&mut self, l: Value, r: Value) {
1372 self.blocks
1373 .get_mut(self.current_block as usize).unwrap()
1374 .instructions.push(InstructionData {
1375 opcode: Opcode::GreaterThanOrEqual,
1376 args: vec![l, r],
1377 });
1378 }
1379
1380 pub fn iless_or_equal(&mut self, l: Value, r: Value) -> Value {
1386 let id = self.values.len();
1387 let v = Value(id as u32);
1388
1389 self.values.push(FunctionValue::Instruction(InstructionData {
1390 opcode: Opcode::LessThanOrEqual,
1391 args: vec![l, r],
1392 }));
1393
1394 v
1395 }
1396
1397 pub fn less_or_equal(&mut self, l: Value, r: Value) {
1404 self.blocks
1405 .get_mut(self.current_block as usize).unwrap()
1406 .instructions.push(InstructionData {
1407 opcode: Opcode::LessThanOrEqual,
1408 args: vec![l, r],
1409 });
1410 }
1411
1412 pub fn call(&mut self, name: String, args: &[Value]) {
1418 let id = self.values.len();
1419 let v = Value(id as u32);
1420
1421 let sym = FunctionValue::Symbol(name);
1422 self.values.push(sym);
1423
1424 let mut a = args.to_vec();
1425 a.push(v);
1426
1427 self.blocks
1428 .get_mut(self.current_block as usize).unwrap()
1429 .instructions.push(InstructionData {
1430 opcode: Opcode::Call,
1431 args: a,
1432 });
1433 }
1434
1435 pub fn return_(&mut self, args: &[Value]) {
1440 self.blocks
1441 .get_mut(self.current_block as usize).unwrap()
1442 .instructions.push(InstructionData {
1443 opcode: Opcode::Return,
1444 args: args.to_vec(),
1445 });
1446 }
1447
1448}