Skip to content

Commit b92d86b

Browse files
committed
fn next_register in CodeGeneratingVisitor.
It's error prone to fetch and increment the next register manually each time.
1 parent e9c86d6 commit b92d86b

File tree

4 files changed

+27
-50
lines changed

4 files changed

+27
-50
lines changed

compiler/passes/src/code_generation/expression.rs

Lines changed: 18 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -134,12 +134,9 @@ impl CodeGeneratingVisitor<'_> {
134134
BinaryOperation::Xor => String::from("xor"),
135135
};
136136

137-
let destination_register = format!("r{}", self.next_register);
137+
let destination_register = self.next_register();
138138
let binary_instruction = format!(" {opcode} {left_operand} {right_operand} into {destination_register};\n",);
139139

140-
// Increment the register counter.
141-
self.next_register += 1;
142-
143140
// Concatenate the instructions.
144141
let mut instructions = left_instructions;
145142
instructions.push_str(&right_instructions);
@@ -152,9 +149,7 @@ impl CodeGeneratingVisitor<'_> {
152149
let (expression_operand, mut instructions) = self.visit_expression(&input.expression);
153150

154151
// Construct the destination register.
155-
let destination_register = format!("r{}", self.next_register);
156-
// Increment the register counter.
157-
self.next_register += 1;
152+
let destination_register = self.next_register();
158153

159154
let cast_instruction = format!(
160155
" cast {expression_operand} into {destination_register} as {};\n",
@@ -177,9 +172,7 @@ impl CodeGeneratingVisitor<'_> {
177172
}
178173

179174
// Construct the destination register.
180-
let destination_register = format!("r{}", self.next_register);
181-
// Increment the register counter.
182-
self.next_register += 1;
175+
let destination_register = self.next_register();
183176

184177
// Get the array type.
185178
let Some(array_type @ Type::Array(..)) = self.state.type_table.get(&input.id) else {
@@ -213,12 +206,9 @@ impl CodeGeneratingVisitor<'_> {
213206
UnaryOperation::ToYCoordinate => ("cast", " as group.y"),
214207
};
215208

216-
let destination_register = format!("r{}", self.next_register);
209+
let destination_register = self.next_register();
217210
let unary_instruction = format!(" {opcode} {expression_operand} into {destination_register}{suffix};\n");
218211

219-
// Increment the register counter.
220-
self.next_register += 1;
221-
222212
// Concatenate the instructions.
223213
let mut instructions = expression_instructions;
224214
instructions.push_str(&unary_instruction);
@@ -231,14 +221,11 @@ impl CodeGeneratingVisitor<'_> {
231221
let (if_true_operand, if_true_instructions) = self.visit_expression(&input.if_true);
232222
let (if_false_operand, if_false_instructions) = self.visit_expression(&input.if_false);
233223

234-
let destination_register = format!("r{}", self.next_register);
224+
let destination_register = self.next_register();
235225
let ternary_instruction = format!(
236226
" ternary {condition_operand} {if_true_operand} {if_false_operand} into {destination_register};\n",
237227
);
238228

239-
// Increment the register counter.
240-
self.next_register += 1;
241-
242229
// Concatenate the instructions.
243230
let mut instructions = condition_instructions;
244231
instructions.push_str(&if_true_instructions);
@@ -287,15 +274,12 @@ impl CodeGeneratingVisitor<'_> {
287274
}
288275

289276
// Push destination register to struct init instruction.
290-
let destination_register = format!("r{}", self.next_register);
277+
let destination_register = self.next_register();
291278
writeln!(struct_init_instruction, "into {destination_register} as {name};",)
292279
.expect("failed to write to string");
293280

294281
instructions.push_str(&struct_init_instruction);
295282

296-
// Increment the register counter.
297-
self.next_register += 1;
298-
299283
(destination_register, instructions)
300284
}
301285

@@ -339,13 +323,6 @@ impl CodeGeneratingVisitor<'_> {
339323
})
340324
.collect::<Vec<_>>();
341325

342-
// Helper function to get a destination register for a function call.
343-
let mut get_destination_register = || {
344-
let destination_register = format!("r{}", self.next_register);
345-
self.next_register += 1;
346-
destination_register
347-
};
348-
349326
// Helper function to construct the instruction associated with a simple function call.
350327
// This assumes that the function call has one output.
351328
let mut construct_simple_function_call = |function: &Identifier, variant: &str, arguments: Vec<String>| {
@@ -359,7 +336,7 @@ impl CodeGeneratingVisitor<'_> {
359336
for argument in arguments {
360337
write!(instruction, " {argument}").expect("failed to write to string");
361338
}
362-
let destination_register = get_destination_register();
339+
let destination_register = self.next_register();
363340
writeln!(instruction, " into {destination_register} as {return_type};").expect("failed to write to string");
364341
(destination_register, instruction)
365342
};
@@ -384,15 +361,15 @@ impl CodeGeneratingVisitor<'_> {
384361
sym::Mapping => match input.name.name {
385362
sym::get => {
386363
let mut instruction = " get".to_string();
387-
let destination_register = get_destination_register();
364+
let destination_register = self.next_register();
388365
// Write the mapping name and the key.
389366
writeln!(instruction, " {}[{}] into {destination_register};", arguments[0], arguments[1])
390367
.expect("failed to write to string");
391368
(destination_register, instruction)
392369
}
393370
sym::get_or_use => {
394371
let mut instruction = " get.or_use".to_string();
395-
let destination_register = get_destination_register();
372+
let destination_register = self.next_register();
396373
// Write the mapping name, the key, and the default value.
397374
writeln!(
398375
instruction,
@@ -417,7 +394,7 @@ impl CodeGeneratingVisitor<'_> {
417394
}
418395
sym::contains => {
419396
let mut instruction = " contains".to_string();
420-
let destination_register = get_destination_register();
397+
let destination_register = self.next_register();
421398
// Write the mapping name and the key.
422399
writeln!(instruction, " {}[{}] into {destination_register};", arguments[0], arguments[1])
423400
.expect("failed to write to string");
@@ -429,15 +406,15 @@ impl CodeGeneratingVisitor<'_> {
429406
match input.name {
430407
Identifier { name: sym::to_x_coordinate, .. } => {
431408
let mut instruction = " cast".to_string();
432-
let destination_register = get_destination_register();
409+
let destination_register = self.next_register();
433410
// Write the argument and the destination register.
434411
writeln!(instruction, " {} into {destination_register} as group.x;", arguments[0],)
435412
.expect("failed to write to string");
436413
(destination_register, instruction)
437414
}
438415
Identifier { name: sym::to_y_coordinate, .. } => {
439416
let mut instruction = " cast".to_string();
440-
let destination_register = get_destination_register();
417+
let destination_register = self.next_register();
441418
// Write the argument and the destination register.
442419
writeln!(instruction, " {} into {destination_register} as group.y;", arguments[0],)
443420
.expect("failed to write to string");
@@ -448,7 +425,7 @@ impl CodeGeneratingVisitor<'_> {
448425
}
449426
sym::ChaCha => {
450427
// Get the destination register.
451-
let destination_register = get_destination_register();
428+
let destination_register = self.next_register();
452429
// Construct the instruction template.
453430
let mut instruction = format!(" rand.chacha into {destination_register} as ");
454431
// Write the return type.
@@ -475,7 +452,7 @@ impl CodeGeneratingVisitor<'_> {
475452
}
476453
sym::signature => {
477454
let mut instruction = " sign.verify".to_string();
478-
let destination_register = get_destination_register();
455+
let destination_register = self.next_register();
479456
// Write the arguments and the destination register.
480457
writeln!(
481458
instruction,
@@ -552,24 +529,18 @@ impl CodeGeneratingVisitor<'_> {
552529
0 | 1 => panic!("Parsing guarantees that a tuple type has at least two elements"),
553530
len => {
554531
for _ in 0..len {
555-
let destination_register = format!("r{}", self.next_register);
556-
destinations.push(destination_register);
557-
self.next_register += 1;
532+
destinations.push(self.next_register());
558533
}
559534
}
560535
},
561536
_ => {
562-
let destination_register = format!("r{}", self.next_register);
563-
destinations.push(destination_register);
564-
self.next_register += 1;
537+
destinations.push(self.next_register());
565538
}
566539
}
567540

568541
// Add a register for async functions to represent the future created.
569542
if func_symbol.function.variant == Variant::AsyncFunction {
570-
let destination_register = format!("r{}", self.next_register);
571-
destinations.push(destination_register);
572-
self.next_register += 1;
543+
destinations.push(self.next_register());
573544
}
574545

575546
// Construct the output operands. These are the destination registers **without** the future.
@@ -615,8 +586,7 @@ impl CodeGeneratingVisitor<'_> {
615586
}
616587

617588
pub fn clone_register(&mut self, register: &str, typ: &Type) -> (String, String) {
618-
let new_reg = format!("r{}", self.next_register);
619-
self.next_register += 1;
589+
let new_reg = self.next_register();
620590
match typ {
621591
Type::Address
622592
| Type::Boolean

compiler/passes/src/code_generation/program.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,7 @@ impl<'a> CodeGeneratingVisitor<'a> {
185185

186186
// Construct and append the input declarations of the function.
187187
for input in function.input.iter() {
188-
let register_string = format!("r{}", self.next_register);
189-
self.next_register += 1;
188+
let register_string = self.next_register();
190189

191190
// Track all internal record inputs.
192191
if let Type::Composite(comp) = &input.type_ {

compiler/passes/src/code_generation/visitor.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,10 @@ pub struct CodeGeneratingVisitor<'a> {
5151
/// This is necessary as if we output them, we need to clone them.
5252
pub internal_record_inputs: IndexSet<String>,
5353
}
54+
55+
impl CodeGeneratingVisitor<'_> {
56+
pub fn next_register(&mut self) -> String {
57+
self.next_register += 1;
58+
format!("r{}", self.next_register - 1)
59+
}
60+
}

errors/src/errors/type_checker/type_checker_error.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,7 @@ create_messages!(
10311031
msg: format!("Invalid annotation: {message}."),
10321032
help: None,
10331033
}
1034+
10341035
@formatted
10351036
ternary_over_external_records {
10361037
args: (ty: impl Display),

0 commit comments

Comments
 (0)