pub struct Flattener<'a> {
pub(crate) symbol_table: &'a SymbolTable,
pub(crate) type_table: &'a TypeTable,
pub(crate) node_builder: &'a NodeBuilder,
pub(crate) assigner: &'a Assigner,
pub(crate) condition_stack: Vec<Guard>,
pub(crate) returns: Vec<(ReturnGuard, ReturnStatement)>,
pub(crate) program: Option<Symbol>,
pub(crate) is_async: bool,
}
Fields§
§symbol_table: &'a SymbolTable
The symbol table associated with the program.
type_table: &'a TypeTable
A mapping between node IDs and their types.
node_builder: &'a NodeBuilder
A counter used to generate unique node IDs.
assigner: &'a Assigner
A struct used to construct (unique) assignment statements.
condition_stack: Vec<Guard>
A stack of condition Expression
s visited up to the current point in the AST.
returns: Vec<(ReturnGuard, ReturnStatement)>
A list containing tuples of guards and expressions associated ReturnStatement
s.
A guard is an expression that evaluates to true on the execution path of the ReturnStatement
.
Note that returns 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 return in a basic block.
program: Option<Symbol>
The program name.
is_async: bool
Whether the function is an async function.
Implementations§
Source§impl<'a> Flattener<'a>
impl<'a> Flattener<'a>
pub(crate) fn new( symbol_table: &'a SymbolTable, type_table: &'a TypeTable, node_builder: &'a NodeBuilder, assigner: &'a Assigner, ) -> Self
Sourcepub(crate) fn construct_early_return_guard(
&mut self,
) -> Option<(Identifier, Vec<Statement>)>
pub(crate) fn construct_early_return_guard( &mut self, ) -> Option<(Identifier, Vec<Statement>)>
Construct an early return guard.
That is, an Identifier assigned to a boolean that is true iff some early return was taken.
Sourcepub(crate) fn construct_guard(&mut self) -> Option<(Identifier, Vec<Statement>)>
pub(crate) fn construct_guard(&mut self) -> Option<(Identifier, Vec<Statement>)>
Construct a guard from the current state of the condition stack.
That is, a boolean expression which is true iff we’ve followed the branches that led to the current point in the Leo code.
Sourcepub(crate) fn fold_guards(
&mut self,
prefix: &str,
guards: Vec<(Option<Expression>, Expression)>,
) -> (Expression, Vec<Statement>)
pub(crate) fn fold_guards( &mut self, prefix: &str, guards: Vec<(Option<Expression>, Expression)>, ) -> (Expression, Vec<Statement>)
Fold guards and expressions into a single expression. Note that this function assumes that at least one guard is present.
Sourcepub(crate) fn unique_simple_assign_statement(
&mut self,
expr: Expression,
) -> (Identifier, Statement)
pub(crate) fn unique_simple_assign_statement( &mut self, expr: Expression, ) -> (Identifier, Statement)
A wrapper around assigner.unique_simple_assign_statement
that updates self.structs
.
Sourcepub(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
A wrapper around assigner.simple_assign_statement
that tracks the type of the lhs.
Sourcepub(crate) fn fold_returns(
&mut self,
block: &mut Block,
returns: Vec<(Option<Expression>, ReturnStatement)>,
)
pub(crate) fn fold_returns( &mut self, block: &mut Block, returns: Vec<(Option<Expression>, ReturnStatement)>, )
Folds a list of return statements into a single return statement and adds the produced statements to the block.
pub(crate) fn ternary_array( &mut self, array: &ArrayType, condition: &Expression, first: &Identifier, second: &Identifier, ) -> (Expression, Vec<Statement>)
pub(crate) fn ternary_struct( &mut self, struct_: &Composite, condition: &Expression, first: &Identifier, second: &Identifier, ) -> (Expression, Vec<Statement>)
pub(crate) fn ternary_tuple( &mut self, tuple_type: &TupleType, condition: &Expression, first: &Identifier, second: &Identifier, ) -> (Expression, Vec<Statement>)
Trait Implementations§
Source§impl ExpressionReconstructor for Flattener<'_>
impl ExpressionReconstructor for Flattener<'_>
Source§fn reconstruct_struct_init(
&mut self,
input: StructExpression,
) -> (Expression, Self::AdditionalOutput)
fn reconstruct_struct_init( &mut self, input: StructExpression, ) -> (Expression, Self::AdditionalOutput)
Reconstructs a struct init expression, flattening any tuples in the expression.
Source§fn reconstruct_ternary(
&mut self,
input: TernaryExpression,
) -> (Expression, Self::AdditionalOutput)
fn reconstruct_ternary( &mut self, input: TernaryExpression, ) -> (Expression, Self::AdditionalOutput)
Reconstructs ternary expressions over arrays, structs, and tuples, accumulating any statements that are generated.
This is necessary because Aleo instructions does not support ternary expressions over composite data types.
For example, the ternary expression cond ? (a, b) : (c, d)
is flattened into the following:
let var$0 = cond ? a : c;
let var$1 = cond ? b : d;
(var$0, var$1)
For structs, the ternary expression cond ? a : b
, where a
and b
are both structs Foo { bar: u8, baz: u8 }
, is flattened into the following:
let var$0 = cond ? a.bar : b.bar;
let var$1 = cond ? a.baz : b.baz;
let var$2 = Foo { bar: var$0, baz: var$1 };
var$2
type AdditionalOutput = Vec<Statement>
fn reconstruct_expression( &mut self, input: Expression, ) -> (Expression, Self::AdditionalOutput)
fn reconstruct_access( &mut self, input: AccessExpression, ) -> (Expression, Self::AdditionalOutput)
fn reconstruct_array_access( &mut self, input: ArrayAccess, ) -> (Expression, Self::AdditionalOutput)
fn reconstruct_associated_constant( &mut self, input: AssociatedConstant, ) -> (Expression, Self::AdditionalOutput)
fn reconstruct_associated_function( &mut self, input: AssociatedFunction, ) -> (Expression, Self::AdditionalOutput)
fn reconstruct_member_access( &mut self, input: MemberAccess, ) -> (Expression, Self::AdditionalOutput)
fn reconstruct_tuple_access( &mut self, input: TupleAccess, ) -> (Expression, Self::AdditionalOutput)
fn reconstruct_array( &mut self, input: ArrayExpression, ) -> (Expression, Self::AdditionalOutput)
fn reconstruct_binary( &mut self, input: BinaryExpression, ) -> (Expression, Self::AdditionalOutput)
fn reconstruct_call( &mut self, input: CallExpression, ) -> (Expression, Self::AdditionalOutput)
fn reconstruct_cast( &mut self, input: CastExpression, ) -> (Expression, Self::AdditionalOutput)
fn reconstruct_err( &mut self, _input: ErrExpression, ) -> (Expression, Self::AdditionalOutput)
fn reconstruct_identifier( &mut self, input: Identifier, ) -> (Expression, Self::AdditionalOutput)
fn reconstruct_literal( &mut self, input: Literal, ) -> (Expression, Self::AdditionalOutput)
fn reconstruct_locator( &mut self, input: LocatorExpression, ) -> (Expression, Self::AdditionalOutput)
fn reconstruct_tuple( &mut self, input: TupleExpression, ) -> (Expression, Self::AdditionalOutput)
fn reconstruct_unary( &mut self, input: UnaryExpression, ) -> (Expression, Self::AdditionalOutput)
fn reconstruct_unit( &mut self, input: UnitExpression, ) -> (Expression, Self::AdditionalOutput)
Source§impl ProgramReconstructor for Flattener<'_>
impl ProgramReconstructor for Flattener<'_>
Source§fn reconstruct_program_scope(&mut self, input: ProgramScope) -> ProgramScope
fn reconstruct_program_scope(&mut self, input: ProgramScope) -> ProgramScope
Flattens a program scope.
Source§fn reconstruct_function(&mut self, function: Function) -> Function
fn reconstruct_function(&mut self, function: Function) -> Function
Flattens a function’s body
fn reconstruct_program(&mut self, input: Program) -> Program
fn reconstruct_stub(&mut self, input: Stub) -> Stub
fn reconstruct_function_stub(&mut self, input: FunctionStub) -> FunctionStub
fn reconstruct_struct(&mut self, input: Composite) -> Composite
fn reconstruct_import(&mut self, input: Program) -> Program
fn reconstruct_mapping(&mut self, input: Mapping) -> Mapping
Source§impl StatementReconstructor for Flattener<'_>
impl StatementReconstructor for Flattener<'_>
Source§fn reconstruct_assert(
&mut self,
input: AssertStatement,
) -> (Statement, Self::AdditionalOutput)
fn reconstruct_assert( &mut self, input: AssertStatement, ) -> (Statement, Self::AdditionalOutput)
Rewrites an assert statement into a flattened form. Assert statements at the top level only have their arguments flattened. Assert statements inside a conditional statement are flattened to such that the check is conditional on the execution path being valid. For example, the following snippet:
if condition1 {
if condition2 {
assert(foo);
}
}
is flattened to:
assert(!(condition1 && condition2) || foo);
which is equivalent to the logical formula (condition1 /\ condition2) ==> foo
.
Source§fn reconstruct_assign(
&mut self,
assign: AssignStatement,
) -> (Statement, Self::AdditionalOutput)
fn reconstruct_assign( &mut self, assign: AssignStatement, ) -> (Statement, Self::AdditionalOutput)
Flattens an assign statement, if necessary. Marks variables as structs as necessary. Note that new statements are only produced if the right hand side is a ternary expression over structs. Otherwise, the statement is returned as is.
Source§fn reconstruct_block(&mut self, block: Block) -> (Block, Self::AdditionalOutput)
fn reconstruct_block(&mut self, block: Block) -> (Block, Self::AdditionalOutput)
Flattens the statements inside a basic block. The resulting block does not contain any conditional statements.
Source§fn reconstruct_conditional(
&mut self,
conditional: ConditionalStatement,
) -> (Statement, Self::AdditionalOutput)
fn reconstruct_conditional( &mut self, conditional: ConditionalStatement, ) -> (Statement, Self::AdditionalOutput)
Flatten a conditional statement into a list of statements.
Source§fn reconstruct_return(
&mut self,
input: ReturnStatement,
) -> (Statement, Self::AdditionalOutput)
fn reconstruct_return( &mut self, input: ReturnStatement, ) -> (Statement, Self::AdditionalOutput)
Transforms a return statement into an empty block statement. Stores the arguments to the return statement, which are later folded into a single return statement at the end of the function.
fn reconstruct_console( &mut self, _: ConsoleStatement, ) -> (Statement, Self::AdditionalOutput)
fn reconstruct_definition( &mut self, _definition: DefinitionStatement, ) -> (Statement, Self::AdditionalOutput)
fn reconstruct_iteration( &mut self, _input: IterationStatement, ) -> (Statement, Self::AdditionalOutput)
fn reconstruct_statement( &mut self, input: Statement, ) -> (Statement, Self::AdditionalOutput)
fn reconstruct_const( &mut self, input: ConstDeclaration, ) -> (Statement, Self::AdditionalOutput)
fn reconstruct_expression_statement( &mut self, input: ExpressionStatement, ) -> (Statement, Self::AdditionalOutput)
Auto Trait Implementations§
impl<'a> Freeze for Flattener<'a>
impl<'a> !RefUnwindSafe for Flattener<'a>
impl<'a> !Send for Flattener<'a>
impl<'a> !Sync for Flattener<'a>
impl<'a> Unpin for Flattener<'a>
impl<'a> !UnwindSafe for Flattener<'a>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more