Handle cast expressions in SSA and CodeGen passes

This commit is contained in:
Pranav Gaddamadugu 2023-06-23 09:36:40 -04:00
parent 9677682580
commit c80f9c317c
2 changed files with 36 additions and 0 deletions

View File

@ -22,6 +22,7 @@ use leo_ast::{
BinaryExpression,
BinaryOperation,
CallExpression,
CastExpression,
ErrExpression,
Expression,
Identifier,
@ -50,6 +51,7 @@ impl<'a> CodeGenerator<'a> {
Expression::Access(expr) => self.visit_access(expr),
Expression::Binary(expr) => self.visit_binary(expr),
Expression::Call(expr) => self.visit_call(expr),
Expression::Cast(expr) => self.visit_cast(expr),
Expression::Struct(expr) => self.visit_struct_init(expr),
Expression::Err(expr) => self.visit_err(expr),
Expression::Identifier(expr) => self.visit_identifier(expr),
@ -127,6 +129,23 @@ impl<'a> CodeGenerator<'a> {
(destination_register, instructions)
}
fn visit_cast(&mut self, input: &'a CastExpression) -> (String, String) {
let (expression_operand, expression_instructions) = self.visit_expression(&input.expression);
let destination_register = format!("r{}", self.next_register);
let cast_instruction =
format!(" cast {expression_operand} into {destination_register} as {};\n", input.type_);
// Increment the register counter.
self.next_register += 1;
// Concatenate the instructions.
let mut instructions = expression_instructions;
instructions.push_str(&cast_instruction);
(destination_register, instructions)
}
fn visit_unary(&mut self, input: &'a UnaryExpression) -> (String, String) {
let (expression_operand, expression_instructions) = self.visit_expression(&input.receiver);

View File

@ -21,6 +21,7 @@ use leo_ast::{
AssociatedFunction,
BinaryExpression,
CallExpression,
CastExpression,
Expression,
ExpressionConsumer,
Identifier,
@ -155,6 +156,22 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
(Expression::Identifier(place), statements)
}
/// Consumes a cast expression, accumulating any statements that are generated.
fn consume_cast(&mut self, input: CastExpression) -> Self::Output {
// Reconstruct the expression being casted.
let (expression, mut statements) = self.consume_expression(*input.expression);
// Construct and accumulate a unique assignment statement storing the result of the cast expression.
let (place, statement) = self.assigner.unique_simple_assign_statement(Expression::Cast(CastExpression {
expression: Box::new(expression),
type_: input.type_,
span: input.span,
}));
statements.push(statement);
(Expression::Identifier(place), statements)
}
/// Consumes a struct initialization expression with renamed variables, accumulating any statements that are generated.
fn consume_struct_init(&mut self, input: StructExpression) -> Self::Output {
let mut statements = Vec::new();