mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-10 13:24:15 +03:00
Remove flattening circuits and nested tuples
This commit is contained in:
parent
6ae2d9727b
commit
fdddb8054a
@ -18,7 +18,7 @@ use crate::Flattener;
|
||||
use itertools::Itertools;
|
||||
|
||||
use leo_ast::{
|
||||
AccessExpression, AssociatedFunction, Expression, ExpressionReconstructor, Member, MemberAccess, Statement, Struct,
|
||||
AccessExpression, AssociatedFunction, Expression, ExpressionReconstructor, Member, MemberAccess, Statement,
|
||||
StructExpression, StructVariableInitializer, TernaryExpression, TupleExpression,
|
||||
};
|
||||
|
||||
@ -75,7 +75,7 @@ impl ExpressionReconstructor for Flattener<'_> {
|
||||
/// Reconstructs a struct init expression, flattening any tuples in the expression.
|
||||
fn reconstruct_struct_init(&mut self, input: StructExpression) -> (Expression, Self::AdditionalOutput) {
|
||||
let mut statements = Vec::new();
|
||||
let mut flattened_expressions = Vec::with_capacity(input.members.len());
|
||||
let mut members = Vec::with_capacity(input.members.len());
|
||||
|
||||
// Reconstruct and flatten the argument expressions.
|
||||
for member in input.members.into_iter() {
|
||||
@ -83,33 +83,17 @@ impl ExpressionReconstructor for Flattener<'_> {
|
||||
let (expr, stmts) = self.reconstruct_expression(member.expression.unwrap());
|
||||
// Accumulate any statements produced.
|
||||
statements.extend(stmts);
|
||||
// Flatten the expression.
|
||||
flattened_expressions.extend(self.flatten_subexpression(expr));
|
||||
// Accunulate the struct members.
|
||||
members.push(StructVariableInitializer {
|
||||
identifier: member.identifier,
|
||||
expression: Some(expr),
|
||||
});
|
||||
}
|
||||
|
||||
// Lookup the flattened definition of the struct.
|
||||
// Note that this unwrap is safe since TYC guarantees that all struct are declared.
|
||||
let struct_: &Struct = self.flattened_structs.get(&input.name.name).unwrap();
|
||||
|
||||
// Collect the names of the flattened struct members.
|
||||
let names = struct_
|
||||
.members
|
||||
.iter()
|
||||
.map(|Member { identifier, .. }| identifier)
|
||||
.cloned();
|
||||
|
||||
let flattened_members = names
|
||||
.zip_eq(flattened_expressions)
|
||||
.map(|(identifier, expression)| StructVariableInitializer {
|
||||
identifier,
|
||||
expression: Some(expression),
|
||||
})
|
||||
.collect();
|
||||
|
||||
(
|
||||
Expression::Struct(StructExpression {
|
||||
name: input.name,
|
||||
members: flattened_members,
|
||||
members,
|
||||
span: input.span,
|
||||
}),
|
||||
statements,
|
||||
|
@ -16,11 +16,7 @@
|
||||
|
||||
use crate::Flattener;
|
||||
|
||||
use leo_ast::{
|
||||
Finalize, FinalizeStatement, Function, Identifier, Member, ProgramReconstructor, Statement, StatementReconstructor,
|
||||
Struct, Type,
|
||||
};
|
||||
use leo_span::Symbol;
|
||||
use leo_ast::{Finalize, FinalizeStatement, Function, ProgramReconstructor, Statement, StatementReconstructor, Type};
|
||||
|
||||
impl ProgramReconstructor for Flattener<'_> {
|
||||
/// Flattens a function's body and finalize block, if it exists.
|
||||
@ -102,8 +98,6 @@ impl ProgramReconstructor for Flattener<'_> {
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: Flatten any tuples in the produced finalize statement.
|
||||
|
||||
// Add the `FinalizeStatement` to the end of the block.
|
||||
block.statements.push(Statement::Finalize(FinalizeStatement {
|
||||
arguments,
|
||||
@ -123,75 +117,4 @@ impl ProgramReconstructor for Flattener<'_> {
|
||||
span: function.span,
|
||||
}
|
||||
}
|
||||
|
||||
/// Flattens the struct definitions in the program, flattening any tuples in the definitions.
|
||||
/// For example, the follow struct definitions:
|
||||
/// ```leo
|
||||
/// struct Bar {
|
||||
/// a: u8,
|
||||
/// b: (u16, u32),
|
||||
/// }
|
||||
///
|
||||
/// struct Foo {
|
||||
/// c: u8,
|
||||
/// d: (Bar, (Bar, Bar)),
|
||||
/// }
|
||||
/// ```
|
||||
/// are flattened in the following way.
|
||||
/// ```leo
|
||||
/// struct Bar {
|
||||
/// a_0: u8,
|
||||
/// b_0: u16,
|
||||
/// b_1: u32,
|
||||
/// }
|
||||
///
|
||||
/// struct Foo {
|
||||
/// c_0: u8,
|
||||
/// d_0: Bar,
|
||||
/// d_1_0: Bar,
|
||||
/// d_1_1: Bar,
|
||||
/// }
|
||||
fn reconstruct_struct(&mut self, input: Struct) -> Struct {
|
||||
// Helper to rename and flatten a struct member.
|
||||
fn rename_member(identifier: Identifier, type_: Type, index: usize) -> Vec<Member> {
|
||||
// Construct the new name for the identifier.
|
||||
let identifier = Identifier::new(Symbol::intern(&format!("{}_{}", identifier.name, index)));
|
||||
match type_ {
|
||||
// If the member is a tuple, then it must be flattened.
|
||||
Type::Tuple(tuple) => {
|
||||
let mut members = Vec::with_capacity(tuple.0.len());
|
||||
tuple.0.into_iter().enumerate().for_each(|(i, element_type)| {
|
||||
members.extend(rename_member(identifier, element_type, i));
|
||||
});
|
||||
members
|
||||
}
|
||||
// Otherwise, rename the member and return it as a singleton list.
|
||||
type_ => vec![Member { identifier, type_ }],
|
||||
}
|
||||
}
|
||||
|
||||
// Flatten the circuit members.
|
||||
let mut members = Vec::with_capacity(input.members.len());
|
||||
input
|
||||
.members
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.for_each(|(i, Member { identifier, type_ })| {
|
||||
members.extend(rename_member(identifier, type_, i));
|
||||
});
|
||||
|
||||
// Construct the flattened struct.
|
||||
let struct_ = Struct {
|
||||
identifier: input.identifier,
|
||||
members,
|
||||
is_record: input.is_record,
|
||||
span: input.span,
|
||||
};
|
||||
|
||||
// Add the flattened struct to the struct map.
|
||||
self.flattened_structs.insert(struct_.identifier.name, struct_.clone());
|
||||
|
||||
// Return the flattened struct.
|
||||
struct_
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ use crate::{Assigner, SymbolTable};
|
||||
|
||||
use leo_ast::{
|
||||
AccessExpression, BinaryExpression, BinaryOperation, Block, Expression, ExpressionReconstructor, Identifier,
|
||||
Member, ReturnStatement, Statement, Struct, TernaryExpression, Type,
|
||||
Member, ReturnStatement, Statement, TernaryExpression, Type,
|
||||
};
|
||||
use leo_span::Symbol;
|
||||
|
||||
@ -43,8 +43,6 @@ pub struct Flattener<'a> {
|
||||
/// Note that finalizes are inserted in the order they are encountered during a pre-order traversal of the AST.
|
||||
/// Note that type checking guarantees that there is at most one finalize in a basic block.
|
||||
pub(crate) finalizes: Vec<Vec<(Option<Expression>, Expression)>>,
|
||||
/// A mapping between struct names and flattened struct declarations.
|
||||
pub(crate) flattened_structs: IndexMap<Symbol, Struct>,
|
||||
/// A mapping between variables and flattened tuple expressions.
|
||||
pub(crate) tuples: IndexMap<Symbol, Vec<Expression>>,
|
||||
}
|
||||
@ -58,7 +56,6 @@ impl<'a> Flattener<'a> {
|
||||
condition_stack: Vec::new(),
|
||||
returns: Vec::new(),
|
||||
finalizes: Vec::new(),
|
||||
flattened_structs: IndexMap::new(),
|
||||
tuples: IndexMap::new(),
|
||||
}
|
||||
}
|
||||
@ -216,15 +213,4 @@ impl<'a> Flattener<'a> {
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
/// Flattens a sub-expression, returning a vector of expressions (if we a flattening a tuple).
|
||||
pub(crate) fn flatten_subexpression(&self, expression: Expression) -> Vec<Expression> {
|
||||
match expression {
|
||||
Expression::Literal(literal) => vec![Expression::Literal(literal)],
|
||||
Expression::Identifier(_identifier) => {
|
||||
todo!()
|
||||
}
|
||||
_ => unreachable!("SSA guarantees that all sub-expressions are either literals or identifiers."),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user