Fix SSA for expr statements

This commit is contained in:
d0cd 2022-11-11 21:03:11 -08:00
parent cf9948e99c
commit 31972e1b38
2 changed files with 28 additions and 10 deletions

View File

@ -112,6 +112,7 @@ impl<'a> CodeGenerator<'a> {
} }
fn visit_expression_statement(&mut self, input: &'a ExpressionStatement) -> String { fn visit_expression_statement(&mut self, input: &'a ExpressionStatement) -> String {
println!("ExpressionStatement: {:?}", input);
match input.expression { match input.expression {
Expression::Call(_) => self.visit_expression(&input.expression).1, Expression::Call(_) => self.visit_expression(&input.expression).1,
_ => unreachable!("ExpressionStatement's can only contain CallExpression's."), _ => unreachable!("ExpressionStatement's can only contain CallExpression's."),

View File

@ -16,12 +16,7 @@
use crate::{RenameTable, StaticSingleAssigner}; use crate::{RenameTable, StaticSingleAssigner};
use leo_ast::{ use leo_ast::{AssignStatement, Block, CallExpression, ConditionalStatement, ConsoleFunction, ConsoleStatement, DecrementStatement, DefinitionStatement, Expression, ExpressionConsumer, ExpressionStatement, FinalizeStatement, Identifier, IncrementStatement, IterationStatement, ReturnStatement, Statement, StatementConsumer, TernaryExpression, TupleExpression};
AssignStatement, Block, ConditionalStatement, ConsoleFunction, ConsoleStatement, DecrementStatement,
DefinitionStatement, Expression, ExpressionConsumer, ExpressionStatement, FinalizeStatement, Identifier,
IncrementStatement, IterationStatement, ReturnStatement, Statement, StatementConsumer, TernaryExpression,
TupleExpression,
};
use leo_span::Symbol; use leo_span::Symbol;
use indexmap::IndexSet; use indexmap::IndexSet;
@ -263,12 +258,34 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
/// Consumes the expressions associated with `ExpressionStatement`, returning the simplified `ExpressionStatement`. /// Consumes the expressions associated with `ExpressionStatement`, returning the simplified `ExpressionStatement`.
fn consume_expression_statement(&mut self, input: ExpressionStatement) -> Self::Output { fn consume_expression_statement(&mut self, input: ExpressionStatement) -> Self::Output {
// Process the expression associated with the `ExpressionStatement`. let mut statements = Vec::new();
let (expression, mut statements) = self.consume_expression(input.expression);
// Add the `ExpressionStatement` to the list of produced statements. // Extract the call expression.
let call = match input.expression {
Expression::Call(call) => call,
_ => unreachable!("Type checking guarantees that expression statements are always function calls."),
};
// Process the arguments, accumulating any statements produced.
let arguments = call
.arguments
.into_iter()
.map(|argument| {
let (argument, mut stmts) = self.consume_expression(argument);
statements.append(&mut stmts);
argument
})
.collect();
// Create and accumulate the new expression statement.
// Note that we do not create a new assignment for the call expression; this is necessary for correct code generation.
statements.push(Statement::Expression(ExpressionStatement { statements.push(Statement::Expression(ExpressionStatement {
expression, expression: Expression::Call(CallExpression {
function: call.function,
arguments,
external: call.external,
span: call.span,
}),
span: input.span, span: input.span,
})); }));