codegen_instruction_builder/
codegen_instruction_builder.rs

1use c64_assembler_6502::{
2    isa_6502,
3    opcodes::{
4        NO_ABSOLUTE, NO_ABSOLUTE_X, NO_ABSOLUTE_Y, NO_ACCUMULATOR, NO_IMMEDIATE, NO_IMPLIED, NO_INDEXED_INDIRECT,
5        NO_INDIRECT, NO_INDIRECT_INDEXED, NO_RELATIVE, NO_ZEROPAGE, NO_ZEROPAGE_X, NO_ZEROPAGE_Y,
6    },
7};
8
9fn main() {
10    let mut lines = Vec::<String>::default();
11
12    for def in isa_6502() {
13        if def.implied != NO_IMPLIED {
14            lines.push(format!(
15                "
16                /// Record a new {0} instruction (addressing mode is implied).
17                /// 
18                /// # Example
19                /// ```
20                /// use c64_assembler::builder::InstructionBuilder;
21                /// let instructions = InstructionBuilder::default()
22                ///     .{0}()
23                ///     .build();
24                /// ```
25                pub fn {0}(&mut self) -> &mut Self {{
26                    self.add_instruction(Operation::{1}, AddressMode::Implied);
27                    self
28                }}",
29                def.instruction.to_string(),
30                def.instruction.to_uppercase()
31            ));
32        } else {
33            lines.push(format!(
34                "
35                /// Record a new {0} instruction with the given addressing mode.
36                fn {0}(&mut self, addressing_mode: AddressMode) -> &mut Self {{
37                    self.add_instruction(Operation::{1}, addressing_mode);
38                    self
39                }}
40                ",
41                def.instruction.to_string(),
42                def.instruction.to_uppercase()
43            ));
44        }
45        if def.immediate != NO_IMMEDIATE {
46            lines.push(format!(
47                "
48                /// Record a {0} instruction with data (byte).
49                /// # Example
50                /// ```
51                /// use c64_assembler::builder::InstructionBuilder;
52                /// let instructions = InstructionBuilder::default()
53                ///     .{0}_imm(0xC0)
54                ///     .build();
55                /// ```
56                pub fn {0}_imm(&mut self, byte: u8) -> &mut Self {{
57                    self.{0}(AddressMode::Immediate(Immediate::Byte(byte)))
58                }}
59
60                /// Record a {0} instruction with lower byte of an address.
61                /// 
62                /// # Example
63                /// ```
64                /// use c64_assembler::builder::InstructionBuilder;
65                /// let instructions = InstructionBuilder::default()
66                ///     .{0}_imm_low(\"test_data\")
67                ///     .label(\"test_data\")
68                ///     .build();
69                /// ```
70                pub fn {0}_imm_low(&mut self, address_name: &str) -> &mut Self {{
71                    self.{0}(AddressMode::Immediate(Immediate::Low(
72                        AddressReference::new(address_name)
73                    )))
74                }}
75
76                /// Record a {0} instruction with higher byte of an address.
77                /// 
78                /// # Example
79                /// ```
80                /// use c64_assembler::builder::InstructionBuilder;
81                /// let instructions = InstructionBuilder::default()
82                ///     .{0}_imm_high(\"test_data\")
83                ///     .label(\"test_data\")
84                ///     .build();
85                /// ```
86                pub fn {0}_imm_high(&mut self, address_name: &str) -> &mut Self {{
87                    self.{0}(AddressMode::Immediate(Immediate::High(
88                        AddressReference::new(address_name)
89                    )))
90                }}
91                ",
92                def.instruction.to_string()
93            ));
94        }
95        if def.accumulator != NO_ACCUMULATOR {
96            lines.push(format!(
97                "
98                /// Record a {0} instruction that uses accumulator as address mode.
99                /// 
100                /// # Example
101                /// ```
102                /// use c64_assembler::builder::InstructionBuilder;
103                /// let instructions = InstructionBuilder::default()
104                ///     .{0}_acc()
105                ///     .build();
106                /// ```
107                pub fn {0}_acc(&mut self) -> &mut Self {{
108                    self.{0}(AddressMode::Accumulator)
109                }}
110                ",
111                def.instruction.to_string()
112            ));
113        }
114
115        if def.absolute != NO_ABSOLUTE || def.zeropage != NO_ZEROPAGE {
116            lines.push(format!(
117                "
118                /// Record a {0} instruction that use an absolute address. 
119                /// 
120                /// # Example
121                /// ```
122                /// use c64_assembler::builder::InstructionBuilder;
123                /// let instructions = InstructionBuilder::default()
124                ///     .{0}_addr(\"test_label\")
125                ///     .label(\"test_label\")
126                ///     .build();
127                /// ```
128                pub fn {0}_addr(&mut self, address_name: &str) -> &mut Self {{
129                    self.{0}(AddressMode::Absolute(AddressReference::new(address_name)))
130                }}
131        
132                /// Record a {0} instruction that use an absolute address with an offset.
133                /// Offset is in bytes.
134                /// 
135                /// # Example
136                /// ```
137                /// use c64_assembler::builder::InstructionBuilder;
138                /// let instructions = InstructionBuilder::default()
139                ///     .{0}_addr_offs(\"test_label\", 8)
140                ///     .label(\"test_label\")
141                ///     .build();
142                /// ```
143                pub fn {0}_addr_offs(&mut self, address_name: &str, offset: Address) -> &mut Self {{
144                    self.{0}(AddressMode::Absolute(AddressReference::with_offset(
145                        address_name, offset
146                    )))
147                }}
148                ",
149                def.instruction.to_string()
150            ));
151        }
152        if def.absolute_x != NO_ABSOLUTE_X || def.zeropage_x != NO_ZEROPAGE_X {
153            lines.push(format!(
154                "
155                /// Record a {0} instructon that use an absolute address with x-register as indexer.
156                /// 
157                /// # Example
158                /// ```
159                /// use c64_assembler::builder::InstructionBuilder;
160                /// let instructions = InstructionBuilder::default()
161                ///     .ldx_imm(0x08)
162                ///     .{0}_addr_x(\"test_label\")
163                ///     .label(\"test_label\")
164                ///     .build();
165                /// ```
166                pub fn {0}_addr_x(&mut self, address_name: &str) -> &mut Self {{
167                    self.{0}(AddressMode::AbsoluteX(AddressReference::new(address_name)))
168                }}
169                ",
170                def.instruction.to_string()
171            ));
172        }
173        if def.absolute_y != NO_ABSOLUTE_Y || def.zeropage_y != NO_ZEROPAGE_Y {
174            lines.push(format!(
175                "
176                /// Record a {0} instructon that use an absolute address with y-register as indexer.
177                /// 
178                /// # Example
179                /// ```
180                /// use c64_assembler::builder::InstructionBuilder;
181                /// let instructions = InstructionBuilder::default()
182                ///     .ldy_imm(0x08)
183                ///     .{0}_addr_y(\"test_label\")
184                ///     .label(\"test_label\")
185                ///     .build();
186                /// ```
187                pub fn {0}_addr_y(&mut self, address_name: &str) -> &mut Self {{
188                    self.{0}(AddressMode::AbsoluteY(AddressReference::new(address_name)))
189                }}
190                ",
191                def.instruction.to_string()
192            ));
193        }
194        if def.relative != NO_RELATIVE {
195            lines.push(format!(
196                "
197                /// Record a {0} instruction that use  relativeeeeeeeee address. 
198                /// 
199                /// # Example
200                /// ```
201                /// use c64_assembler::builder::InstructionBuilder;
202                /// let instructions = InstructionBuilder::default()
203                ///     .{0}_addr(\"test_label\")
204                ///     .label(\"test_label\")
205                ///     .build();
206                /// ```
207                pub fn {0}_addr(&mut self, address_name: &str) -> &mut Self {{
208                    self.{0}(AddressMode::Relative(AddressReference::new(address_name)))
209                }}
210        
211                /// Record a {0} instruction that use a relative address with an offset.
212                /// Offset is in bytes.
213                /// 
214                /// # Example
215                /// ```
216                /// use c64_assembler::builder::InstructionBuilder;
217                /// let instructions = InstructionBuilder::default()
218                ///     .{0}_addr_offs(\"test_label\", 8)
219                ///     .label(\"test_label\")
220                ///     .build();
221                /// ```
222                pub fn {0}_addr_offs(&mut self, address_name: &str, offset: Address) -> &mut Self {{
223                    self.{0}(AddressMode::Relative(AddressReference::with_offset(
224                        address_name, offset
225                    )))
226                }}
227                ",
228                def.instruction.to_string()
229            ));
230        }
231        if def.indirect != NO_INDIRECT {
232            lines.push(format!(
233                "
234                /// Record a {0} instruction that uses indirect addressing mode.
235                /// 
236                /// # Example
237                /// ```
238                /// use c64_assembler::builder::InstructionBuilder;
239                /// let instructions = InstructionBuilder::default()
240                ///     .{0}_ind(\"test_label\")
241                ///     .label(\"test_label\")
242                ///     .build();
243                /// ```
244                pub fn {0}_ind(&mut self, address_name: &str) -> &mut Self {{
245                    self.{0}(AddressMode::Indirect(AddressReference::new(address_name)))
246                }}
247                ",
248                def.instruction.to_string()
249            ));
250        }
251        if def.indexed_indirect != NO_INDEXED_INDIRECT {
252            lines.push(format!(
253                "
254                /// Record a {0} instruction that uses indexed indirect addressing mode.
255                /// 
256                /// # Example
257                /// ```
258                /// use c64_assembler::builder::InstructionBuilder;
259                /// let instructions = InstructionBuilder::default()
260                ///     .ldx_imm(0x08)
261                ///     .{0}_ind_x(\"test_label\")
262                ///     .label(\"test_label\")
263                ///     .build();
264                /// ```
265                pub fn {0}_ind_x(&mut self, address_name: &str) -> &mut Self {{
266                    self.{0}(AddressMode::IndexedIndirect(AddressReference::new(address_name)))
267                }}
268                ",
269                def.instruction.to_string()
270            ));
271        }
272        if def.indirect_indexed != NO_INDIRECT_INDEXED {
273            lines.push(format!(
274                "
275                /// Record a {0} instruction that uses indirect indexed addressing mode.
276                /// 
277                /// # Example
278                /// ```
279                /// use c64_assembler::builder::InstructionBuilder;
280                /// let instructions = InstructionBuilder::default()
281                ///     .ldy_imm(0x08)
282                ///     .{0}_ind_y(\"test_label\")
283                ///     .label(\"test_label\")
284                ///     .build();
285                /// ```
286                pub fn {0}_ind_y(&mut self, address_name: &str) -> &mut Self {{
287                    self.{0}(AddressMode::IndirectIndexed(AddressReference::new(address_name)))
288                }}
289                ",
290                def.instruction.to_string()
291            ));
292        }
293    }
294
295    print!("{}", lines.join("\n"));
296}