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);
// Return the identifier associated with the folded tuple element.
identifier
Expression::Identifier(identifier)
})
.collect(),
span: Default::default(),
@ -132,7 +132,7 @@ impl ExpressionReconstructor for Flattener<'_> {
CircuitVariableInitializer {
identifier: *id,
expression: Some(identifier),
expression: Some(Expression::Identifier(identifier)),
}
})
.collect();
@ -150,18 +150,12 @@ impl ExpressionReconstructor for Flattener<'_> {
let (identifier, statement) = self.unique_simple_assign_statement(expr);
// Mark the lhs of the assignment as a circuit.
match identifier {
Expression::Identifier(identifier) => self
.circuits
.insert(identifier.name, first_member_circuit.identifier.name),
_ => unreachable!(
"`unique_simple_assign_statement` always produces an identifier on the left hand size."
),
};
self.circuits
.insert(identifier.name, first_member_circuit.identifier.name);
statements.push(statement);
(identifier, statements)
(Expression::Identifier(identifier), statements)
}
_ => {
let if_true = Expression::Access(AccessExpression::Member(first));
@ -185,7 +179,7 @@ impl ExpressionReconstructor for Flattener<'_> {
// Accumulate the new assignment statement.
statements.push(statement);
(identifier, statements)
(Expression::Identifier(identifier), statements)
}
}
}
@ -234,7 +228,7 @@ impl ExpressionReconstructor for Flattener<'_> {
CircuitVariableInitializer {
identifier: *id,
expression: Some(identifier),
expression: Some(Expression::Identifier(identifier)),
}
})
.collect();
@ -252,18 +246,11 @@ impl ExpressionReconstructor for Flattener<'_> {
let (identifier, statement) = self.unique_simple_assign_statement(expr);
// Mark the lhs of the assignment as a circuit.
match identifier {
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."
),
};
self.circuits.insert(identifier.name, first_circuit.identifier.name);
statements.push(statement);
(identifier, statements)
(Expression::Identifier(identifier), statements)
}
// 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.
@ -287,7 +274,7 @@ impl ExpressionReconstructor for Flattener<'_> {
// Accumulate the new assignment 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.
let place = Expression::Identifier(lhs);
self.update_circuits(&place, &value);
self.update_circuits(&lhs, &value);
(
Statement::Assign(Box::new(AssignStatement {
place,
place: Expression::Identifier(lhs),
value,
span: assign.span,
})),

View File

@ -111,7 +111,7 @@ impl<'a> Flattener<'a> {
.into_iter()
.rev()
.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.
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.
/// The function assumes that the identifier or access expression is a circuit.
pub(crate) fn lookup_circuit_symbol(&self, expression: &Expression) -> Option<Symbol> {
match expression {
Expression::Identifier(identifier) => self.circuits.get(&identifier.name).copied(),
@ -138,19 +137,13 @@ impl<'a> Flattener<'a> {
_ => None,
}
}
_ => unreachable!("Expected identifier or access expression"),
_ => None,
}
}
/// Updates `self.circuits` for new assignment statements.
/// Expects the left hand side of the assignment to be an identifier.
pub(crate) fn update_circuits(&mut self, lhs: &Expression, rhs: &Expression) {
let lhs = match lhs {
Expression::Identifier(identifier) => identifier,
// TODO: Document, or fix
_ => unreachable!("Expected identifier"),
};
pub(crate) fn update_circuits(&mut self, lhs: &Identifier, rhs: &Expression) {
match rhs {
Expression::Circuit(rhs) => {
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`.
pub(crate) fn unique_simple_assign_statement(&mut self, expr: Expression) -> (Expression, Statement) {
// TODO: Fix clone
let (place, statement) = self.assigner.unique_simple_assign_statement(expr.clone());
self.update_circuits(&place, &expr);
pub(crate) fn unique_simple_assign_statement(&mut self, expr: Expression) -> (Identifier, Statement) {
let (place, statement) = self.assigner.unique_simple_assign_statement(expr);
match &statement {
Statement::Assign(assign) => {
self.update_circuits(&place, &assign.value);
}
_ => unreachable!("`assigner.unique_simple_assign_statement` always returns an assignment statement."),
}
(place, statement)
}
/// A wrapper around `assigner.simple_assign_statement` that updates `self.circuits`.
pub(crate) fn simple_assign_statement(&mut self, lhs: Identifier, rhs: Expression) -> Statement {
// TODO: Fix clone.
self.update_circuits(&Expression::Identifier(lhs), &rhs);
self.update_circuits(&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.
/// 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.
let name = self.unique_symbol("$var");
@ -53,6 +53,6 @@ impl Assigner {
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));
statements.push(statement);
(place, statements)
(Expression::Identifier(place), statements)
}
/// Consumes a binary expression, accumulating any statements that are generated.
@ -107,7 +107,7 @@ impl ExpressionConsumer for StaticSingleAssigner {
}));
statements.push(statement);
(place, statements)
(Expression::Identifier(place), statements)
}
/// 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);
(place, statements)
(Expression::Identifier(place), statements)
}
/// 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);
(place, statements)
(Expression::Identifier(place), statements)
}
/// Produces a new `Identifier` with a unique name.
@ -235,7 +235,7 @@ impl ExpressionConsumer for StaticSingleAssigner {
}));
statements.push(statement);
(place, statements)
(Expression::Identifier(place), statements)
}
/// Consumes a tuple expression, accumulating any statements that are generated
@ -279,6 +279,6 @@ impl ExpressionConsumer for StaticSingleAssigner {
}));
statements.push(statement);
(place, statements)
(Expression::Identifier(place), statements)
}
}