Refactor guard construction

This commit is contained in:
d0cd 2022-10-25 15:21:43 -07:00
parent ebd06d292a
commit 52ff7b82c5
2 changed files with 30 additions and 32 deletions

View File

@ -17,9 +17,9 @@
use crate::Flattener;
use leo_ast::{
AssignStatement, BinaryExpression, BinaryOperation, Block, ConditionalStatement, DefinitionStatement, Expression,
ExpressionReconstructor, FinalizeStatement, IterationStatement, Node, ReturnStatement, Statement,
StatementReconstructor, UnaryExpression, UnaryOperation,
AssignStatement, Block, ConditionalStatement, ConsoleStatement,
DefinitionStatement, Expression, ExpressionReconstructor, FinalizeStatement, IterationStatement, Node,
ReturnStatement, Statement, StatementReconstructor, UnaryExpression, UnaryOperation,
};
impl StatementReconstructor for Flattener<'_> {
@ -110,6 +110,11 @@ impl StatementReconstructor for Flattener<'_> {
(Statement::dummy(Default::default()), statements)
}
/// Rewrites a console statement into a flattened form.
fn reconstruct_console(&mut self, input: ConsoleStatement) -> (Statement, Self::AdditionalOutput) {
todo!()
}
/// Static single assignment converts definition statements into assignment statements.
fn reconstruct_definition(&mut self, _definition: DefinitionStatement) -> (Statement, Self::AdditionalOutput) {
unreachable!("`DefinitionStatement`s should not exist in the AST at this phase of compilation.")
@ -119,20 +124,7 @@ impl StatementReconstructor for Flattener<'_> {
/// Stores the arguments to the finalize statement, which are later folded into a single finalize statement at the end of the function.
fn reconstruct_finalize(&mut self, input: FinalizeStatement) -> (Statement, Self::AdditionalOutput) {
// Construct the associated guard.
let guard = match self.condition_stack.is_empty() {
true => None,
false => {
let (first, rest) = self.condition_stack.split_first().unwrap();
Some(rest.iter().cloned().fold(first.clone(), |acc, condition| {
Expression::Binary(BinaryExpression {
op: BinaryOperation::And,
left: Box::new(acc),
right: Box::new(condition),
span: Default::default(),
})
}))
}
};
let guard = self.construct_guard();
// For each finalize argument, add it and its associated guard to the appropriate list of finalize arguments.
// Note that type checking guarantees that the number of arguments in a finalize statement is equal to the number of arguments in to the finalize block.
@ -153,20 +145,7 @@ impl StatementReconstructor for Flattener<'_> {
/// Stores the arguments to the return statement, which are later folded into a single return statement at the end of the function.
fn reconstruct_return(&mut self, input: ReturnStatement) -> (Statement, Self::AdditionalOutput) {
// Construct the associated guard.
let guard = match self.condition_stack.is_empty() {
true => None,
false => {
let (first, rest) = self.condition_stack.split_first().unwrap();
Some(rest.iter().cloned().fold(first.clone(), |acc, condition| {
Expression::Binary(BinaryExpression {
op: BinaryOperation::And,
left: Box::new(acc),
right: Box::new(condition),
span: Default::default(),
})
}))
}
};
let guard = self.construct_guard();
// Add it to the list of return statements.
self.returns.push((guard, input.expression));

View File

@ -17,7 +17,8 @@
use crate::{Assigner, SymbolTable};
use leo_ast::{
AccessExpression, Expression, ExpressionReconstructor, Identifier, Member, Statement, TernaryExpression, Type,
AccessExpression, BinaryExpression, BinaryOperation, Expression, ExpressionReconstructor, Identifier, Member,
Statement, TernaryExpression, Type,
};
use leo_span::Symbol;
@ -174,4 +175,22 @@ impl<'a> Flattener<'a> {
self.update_structs(&lhs, &rhs);
self.assigner.simple_assign_statement(lhs, rhs)
}
/// Constructs a conjunction of all the conditions in the stack.
pub(crate) fn construct_guard(&self) -> Option<Expression> {
match self.condition_stack.is_empty() {
true => None,
false => {
let (first, rest) = self.condition_stack.split_first().unwrap();
Some(rest.iter().cloned().fold(first.clone(), |acc, condition| {
Expression::Binary(BinaryExpression {
op: BinaryOperation::And,
left: Box::new(acc),
right: Box::new(condition),
span: Default::default(),
})
}))
}
}
}
}