mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-09-11 13:56:58 +03:00
Refactor AssignmentRename to DefinitionRenamer
This commit is contained in:
parent
6b412b0129
commit
b8a41e483d
@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Assigner, RenameTable};
|
||||
use crate::{Definer, RenameTable};
|
||||
use leo_ast::{
|
||||
AssignStatement,
|
||||
ConditionalStatement,
|
||||
@ -33,18 +33,18 @@ use leo_ast::{
|
||||
use leo_span::Symbol;
|
||||
|
||||
// TODO: Generalize the functionality of this reconstructor to be used in other passes.
|
||||
/// An `AssignmentRenamer` renames the left-hand side of all assignment statements in an AST node.
|
||||
/// An `DefinitionRenamer` renames the left-hand side of all definition statements in an AST node.
|
||||
/// The new names are propagated to all following identifiers.
|
||||
pub struct AssignmentRenamer<'a> {
|
||||
pub assigner: &'a Assigner,
|
||||
pub struct DefinitionRenamer<'a> {
|
||||
pub definer: &'a Definer,
|
||||
pub rename_table: RenameTable,
|
||||
pub is_lhs: bool,
|
||||
}
|
||||
|
||||
impl<'a> AssignmentRenamer<'a> {
|
||||
impl<'a> DefinitionRenamer<'a> {
|
||||
/// Initialize a new `AssignmentRenamer`.
|
||||
pub fn new(assigner: &'a Assigner) -> Self {
|
||||
Self { assigner, rename_table: RenameTable::new(None), is_lhs: false }
|
||||
pub fn new(definer: &'a Definer) -> Self {
|
||||
Self { definer, rename_table: RenameTable::new(None), is_lhs: false }
|
||||
}
|
||||
|
||||
/// Load the internal rename table with a set of entries.
|
||||
@ -60,15 +60,15 @@ impl<'a> AssignmentRenamer<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl ExpressionReconstructor for AssignmentRenamer<'_> {
|
||||
impl ExpressionReconstructor for DefinitionRenamer<'_> {
|
||||
type AdditionalOutput = ();
|
||||
|
||||
/// Rename the identifier if it is the left-hand side of an assignment, otherwise look up for a new name in the internal rename table.
|
||||
/// Rename the identifier if it is the left-hand side of a definition, otherwise look up for a new name in the internal rename table.
|
||||
fn reconstruct_identifier(&mut self, input: Identifier) -> (Expression, Self::AdditionalOutput) {
|
||||
let name = match self.is_lhs {
|
||||
// If consuming the left-hand side of an assignment, a new unique name is introduced.
|
||||
true => {
|
||||
let new_name = self.assigner.unique_symbol(input.name, "$");
|
||||
let new_name = self.definer.unique_symbol(input.name, "$");
|
||||
self.rename_table.update(input.name, new_name);
|
||||
new_name
|
||||
}
|
||||
@ -110,20 +110,27 @@ impl ExpressionReconstructor for AssignmentRenamer<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl StatementReconstructor for AssignmentRenamer<'_> {
|
||||
/// Rename the left-hand side of the assignment statement.
|
||||
fn reconstruct_assign(&mut self, input: AssignStatement) -> (Statement, Self::AdditionalOutput) {
|
||||
// First rename the right-hand-side of the assignment.
|
||||
impl StatementReconstructor for DefinitionRenamer<'_> {
|
||||
/// Rename the left-hand side of the definition statement.
|
||||
fn reconstruct_definition(&mut self, input: DefinitionStatement) -> (Statement, Self::AdditionalOutput) {
|
||||
// First rename the right-hand-side of the definition.
|
||||
let value = self.reconstruct_expression(input.value).0;
|
||||
|
||||
// Then assign a new unique name to the left-hand-side of the assignment.
|
||||
// Note that this order is necessary to ensure that the right-hand-side uses the correct name when consuming a complex assignment.
|
||||
// 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 definition.
|
||||
self.is_lhs = true;
|
||||
let place = self.reconstruct_expression(input.place).0;
|
||||
self.is_lhs = false;
|
||||
|
||||
(
|
||||
Statement::Assign(Box::new(AssignStatement { place, value, span: input.span, id: input.id })),
|
||||
Statement::Definition(DefinitionStatement {
|
||||
declaration_type: input.declaration_type,
|
||||
type_: input.type_,
|
||||
place,
|
||||
value,
|
||||
span: input.span,
|
||||
id: input.id,
|
||||
}),
|
||||
Default::default(),
|
||||
)
|
||||
}
|
||||
@ -138,9 +145,9 @@ impl StatementReconstructor for AssignmentRenamer<'_> {
|
||||
unreachable!("`ConsoleStatement`s should not be in the AST at this phase of compilation.")
|
||||
}
|
||||
|
||||
/// Static single assignment replaces definition statements with assignment statements.
|
||||
fn reconstruct_definition(&mut self, _: DefinitionStatement) -> (Statement, Self::AdditionalOutput) {
|
||||
unreachable!("`DefinitionStatement`s should not exist in the AST at this phase of compilation.")
|
||||
/// Static single assignment replaces assignment statements with definition statements.
|
||||
fn reconstruct_assign(&mut self, _: AssignStatement) -> (Statement, Self::AdditionalOutput) {
|
||||
unreachable!("`AssignStatement`s should not exist in the AST at this phase of compilation.")
|
||||
}
|
||||
|
||||
/// Loop unrolling unrolls and removes iteration statements from the program.
|
||||
@ -149,4 +156,4 @@ impl StatementReconstructor for AssignmentRenamer<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl ProgramReconstructor for AssignmentRenamer<'_> {}
|
||||
impl ProgramReconstructor for DefinitionRenamer<'_> {}
|
||||
|
@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Assigner, AssignmentRenamer, CallGraph};
|
||||
use crate::{CallGraph, Definer, DefinitionRenamer};
|
||||
|
||||
use leo_ast::{Function, NodeBuilder};
|
||||
use leo_span::Symbol;
|
||||
@ -25,18 +25,18 @@ pub struct FunctionInliner<'a> {
|
||||
/// The call graph for the program.
|
||||
pub(crate) call_graph: &'a CallGraph,
|
||||
/// A wrapper around an Assigner used to create unique variable assignments.
|
||||
pub(crate) assignment_renamer: AssignmentRenamer<'a>,
|
||||
pub(crate) assignment_renamer: DefinitionRenamer<'a>,
|
||||
/// A map of reconstructed functions in the current program scope.
|
||||
pub(crate) reconstructed_functions: Vec<(Symbol, Function)>,
|
||||
}
|
||||
|
||||
impl<'a> FunctionInliner<'a> {
|
||||
/// Initializes a new `FunctionInliner`.
|
||||
pub fn new(node_builder: &'a NodeBuilder, call_graph: &'a CallGraph, assigner: &'a Assigner) -> Self {
|
||||
pub fn new(node_builder: &'a NodeBuilder, call_graph: &'a CallGraph, assigner: &'a Definer) -> Self {
|
||||
Self {
|
||||
node_builder,
|
||||
call_graph,
|
||||
assignment_renamer: AssignmentRenamer::new(assigner),
|
||||
assignment_renamer: DefinitionRenamer::new(assigner),
|
||||
reconstructed_functions: Default::default(),
|
||||
}
|
||||
}
|
||||
|
@ -64,13 +64,13 @@ mod inline_program;
|
||||
pub mod function_inliner;
|
||||
pub use function_inliner::*;
|
||||
|
||||
use crate::{Assigner, CallGraph, Pass};
|
||||
use crate::{CallGraph, Definer, Pass};
|
||||
|
||||
use leo_ast::{Ast, NodeBuilder, ProgramReconstructor};
|
||||
use leo_errors::Result;
|
||||
|
||||
impl<'a> Pass for FunctionInliner<'a> {
|
||||
type Input = (Ast, &'a NodeBuilder, &'a CallGraph, &'a Assigner);
|
||||
type Input = (Ast, &'a NodeBuilder, &'a CallGraph, &'a Definer);
|
||||
type Output = Result<Ast>;
|
||||
|
||||
fn do_pass((ast, node_builder, call_graph, assigner): Self::Input) -> Self::Output {
|
||||
|
Loading…
Reference in New Issue
Block a user