mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-27 04:01:47 +03:00
Cleanup
This commit is contained in:
parent
a2795baed8
commit
a39ab9f77f
@ -15,7 +15,7 @@
|
|||||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//! This module contains a Consumer trait for the AST.
|
//! This module contains a Consumer trait for the AST.
|
||||||
//! Consumers are used to completely transform the AST without any opinion on the output.
|
//! Consumers are used to completely transform the AST without any restrictions on the output.
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
//! This module contains both a Reducer and Visitor design pattern.
|
//! This module contains both a Reducer and Visitor design pattern.
|
||||||
//! These both iterate over the AST.
|
//! These both iterate over the AST.
|
||||||
|
|
||||||
// todo @gluax: Move the files in this module into `leo-passes` in a future PR.
|
// TODO: Move the files in this module into `leo-passes` in a future PR.
|
||||||
|
|
||||||
pub mod consumer;
|
pub mod consumer;
|
||||||
pub use consumer::*;
|
pub use consumer::*;
|
||||||
|
@ -45,7 +45,6 @@ impl<'a> CodeGenerator<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn visit_identifier(&mut self, input: &'a Identifier) -> (String, String) {
|
fn visit_identifier(&mut self, input: &'a Identifier) -> (String, String) {
|
||||||
println!("{:?}", input);
|
|
||||||
(self.variable_mapping.get(&input.name).unwrap().clone(), String::new())
|
(self.variable_mapping.get(&input.name).unwrap().clone(), String::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
//! See https://en.wikipedia.org/wiki/Static_single-assignment_form for more information.
|
//! See https://en.wikipedia.org/wiki/Static_single-assignment_form for more information.
|
||||||
//! The pass also flattens `ConditionalStatement`s into a sequence of `AssignStatement`s.
|
//! The pass also flattens `ConditionalStatement`s into a sequence of `AssignStatement`s.
|
||||||
//! The pass also rewrites `ReturnStatement`s into `AssignStatement`s and consolidates the returned values as a single `ReturnStatement` at the end of the function.
|
//! The pass also rewrites `ReturnStatement`s into `AssignStatement`s and consolidates the returned values as a single `ReturnStatement` at the end of the function.
|
||||||
//! The pass also simplifies complex expressions into a sequence of `AssignStatement`s. For example, `(a + b) * c` is rewritten into `expr$1 = a + b; expr$2 = expr$1 * c`.
|
//! The pass also simplifies complex expressions into a sequence of `AssignStatement`s. For example, `(a + b) * c` is rewritten into `$var$1 = a + b; $var$2 = $var$1 * c`.
|
||||||
//!
|
//!
|
||||||
//! Consider the following Leo code.
|
//! Consider the following Leo code.
|
||||||
//! ```leo
|
//! ```leo
|
||||||
@ -71,8 +71,6 @@ impl<'a> Pass for StaticSingleAssigner<'a> {
|
|||||||
let program = consumer.consume_program(ast.into_repr());
|
let program = consumer.consume_program(ast.into_repr());
|
||||||
handler.last_err()?;
|
handler.last_err()?;
|
||||||
|
|
||||||
println!("AST AFTER SSA:\n{}", program);
|
|
||||||
|
|
||||||
Ok(Ast::new(program))
|
Ok(Ast::new(program))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
|
|||||||
// In this case, we must consume the expression.
|
// In this case, we must consume the expression.
|
||||||
true => self.consume_expression(arg.expression.unwrap()),
|
true => self.consume_expression(arg.expression.unwrap()),
|
||||||
};
|
};
|
||||||
// Add the output to the additional output.
|
// Accumulate any statements produced.
|
||||||
statements.append(&mut stmts);
|
statements.append(&mut stmts);
|
||||||
|
|
||||||
// Return the new member.
|
// Return the new member.
|
||||||
@ -244,8 +244,8 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// Note that we do not construct new assignment statement for the tuple expression, since tuple expressions are not supported.
|
|
||||||
// TODO: Fix when tuple expressions are supported.
|
// TODO: Fix when tuple expressions are supported.
|
||||||
|
// Note that we do not construct new assignment statement for the tuple expression, since tuple expressions are not supported.
|
||||||
(
|
(
|
||||||
Expression::Tuple(TupleExpression {
|
Expression::Tuple(TupleExpression {
|
||||||
elements,
|
elements,
|
||||||
|
@ -46,8 +46,26 @@ impl FunctionConsumer for StaticSingleAssigner<'_> {
|
|||||||
let (_, last_return_expression) = returns.pop().unwrap();
|
let (_, last_return_expression) = returns.pop().unwrap();
|
||||||
|
|
||||||
// Produce a chain of ternary expressions and assignments for the set of early returns.
|
// Produce a chain of ternary expressions and assignments for the set of early returns.
|
||||||
// TODO: Can this be simplified?
|
|
||||||
let mut stmts = Vec::with_capacity(returns.len());
|
let mut stmts = Vec::with_capacity(returns.len());
|
||||||
|
|
||||||
|
// Helper to construct and store ternary assignments. e.g `$ret$0 = $var$0 ? $var$1 : $var$2`
|
||||||
|
let mut construct_ternary_assignment = |guard: Expression, if_true: Expression, if_false: Expression| {
|
||||||
|
let place = Expression::Identifier(Identifier {
|
||||||
|
name: self.unique_symbol("$ret"),
|
||||||
|
span: Default::default(),
|
||||||
|
});
|
||||||
|
stmts.push(Self::simple_assign_statement(
|
||||||
|
place.clone(),
|
||||||
|
Expression::Ternary(TernaryExpression {
|
||||||
|
condition: Box::new(guard),
|
||||||
|
if_true: Box::new(if_true),
|
||||||
|
if_false: Box::new(if_false),
|
||||||
|
span: Default::default(),
|
||||||
|
}),
|
||||||
|
));
|
||||||
|
place
|
||||||
|
};
|
||||||
|
|
||||||
let expression = returns
|
let expression = returns
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.rev()
|
.rev()
|
||||||
@ -64,19 +82,7 @@ impl FunctionConsumer for StaticSingleAssigner<'_> {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.zip_eq(acc_tuple.elements.into_iter())
|
.zip_eq(acc_tuple.elements.into_iter())
|
||||||
.map(|(if_true, if_false)| {
|
.map(|(if_true, if_false)| {
|
||||||
// Create an assignment statement for the element expression in the tuple.
|
construct_ternary_assignment(guard.clone(), if_true, if_false)
|
||||||
let place = Expression::Identifier(Identifier {
|
|
||||||
name: self.unique_symbol("$ret"),
|
|
||||||
span: Default::default(),
|
|
||||||
});
|
|
||||||
let value = Expression::Ternary(TernaryExpression {
|
|
||||||
condition: Box::new(guard.clone()),
|
|
||||||
if_true: Box::new(if_true),
|
|
||||||
if_false: Box::new(if_false),
|
|
||||||
span: Default::default(),
|
|
||||||
});
|
|
||||||
stmts.push(Self::simple_assign_statement(place.clone(), value));
|
|
||||||
place
|
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
span: Default::default(),
|
span: Default::default(),
|
||||||
@ -84,26 +90,12 @@ impl FunctionConsumer for StaticSingleAssigner<'_> {
|
|||||||
}
|
}
|
||||||
// Otherwise, fold the return expressions into a single ternary expression.
|
// Otherwise, fold the return expressions into a single ternary expression.
|
||||||
// Note that `expr` and `acc` are correspond to the `if` and `else` cases of the ternary expression respectively.
|
// Note that `expr` and `acc` are correspond to the `if` and `else` cases of the ternary expression respectively.
|
||||||
(expr, acc) => {
|
(expr, acc) => construct_ternary_assignment(guard, expr, acc),
|
||||||
let place = Expression::Identifier(Identifier {
|
|
||||||
name: self.unique_symbol("$ret"),
|
|
||||||
span: Default::default(),
|
|
||||||
});
|
|
||||||
let value = Expression::Ternary(TernaryExpression {
|
|
||||||
condition: Box::new(guard),
|
|
||||||
if_true: Box::new(expr),
|
|
||||||
if_false: Box::new(acc),
|
|
||||||
span: Default::default(),
|
|
||||||
});
|
|
||||||
stmts.push(Self::simple_assign_statement(place.clone(), value));
|
|
||||||
place
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
println!("1");
|
// Add all of the accumulated statements to the end of the block.
|
||||||
statements.extend(stmts);
|
statements.extend(stmts);
|
||||||
println!("2");
|
|
||||||
|
|
||||||
// Add the `ReturnStatement` to the end of the block.
|
// Add the `ReturnStatement` to the end of the block.
|
||||||
statements.push(Statement::Return(ReturnStatement {
|
statements.push(Statement::Return(ReturnStatement {
|
||||||
@ -137,7 +129,7 @@ impl ProgramConsumer for StaticSingleAssigner<'_> {
|
|||||||
name: input.name,
|
name: input.name,
|
||||||
network: input.network,
|
network: input.network,
|
||||||
expected_input: input.expected_input,
|
expected_input: input.expected_input,
|
||||||
// TODO: Do inputs need to be processed?
|
// TODO: Do inputs need to be processed? They are not processed in the existing compiler.
|
||||||
imports: input.imports,
|
imports: input.imports,
|
||||||
functions: input
|
functions: input
|
||||||
.functions
|
.functions
|
||||||
|
@ -59,8 +59,11 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
|
|||||||
|
|
||||||
/// Consumes the `DefinitionStatement` into an `AssignStatement`, renaming the left-hand-side as appropriate.
|
/// Consumes the `DefinitionStatement` into an `AssignStatement`, renaming the left-hand-side as appropriate.
|
||||||
fn consume_definition(&mut self, definition: DefinitionStatement) -> Self::Output {
|
fn consume_definition(&mut self, definition: DefinitionStatement) -> Self::Output {
|
||||||
|
// First consume the right-hand-side of the definition.
|
||||||
let (value, mut statements) = self.consume_expression(definition.value);
|
let (value, mut statements) = self.consume_expression(definition.value);
|
||||||
|
|
||||||
|
// Then assign a new unique name to the left-hand-side of the definition.
|
||||||
|
// Note that this order is necessary to ensure that the right-hand-side uses the correct name when consuming a complex assignment.
|
||||||
self.is_lhs = true;
|
self.is_lhs = true;
|
||||||
let identifier = match self.consume_identifier(definition.variable_name).0 {
|
let identifier = match self.consume_identifier(definition.variable_name).0 {
|
||||||
Expression::Identifier(identifier) => identifier,
|
Expression::Identifier(identifier) => identifier,
|
||||||
@ -99,11 +102,6 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
|
|||||||
fn consume_conditional(&mut self, conditional: ConditionalStatement) -> Self::Output {
|
fn consume_conditional(&mut self, conditional: ConditionalStatement) -> Self::Output {
|
||||||
// Simplify the condition and add it into the rename table.
|
// Simplify the condition and add it into the rename table.
|
||||||
let (condition, mut statements) = self.consume_expression(conditional.condition);
|
let (condition, mut statements) = self.consume_expression(conditional.condition);
|
||||||
// TODO: Is this needed?
|
|
||||||
println!("Condition:\n{:?}\n", condition);
|
|
||||||
println!("Statements:\n{:?}\n", statements);
|
|
||||||
println!("Rename Table:\n{:?}\n", self.rename_table);
|
|
||||||
// self.rename_table.update(symbol, symbol);
|
|
||||||
|
|
||||||
// Instantiate a `RenameTable` for the then-block.
|
// Instantiate a `RenameTable` for the then-block.
|
||||||
self.push();
|
self.push();
|
||||||
@ -132,18 +130,7 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
|
|||||||
span: condition.span(),
|
span: condition.span(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
statements.extend(match *statement {
|
statements.extend(self.consume_statement(*statement));
|
||||||
// TODO: Check that the statement below still holds.
|
|
||||||
// The `ConditionalStatement` must be consumed as a `Block` statement to ensure that appropriate statements are produced.
|
|
||||||
Statement::Conditional(stmt) => self.consume_block(Block {
|
|
||||||
statements: vec![Statement::Conditional(stmt)],
|
|
||||||
span: Default::default(),
|
|
||||||
}),
|
|
||||||
Statement::Block(stmt) => self.consume_block(stmt),
|
|
||||||
_ => unreachable!(
|
|
||||||
"`ConditionalStatement`s next statement must be a `ConditionalStatement` or a `Block`."
|
|
||||||
),
|
|
||||||
});
|
|
||||||
|
|
||||||
// Remove the negated condition from the condition stack.
|
// Remove the negated condition from the condition stack.
|
||||||
self.condition_stack.pop();
|
self.condition_stack.pop();
|
||||||
@ -192,7 +179,7 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
|
|||||||
// Update the `RenameTable` with the new name of the variable.
|
// Update the `RenameTable` with the new name of the variable.
|
||||||
self.rename_table.update(*(*symbol), new_name);
|
self.rename_table.update(*(*symbol), new_name);
|
||||||
|
|
||||||
// Store the generate phi functions.
|
// Store the generated phi function.
|
||||||
statements.push(assignment);
|
statements.push(assignment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -200,10 +187,12 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
|
|||||||
statements
|
statements
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Error message
|
||||||
fn consume_iteration(&mut self, _input: IterationStatement) -> Self::Output {
|
fn consume_iteration(&mut self, _input: IterationStatement) -> Self::Output {
|
||||||
unreachable!("`IterationStatement`s should not be in the AST at this phase of compilation.");
|
unreachable!("`IterationStatement`s should not be in the AST at this phase of compilation.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Where do we handle console statements.
|
||||||
fn consume_console(&mut self, input: ConsoleStatement) -> Self::Output {
|
fn consume_console(&mut self, input: ConsoleStatement) -> Self::Output {
|
||||||
vec![Statement::Console(input)]
|
vec![Statement::Console(input)]
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user