This commit is contained in:
Pranav Gaddamadugu 2022-09-17 19:17:01 +02:00
parent 7a29c76805
commit 611e65554d
5 changed files with 32 additions and 50 deletions

View File

@ -76,7 +76,7 @@ impl ExpressionReconstructor for Flattener<'_> {
statements.push(statement); statements.push(statement);
// Return the identifier associated with the folded tuple element. // Return the identifier associated with the folded tuple element.
identifier Expression::Identifier(identifier)
}) })
.collect(), .collect(),
span: Default::default(), span: Default::default(),
@ -132,7 +132,7 @@ impl ExpressionReconstructor for Flattener<'_> {
CircuitVariableInitializer { CircuitVariableInitializer {
identifier: *id, identifier: *id,
expression: Some(identifier), expression: Some(Expression::Identifier(identifier)),
} }
}) })
.collect(); .collect();
@ -150,18 +150,12 @@ impl ExpressionReconstructor for Flattener<'_> {
let (identifier, statement) = self.unique_simple_assign_statement(expr); let (identifier, statement) = self.unique_simple_assign_statement(expr);
// Mark the lhs of the assignment as a circuit. // Mark the lhs of the assignment as a circuit.
match identifier { self.circuits
Expression::Identifier(identifier) => self .insert(identifier.name, first_member_circuit.identifier.name);
.circuits
.insert(identifier.name, first_member_circuit.identifier.name),
_ => unreachable!(
"`unique_simple_assign_statement` always produces an identifier on the left hand size."
),
};
statements.push(statement); statements.push(statement);
(identifier, statements) (Expression::Identifier(identifier), statements)
} }
_ => { _ => {
let if_true = Expression::Access(AccessExpression::Member(first)); let if_true = Expression::Access(AccessExpression::Member(first));
@ -185,7 +179,7 @@ impl ExpressionReconstructor for Flattener<'_> {
// Accumulate the new assignment statement. // Accumulate the new assignment statement.
statements.push(statement); statements.push(statement);
(identifier, statements) (Expression::Identifier(identifier), statements)
} }
} }
} }
@ -234,7 +228,7 @@ impl ExpressionReconstructor for Flattener<'_> {
CircuitVariableInitializer { CircuitVariableInitializer {
identifier: *id, identifier: *id,
expression: Some(identifier), expression: Some(Expression::Identifier(identifier)),
} }
}) })
.collect(); .collect();
@ -252,18 +246,11 @@ impl ExpressionReconstructor for Flattener<'_> {
let (identifier, statement) = self.unique_simple_assign_statement(expr); let (identifier, statement) = self.unique_simple_assign_statement(expr);
// Mark the lhs of the assignment as a circuit. // Mark the lhs of the assignment as a circuit.
match identifier { self.circuits.insert(identifier.name, first_circuit.identifier.name);
Expression::Identifier(identifier) => {
self.circuits.insert(identifier.name, first_circuit.identifier.name)
}
_ => unreachable!(
"`unique_simple_assign_statement` always produces an identifier on the left hand size."
),
};
statements.push(statement); statements.push(statement);
(identifier, statements) (Expression::Identifier(identifier), statements)
} }
// Otherwise, create a new intermediate assignment for the ternary expression are return the assigned variable. // Otherwise, create a new intermediate assignment for the ternary expression are return the assigned variable.
// Note that a new assignment must be created to flattened nested ternary expressions. // Note that a new assignment must be created to flattened nested ternary expressions.
@ -287,7 +274,7 @@ impl ExpressionReconstructor for Flattener<'_> {
// Accumulate the new assignment statement. // Accumulate the new assignment statement.
statements.push(statement); statements.push(statement);
(identifier, statements) (Expression::Identifier(identifier), statements)
} }
} }
} }

View File

@ -41,12 +41,11 @@ impl StatementReconstructor for Flattener<'_> {
}; };
// Update the `self.circuits` if the rhs is a circuit. // Update the `self.circuits` if the rhs is a circuit.
let place = Expression::Identifier(lhs); self.update_circuits(&lhs, &value);
self.update_circuits(&place, &value);
( (
Statement::Assign(Box::new(AssignStatement { Statement::Assign(Box::new(AssignStatement {
place, place: Expression::Identifier(lhs),
value, value,
span: assign.span, span: assign.span,
})), })),

View File

@ -111,7 +111,7 @@ impl<'a> Flattener<'a> {
.into_iter() .into_iter()
.rev() .rev()
.fold(last_expression, |acc, (guard, expr)| match guard { .fold(last_expression, |acc, (guard, expr)| match guard {
None => unreachable!("All expression except for the last one must have a guard."), None => unreachable!("All expressions except for the last one must have a guard."),
// Note that type checking guarantees that all expressions have the same type. // Note that type checking guarantees that all expressions have the same type.
Some(guard) => construct_ternary_assignment(guard, expr, acc), Some(guard) => construct_ternary_assignment(guard, expr, acc),
}); });
@ -120,7 +120,6 @@ impl<'a> Flattener<'a> {
} }
/// Looks up the name of the circuit associated with an identifier or access expression, if it exists. /// Looks up the name of the circuit associated with an identifier or access expression, if it exists.
/// The function assumes that the identifier or access expression is a circuit.
pub(crate) fn lookup_circuit_symbol(&self, expression: &Expression) -> Option<Symbol> { pub(crate) fn lookup_circuit_symbol(&self, expression: &Expression) -> Option<Symbol> {
match expression { match expression {
Expression::Identifier(identifier) => self.circuits.get(&identifier.name).copied(), Expression::Identifier(identifier) => self.circuits.get(&identifier.name).copied(),
@ -138,19 +137,13 @@ impl<'a> Flattener<'a> {
_ => None, _ => None,
} }
} }
_ => unreachable!("Expected identifier or access expression"), _ => None,
} }
} }
/// Updates `self.circuits` for new assignment statements. /// Updates `self.circuits` for new assignment statements.
/// Expects the left hand side of the assignment to be an identifier. /// Expects the left hand side of the assignment to be an identifier.
pub(crate) fn update_circuits(&mut self, lhs: &Expression, rhs: &Expression) { pub(crate) fn update_circuits(&mut self, lhs: &Identifier, rhs: &Expression) {
let lhs = match lhs {
Expression::Identifier(identifier) => identifier,
// TODO: Document, or fix
_ => unreachable!("Expected identifier"),
};
match rhs { match rhs {
Expression::Circuit(rhs) => { Expression::Circuit(rhs) => {
self.circuits.insert(lhs.name, rhs.name.name); self.circuits.insert(lhs.name, rhs.name.name);
@ -166,17 +159,20 @@ impl<'a> Flattener<'a> {
} }
/// A wrapper around `assigner.unique_simple_assign_statement` that updates `self.circuits`. /// A wrapper around `assigner.unique_simple_assign_statement` that updates `self.circuits`.
pub(crate) fn unique_simple_assign_statement(&mut self, expr: Expression) -> (Expression, Statement) { pub(crate) fn unique_simple_assign_statement(&mut self, expr: Expression) -> (Identifier, Statement) {
// TODO: Fix clone let (place, statement) = self.assigner.unique_simple_assign_statement(expr);
let (place, statement) = self.assigner.unique_simple_assign_statement(expr.clone()); match &statement {
self.update_circuits(&place, &expr); Statement::Assign(assign) => {
self.update_circuits(&place, &assign.value);
}
_ => unreachable!("`assigner.unique_simple_assign_statement` always returns an assignment statement."),
}
(place, statement) (place, statement)
} }
/// A wrapper around `assigner.simple_assign_statement` that updates `self.circuits`. /// A wrapper around `assigner.simple_assign_statement` that updates `self.circuits`.
pub(crate) fn simple_assign_statement(&mut self, lhs: Identifier, rhs: Expression) -> Statement { pub(crate) fn simple_assign_statement(&mut self, lhs: Identifier, rhs: Expression) -> Statement {
// TODO: Fix clone. self.update_circuits(&lhs, &rhs);
self.update_circuits(&Expression::Identifier(lhs), &rhs);
self.assigner.simple_assign_statement(lhs, rhs) self.assigner.simple_assign_statement(lhs, rhs)
} }
} }

View File

@ -44,7 +44,7 @@ impl Assigner {
/// Constructs a simple assign statement for `expr` with a unique name. /// Constructs a simple assign statement for `expr` with a unique name.
/// For example, `expr` is transformed into `$var$0 = expr;`. /// For example, `expr` is transformed into `$var$0 = expr;`.
pub(crate) fn unique_simple_assign_statement(&mut self, expr: Expression) -> (Expression, Statement) { pub(crate) fn unique_simple_assign_statement(&mut self, expr: Expression) -> (Identifier, Statement) {
// Create a new variable for the expression. // Create a new variable for the expression.
let name = self.unique_symbol("$var"); let name = self.unique_symbol("$var");
@ -53,6 +53,6 @@ impl Assigner {
span: Default::default(), span: Default::default(),
}; };
(Expression::Identifier(place), self.simple_assign_statement(place, expr)) (place, self.simple_assign_statement(place, expr))
} }
} }

View File

@ -84,7 +84,7 @@ impl ExpressionConsumer for StaticSingleAssigner {
let (place, statement) = self.assigner.unique_simple_assign_statement(Expression::Access(expr)); let (place, statement) = self.assigner.unique_simple_assign_statement(Expression::Access(expr));
statements.push(statement); statements.push(statement);
(place, statements) (Expression::Identifier(place), statements)
} }
/// Consumes a binary expression, accumulating any statements that are generated. /// Consumes a binary expression, accumulating any statements that are generated.
@ -107,7 +107,7 @@ impl ExpressionConsumer for StaticSingleAssigner {
})); }));
statements.push(statement); statements.push(statement);
(place, statements) (Expression::Identifier(place), statements)
} }
/// Consumes a call expression without visiting the function name, accumulating any statements that are generated. /// Consumes a call expression without visiting the function name, accumulating any statements that are generated.
@ -137,7 +137,7 @@ impl ExpressionConsumer for StaticSingleAssigner {
})); }));
statements.push(statement); statements.push(statement);
(place, statements) (Expression::Identifier(place), statements)
} }
/// Consumes a circuit initialization expression with renamed variables, accumulating any statements that are generated. /// Consumes a circuit initialization expression with renamed variables, accumulating any statements that are generated.
@ -178,7 +178,7 @@ impl ExpressionConsumer for StaticSingleAssigner {
})); }));
statements.push(statement); statements.push(statement);
(place, statements) (Expression::Identifier(place), statements)
} }
/// Produces a new `Identifier` with a unique name. /// Produces a new `Identifier` with a unique name.
@ -235,7 +235,7 @@ impl ExpressionConsumer for StaticSingleAssigner {
})); }));
statements.push(statement); statements.push(statement);
(place, statements) (Expression::Identifier(place), statements)
} }
/// Consumes a tuple expression, accumulating any statements that are generated /// Consumes a tuple expression, accumulating any statements that are generated
@ -279,6 +279,6 @@ impl ExpressionConsumer for StaticSingleAssigner {
})); }));
statements.push(statement); statements.push(statement);
(place, statements) (Expression::Identifier(place), statements)
} }
} }