ellie_bytecode/transpiler/types/
reference.rs

1use ellie_core::definite::types::reference::ReferenceType;
2
3use crate::{
4    instruction_table::Instructions,
5    instructions::{Instruction, Registers},
6};
7
8use super::TypeTranspiler;
9
10impl TypeTranspiler for ReferenceType {
11    fn transpile(&self, options: &mut super::TypeTranspilerOptions) {
12        self.reference.transpile(
13            options
14                .copy()
15                .set_assembler(options.assembler_mut())
16                .set_target_register(Registers::B),
17        );
18
19        options
20            .assembler_mut()
21            .instructions
22            .push(Instructions::STB(Instruction::implicit()));
23
24        let mut last_pos = options.assembler().location();
25        for (idx, chain) in self.index_chain.iter().enumerate() {
26            match chain.rtype {
27                ellie_core::definite::types::class_instance::AttributeType::Property => {
28                    match options.target_register() {
29                        Registers::A => {
30                            options.assembler_mut().instructions.push(Instructions::LDA(
31                                Instruction::absolute_property(last_pos, chain.idx),
32                            ));
33                        }
34                        Registers::B => {
35                            options.assembler_mut().instructions.push(Instructions::LDB(
36                                Instruction::absolute_property(last_pos, chain.idx),
37                            ));
38                        }
39                        Registers::C => {
40                            options.assembler_mut().instructions.push(Instructions::LDC(
41                                Instruction::absolute_property(last_pos, chain.idx),
42                            ));
43                        }
44                        Registers::X => {
45                            options.assembler_mut().instructions.push(Instructions::LDX(
46                                Instruction::absolute_property(last_pos, chain.idx),
47                            ));
48                        }
49                        Registers::Y => {
50                            options.assembler_mut().instructions.push(Instructions::LDY(
51                                Instruction::absolute_property(last_pos, chain.idx),
52                            ));
53                        }
54                    }
55                }
56                ellie_core::definite::types::class_instance::AttributeType::Method => {
57                    unreachable!("Method is handled by the function call")
58                }
59                ellie_core::definite::types::class_instance::AttributeType::Getter => {
60                    unreachable!("Getter is handled by the getter call")
61                }
62                ellie_core::definite::types::class_instance::AttributeType::Setter => todo!(),
63                ellie_core::definite::types::class_instance::AttributeType::EnumItemData => {
64                    todo!()
65                }
66                ellie_core::definite::types::class_instance::AttributeType::EnumItemNoData => {
67                    todo!()
68                }
69            }
70            if self.index_chain.len() - 1 != idx {
71                match chain.rtype {
72                    ellie_core::definite::types::class_instance::AttributeType::Property => {
73                        match options.target_register() {
74                            Registers::A => {
75                                options
76                                    .assembler_mut()
77                                    .instructions
78                                    .push(Instructions::STA(Instruction::implicit()));
79                            }
80                            Registers::B => {
81                                options
82                                    .assembler_mut()
83                                    .instructions
84                                    .push(Instructions::STB(Instruction::implicit()));
85                            }
86                            Registers::C => {
87                                options
88                                    .assembler_mut()
89                                    .instructions
90                                    .push(Instructions::STC(Instruction::implicit()));
91                            }
92                            Registers::X => {
93                                options
94                                    .assembler_mut()
95                                    .instructions
96                                    .push(Instructions::STX(Instruction::implicit()));
97                            }
98                            Registers::Y => {
99                                options
100                                    .assembler_mut()
101                                    .instructions
102                                    .push(Instructions::STY(Instruction::implicit()));
103                            }
104                        }
105                        last_pos = options.assembler().location();
106                    }
107                    ellie_core::definite::types::class_instance::AttributeType::Method => {
108                        unreachable!("Method is handled by the function call")
109                    }
110                    ellie_core::definite::types::class_instance::AttributeType::Getter => {
111                        unreachable!("Getter is handled by the getter call")
112                    }
113                    ellie_core::definite::types::class_instance::AttributeType::Setter => todo!(),
114                    ellie_core::definite::types::class_instance::AttributeType::EnumItemData => {
115                        todo!()
116                    }
117                    ellie_core::definite::types::class_instance::AttributeType::EnumItemNoData => {
118                        todo!()
119                    }
120                }
121            }
122        }
123    }
124}