Removed old Visitor and Reducer files

This commit is contained in:
Pranav Gaddamadugu 2022-07-01 11:54:44 -07:00
parent e6794a0dec
commit a60439eb8a
4 changed files with 2 additions and 914 deletions

View File

@ -19,14 +19,8 @@
// todo @gluax: Move the files in this module into `leo-passes` in a future PR.
// pub mod reconstructing_reducer;
// pub use reconstructing_reducer::*;
//
// pub mod reconstructing_director;
// pub use reconstructing_director::*;
pub mod reconstructor;
pub use reconstructor::*;
pub mod visitor;
pub use visitor::*;
pub mod visitor_director;
pub use visitor_director::*;

View File

@ -1,340 +0,0 @@
// Copyright (C) 2019-2022 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// 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/>.
//! This module contains a Director for how to map over the AST
//! and applies a reducer call to each node.
use crate::*;
use leo_errors::{AstError, Result};
use leo_span::Span;
use indexmap::IndexMap;
pub struct ReconstructingDirector<R: ReconstructingReducer> {
reducer: R,
}
impl<R: ReconstructingReducer> ReconstructingDirector<R> {
pub fn new(reducer: R) -> Self {
Self { reducer }
}
pub fn reduce_type(&mut self, type_: &Type, span: &Span) -> Result<Type> {
self.reducer.reduce_type(type_, *type_, span)
}
// Expressions
pub fn reduce_expression(&mut self, expression: &Expression) -> Result<Expression> {
let new = match expression {
Expression::Identifier(identifier) => Expression::Identifier(self.reduce_identifier(identifier)?),
Expression::Literal(lit) => self.reduce_literal(lit)?,
Expression::Binary(binary) => Expression::Binary(self.reduce_binary(binary)?),
Expression::Unary(unary) => Expression::Unary(self.reduce_unary(unary)?),
Expression::Ternary(ternary) => Expression::Ternary(self.reduce_ternary(ternary)?),
Expression::Call(call) => Expression::Call(self.reduce_call(call)?),
Expression::CircuitInit(circuit_init) => Expression::CircuitInit(self.reduce_circuit_init(circuit_init)?),
Expression::Err(s) => Expression::Err(s.clone()),
};
self.reducer.reduce_expression(expression, new)
}
pub fn reduce_identifier(&mut self, identifier: &Identifier) -> Result<Identifier> {
self.reducer.reduce_identifier(identifier)
}
pub fn reduce_group_tuple(&mut self, group_tuple: &GroupTuple) -> Result<GroupTuple> {
self.reducer.reduce_group_tuple(group_tuple)
}
pub fn reduce_group_literal(&mut self, group_lit: &GroupLiteral) -> Result<GroupLiteral> {
let new = match group_lit {
GroupLiteral::Tuple(group_tuple) => GroupLiteral::Tuple(self.reduce_group_tuple(group_tuple)?),
_ => group_lit.clone(),
};
self.reducer.reduce_group_literal(group_lit, new)
}
pub fn reduce_string(&mut self, string: &str, span: &Span) -> Result<Expression> {
self.reducer.reduce_string(string, span)
}
pub fn reduce_literal(&mut self, lit: &LiteralExpression) -> Result<Expression> {
let new = match lit {
LiteralExpression::Group(group_value) => Expression::Literal(LiteralExpression::Group(Box::new(
self.reduce_group_literal(group_value)?,
))),
LiteralExpression::String(string, span) => self.reduce_string(string, span)?,
_ => Expression::Literal(lit.clone()),
};
self.reducer.reduce_literal(lit, new)
}
pub fn reduce_binary(&mut self, binary: &BinaryExpression) -> Result<BinaryExpression> {
let left = self.reduce_expression(&binary.left)?;
let right = self.reduce_expression(&binary.right)?;
self.reducer.reduce_binary(binary, left, right, binary.op)
}
pub fn reduce_unary(&mut self, unary: &UnaryExpression) -> Result<UnaryExpression> {
let inner = self.reduce_expression(&unary.receiver)?;
self.reducer.reduce_unary(unary, inner, unary.op)
}
pub fn reduce_ternary(&mut self, ternary: &TernaryExpression) -> Result<TernaryExpression> {
let condition = self.reduce_expression(&ternary.condition)?;
let if_true = self.reduce_expression(&ternary.if_true)?;
let if_false = self.reduce_expression(&ternary.if_false)?;
self.reducer.reduce_ternary(ternary, condition, if_true, if_false)
}
pub fn reduce_call(&mut self, call: &CallExpression) -> Result<CallExpression> {
let function = self.reduce_expression(&call.function)?;
let mut arguments = vec![];
for argument in call.arguments.iter() {
arguments.push(self.reduce_expression(argument)?);
}
self.reducer.reduce_call(call, function, arguments)
}
// Statements
pub fn reduce_statement(&mut self, statement: &Statement) -> Result<Statement> {
let new = match statement {
Statement::Return(return_statement) => Statement::Return(self.reduce_return(return_statement)?),
Statement::Definition(definition) => Statement::Definition(self.reduce_definition(definition)?),
Statement::Assign(assign) => Statement::Assign(Box::new(self.reduce_assign(assign)?)),
Statement::Conditional(conditional) => Statement::Conditional(self.reduce_conditional(conditional)?),
Statement::Iteration(iteration) => Statement::Iteration(Box::new(self.reduce_iteration(iteration)?)),
Statement::Console(console) => Statement::Console(self.reduce_console(console)?),
Statement::Block(block) => Statement::Block(self.reduce_block(block)?),
};
self.reducer.reduce_statement(statement, new)
}
pub fn reduce_return(&mut self, return_statement: &ReturnStatement) -> Result<ReturnStatement> {
let expression = self.reduce_expression(&return_statement.expression)?;
self.reducer.reduce_return(return_statement, expression)
}
pub fn reduce_variable_name(&mut self, variable_name: &VariableName) -> Result<VariableName> {
let identifier = self.reduce_identifier(&variable_name.identifier)?;
self.reducer.reduce_variable_name(variable_name, identifier)
}
pub fn reduce_definition(&mut self, definition: &DefinitionStatement) -> Result<DefinitionStatement> {
let mut variable_names = vec![];
for variable_name in definition.variable_names.iter() {
variable_names.push(self.reduce_variable_name(variable_name)?);
}
let type_ = self.reduce_type(&definition.type_, &definition.span)?;
let value = self.reduce_expression(&definition.value)?;
self.reducer.reduce_definition(definition, variable_names, type_, value)
}
pub fn reduce_assign(&mut self, assign: &AssignStatement) -> Result<AssignStatement> {
let place = self.reduce_expression(&assign.place)?;
let value = self.reduce_expression(&assign.value)?;
self.reducer.reduce_assign(assign, place, value)
}
pub fn reduce_conditional(&mut self, conditional: &ConditionalStatement) -> Result<ConditionalStatement> {
let condition = self.reduce_expression(&conditional.condition)?;
let block = self.reduce_block(&conditional.block)?;
let next = conditional
.next
.as_ref()
.map(|condition| self.reduce_statement(condition))
.transpose()?;
self.reducer.reduce_conditional(conditional, condition, block, next)
}
pub fn reduce_iteration(&mut self, iteration: &IterationStatement) -> Result<IterationStatement> {
let variable = self.reduce_identifier(&iteration.variable)?;
let type_ = self.reduce_type(&iteration.type_, &iteration.span())?;
let start = self.reduce_expression(&iteration.start)?;
let stop = self.reduce_expression(&iteration.stop)?;
let block = self.reduce_block(&iteration.block)?;
self.reducer
.reduce_iteration(iteration, variable, type_, start, stop, block)
}
pub fn reduce_console(&mut self, console_function_call: &ConsoleStatement) -> Result<ConsoleStatement> {
let function = match &console_function_call.function {
ConsoleFunction::Assert(expression) => ConsoleFunction::Assert(self.reduce_expression(expression)?),
ConsoleFunction::Error(args) | ConsoleFunction::Log(args) => {
let mut parameters = vec![];
for parameter in args.parameters.iter() {
parameters.push(self.reduce_expression(parameter)?);
}
let formatted = ConsoleArgs {
string: args.string.clone(),
parameters,
span: args.span,
};
match &console_function_call.function {
ConsoleFunction::Error(_) => ConsoleFunction::Error(formatted),
ConsoleFunction::Log(_) => ConsoleFunction::Log(formatted),
_ => return Err(AstError::impossible_console_assert_call(args.span).into()),
}
}
};
self.reducer.reduce_console(console_function_call, function)
}
pub fn reduce_block(&mut self, block: &Block) -> Result<Block> {
let mut statements = vec![];
for statement in block.statements.iter() {
statements.push(self.reduce_statement(statement)?);
}
self.reducer.reduce_block(block, statements)
}
// Program
pub fn reduce_program(&mut self, program: &Program) -> Result<Program> {
let mut inputs = vec![];
for input in program.expected_input.iter() {
inputs.push(self.reduce_function_input(input)?);
}
let mut functions = IndexMap::new();
let mut circuits = IndexMap::new();
for (name, function) in program.functions.iter() {
functions.insert(*name, self.reduce_function(function)?);
}
for (name, circuit) in program.circuits.iter() {
circuits.insert(*name, self.reduce_circuit(circuit)?);
}
self.reducer.reduce_program(program, inputs, functions, circuits)
}
// Functions
pub fn reduce_function_input_variable(
&mut self,
variable: &FunctionInputVariable,
) -> Result<FunctionInputVariable> {
let identifier = self.reduce_identifier(&variable.identifier)?;
let type_ = self.reduce_type(&variable.type_, &variable.span)?;
self.reducer.reduce_function_input_variable(variable, identifier, type_)
}
pub fn reduce_function_input(&mut self, input: &FunctionInput) -> Result<FunctionInput> {
let new = match input {
FunctionInput::Variable(function_input_variable) => {
FunctionInput::Variable(self.reduce_function_input_variable(function_input_variable)?)
}
};
self.reducer.reduce_function_input(input, new)
}
pub fn reduce_function(&mut self, function: &Function) -> Result<Function> {
let identifier = self.reduce_identifier(&function.identifier)?;
let mut inputs = vec![];
for input in function.input.iter() {
inputs.push(self.reduce_function_input(input)?);
}
let output = self.reduce_type(&function.output, &function.span)?;
let block = self.reduce_block(&function.block)?;
self.reducer
.reduce_function(function, identifier, inputs, output, block)
}
// Circuits
pub fn reduce_circuit_variable_initializer(
&mut self,
variable: &CircuitVariableInitializer,
) -> Result<CircuitVariableInitializer> {
let identifier = self.reduce_identifier(&variable.identifier)?;
let expression = variable
.expression
.as_ref()
.map(|expr| self.reduce_expression(expr))
.transpose()?;
self.reducer
.reduce_circuit_variable_initializer(variable, identifier, expression)
}
pub fn reduce_circuit_init(&mut self, circuit_init: &CircuitInitExpression) -> Result<CircuitInitExpression> {
let name = self.reduce_identifier(&circuit_init.name)?;
let mut members = vec![];
for member in circuit_init.members.iter() {
members.push(self.reduce_circuit_variable_initializer(member)?);
}
self.reducer.reduce_circuit_init(circuit_init, name, members)
}
pub fn reduce_circuit_member(&mut self, circuit_member: &CircuitMember) -> Result<CircuitMember> {
let new = match circuit_member {
CircuitMember::CircuitConst(identifier, type_, value) => CircuitMember::CircuitConst(
self.reduce_identifier(identifier)?,
self.reduce_type(type_, &identifier.span)?,
self.reduce_expression(value)?,
),
CircuitMember::CircuitVariable(identifier, type_) => CircuitMember::CircuitVariable(
self.reduce_identifier(identifier)?,
self.reduce_type(type_, &identifier.span)?,
),
CircuitMember::CircuitFunction(function) => {
CircuitMember::CircuitFunction(Box::new(self.reduce_function(function)?))
}
};
self.reducer.reduce_circuit_member(circuit_member, new)
}
pub fn reduce_circuit(&mut self, circuit: &Circuit) -> Result<Circuit> {
let circuit_name = self.reduce_identifier(&circuit.identifier)?;
let mut members = vec![];
for member in circuit.members.iter() {
members.push(self.reduce_circuit_member(member)?);
}
self.reducer.reduce_circuit(circuit, circuit_name, members)
}
}

View File

@ -1,320 +0,0 @@
// Copyright (C) 2019-2022 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// 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/>.
//! This module contains a Reducer Trait for the AST.
//! It implements default methods for each node to be made
//! given the information of the old node.
use crate::*;
use leo_errors::Result;
use leo_span::{Span, Symbol};
use indexmap::IndexMap;
// Needed to fix clippy bug.
#[allow(clippy::redundant_closure)]
pub trait ReconstructingReducer {
fn in_circuit(&self) -> bool;
fn swap_in_circuit(&mut self);
fn reduce_type(&mut self, _type_: &Type, new: Type, _span: &Span) -> Result<Type> {
Ok(new)
}
// Expressions
fn reduce_expression(&mut self, _expression: &Expression, new: Expression) -> Result<Expression> {
Ok(new)
}
fn reduce_identifier(&mut self, identifier: &Identifier) -> Result<Identifier> {
Ok(Identifier {
name: identifier.name,
span: identifier.span,
})
}
fn reduce_group_tuple(&mut self, group_tuple: &GroupTuple) -> Result<GroupTuple> {
Ok(GroupTuple {
x: group_tuple.x.clone(),
y: group_tuple.y.clone(),
span: group_tuple.span,
})
}
fn reduce_group_literal(&mut self, _group_lit: &GroupLiteral, new: GroupLiteral) -> Result<GroupLiteral> {
Ok(new)
}
fn reduce_string(&mut self, string: &str, span: &Span) -> Result<Expression> {
Ok(Expression::Literal(LiteralExpression::String(
string.to_string(),
*span,
)))
}
fn reduce_literal(&mut self, _lit: &LiteralExpression, new: Expression) -> Result<Expression> {
Ok(new)
}
fn reduce_binary(
&mut self,
binary: &BinaryExpression,
left: Expression,
right: Expression,
op: BinaryOperation,
) -> Result<BinaryExpression> {
Ok(BinaryExpression {
left: Box::new(left),
right: Box::new(right),
op,
span: binary.span,
})
}
fn reduce_unary(
&mut self,
unary: &UnaryExpression,
inner: Expression,
op: UnaryOperation,
) -> Result<UnaryExpression> {
Ok(UnaryExpression {
receiver: Box::new(inner),
op,
span: unary.span,
})
}
fn reduce_ternary(
&mut self,
ternary: &TernaryExpression,
condition: Expression,
if_true: Expression,
if_false: Expression,
) -> Result<TernaryExpression> {
Ok(TernaryExpression {
condition: Box::new(condition),
if_true: Box::new(if_true),
if_false: Box::new(if_false),
span: ternary.span,
})
}
fn reduce_call(
&mut self,
call: &CallExpression,
function: Expression,
arguments: Vec<Expression>,
) -> Result<CallExpression> {
Ok(CallExpression {
function: Box::new(function),
arguments,
span: call.span,
})
}
// Statements
fn reduce_statement(&mut self, _statement: &Statement, new: Statement) -> Result<Statement> {
Ok(new)
}
fn reduce_return(&mut self, return_statement: &ReturnStatement, expression: Expression) -> Result<ReturnStatement> {
Ok(ReturnStatement {
expression,
span: return_statement.span,
})
}
fn reduce_variable_name(&mut self, variable_name: &VariableName, identifier: Identifier) -> Result<VariableName> {
Ok(VariableName {
mutable: variable_name.mutable,
identifier,
span: variable_name.span,
})
}
fn reduce_definition(
&mut self,
definition: &DefinitionStatement,
variable_names: Vec<VariableName>,
type_: Type,
value: Expression,
) -> Result<DefinitionStatement> {
Ok(DefinitionStatement {
declaration_type: definition.declaration_type,
variable_names,
type_,
value,
span: definition.span,
})
}
fn reduce_assign(
&mut self,
assign: &AssignStatement,
place: Expression,
value: Expression,
) -> Result<AssignStatement> {
Ok(AssignStatement {
operation: assign.operation,
place,
value,
span: assign.span,
})
}
fn reduce_conditional(
&mut self,
conditional: &ConditionalStatement,
condition: Expression,
block: Block,
statement: Option<Statement>,
) -> Result<ConditionalStatement> {
Ok(ConditionalStatement {
condition,
block,
next: statement.map(|statement| Box::new(statement)),
span: conditional.span,
})
}
fn reduce_iteration(
&mut self,
iteration: &IterationStatement,
variable: Identifier,
type_: Type,
start: Expression,
stop: Expression,
block: Block,
) -> Result<IterationStatement> {
Ok(IterationStatement {
variable,
type_,
start,
stop,
inclusive: iteration.inclusive,
block,
span: iteration.span,
})
}
fn reduce_console(&mut self, console: &ConsoleStatement, function: ConsoleFunction) -> Result<ConsoleStatement> {
Ok(ConsoleStatement {
function,
span: console.span,
})
}
fn reduce_block(&mut self, block: &Block, statements: Vec<Statement>) -> Result<Block> {
Ok(Block {
statements,
span: block.span,
})
}
#[allow(clippy::too_many_arguments)]
// Program
fn reduce_program(
&mut self,
program: &Program,
expected_input: Vec<FunctionInput>,
functions: IndexMap<Identifier, Function>,
circuits: IndexMap<Identifier, Circuit>,
) -> Result<Program> {
Ok(Program {
name: program.name.clone(),
expected_input,
functions,
circuits,
})
}
fn reduce_function_input_variable(
&mut self,
variable: &FunctionInputVariable,
identifier: Identifier,
type_: Type,
) -> Result<FunctionInputVariable> {
Ok(FunctionInputVariable::new(
identifier,
variable.mode(),
type_,
variable.span,
))
}
fn reduce_function_input(&mut self, _input: &FunctionInput, new: FunctionInput) -> Result<FunctionInput> {
Ok(new)
}
fn reduce_import(&mut self, identifier: Vec<Symbol>, import: Program) -> Result<(Vec<Symbol>, Program)> {
Ok((identifier, import))
}
#[allow(clippy::too_many_arguments)]
fn reduce_function(
&mut self,
function: &Function,
identifier: Identifier,
input: Vec<FunctionInput>,
output: Type,
block: Block,
) -> Result<Function> {
Ok(Function {
identifier,
input,
output,
block,
core_mapping: function.core_mapping.clone(),
span: function.span,
})
}
fn reduce_circuit_variable_initializer(
&mut self,
_variable: &CircuitVariableInitializer,
identifier: Identifier,
expression: Option<Expression>,
) -> Result<CircuitVariableInitializer> {
Ok(CircuitVariableInitializer { identifier, expression })
}
fn reduce_circuit_init(
&mut self,
circuit_init: &CircuitInitExpression,
name: Identifier,
members: Vec<CircuitVariableInitializer>,
) -> Result<CircuitInitExpression> {
Ok(CircuitInitExpression {
name,
members,
span: circuit_init.span.clone(),
})
}
fn reduce_circuit_member(&mut self, _circuit_member: &CircuitMember, new: CircuitMember) -> Result<CircuitMember> {
Ok(new)
}
fn reduce_circuit(
&mut self,
circuit: &Circuit,
circuit_name: Identifier,
members: Vec<CircuitMember>,
) -> Result<Circuit> {
Ok(Circuit { identifier: circuit_name, members, span: circuit.span.clone() })
}
}

View File

@ -1,246 +0,0 @@
// Copyright (C) 2019-2022 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// 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/>.
//! This module contains Visitor trait implementations for the AST.
//! It implements default methods for each node to be made
//! given the type of node its visiting.
use crate::*;
pub trait VisitorDirector<'a> {
type Visitor: ExpressionVisitor<'a> + ProgramVisitor<'a> + StatementVisitor<'a>;
fn visitor(self) -> Self::Visitor;
fn visitor_ref(&mut self) -> &mut Self::Visitor;
}
pub trait ExpressionVisitorDirector<'a>: VisitorDirector<'a> {
type AdditionalInput: Default;
type Output;
fn visit_expression(&mut self, input: &'a Expression, additional: &Self::AdditionalInput) -> Option<Self::Output> {
if let VisitResult::VisitChildren = self.visitor_ref().visit_expression(input) {
match input {
Expression::Access(expr) => self.visit_access(expr, additional),
Expression::Identifier(expr) => self.visit_identifier(expr, additional),
Expression::Literal(expr) => self.visit_literal(expr, additional),
Expression::Binary(expr) => self.visit_binary(expr, additional),
Expression::Call(expr) => self.visit_call(expr, additional),
Expression::CircuitInit(expr) => self.visit_circuit_init(expr, additional),
Expression::Err(expr) => self.visit_err(expr, additional),
Expression::Ternary(expr) => self.visit_ternary(expr, additional),
Expression::Unary(expr) => self.visit_unary(expr, additional),
};
}
None
}
fn visit_identifier(&mut self, input: &'a Identifier, _additional: &Self::AdditionalInput) -> Option<Self::Output> {
self.visitor_ref().visit_identifier(input);
None
}
fn visit_literal(
&mut self,
input: &'a LiteralExpression,
_additional: &Self::AdditionalInput,
) -> Option<Self::Output> {
self.visitor_ref().visit_literal(input);
None
}
fn visit_access(
&mut self,
input: &'a AccessExpression,
additional: &Self::AdditionalInput,
) -> Option<Self::Output> {
if let VisitResult::VisitChildren = self.visitor_ref().visit_access(input) {
match input {
AccessExpression::Member(member) => return self.visit_expression(&member.inner, additional),
AccessExpression::AssociatedConstant(_member) => {}
AccessExpression::AssociatedFunction(member) => {
member.args.iter().for_each(|expr| {
self.visit_expression(expr, additional);
});
}
};
}
None
}
fn visit_binary(
&mut self,
input: &'a BinaryExpression,
additional: &Self::AdditionalInput,
) -> Option<Self::Output> {
if let VisitResult::VisitChildren = self.visitor_ref().visit_binary(input) {
self.visit_expression(&input.left, additional);
self.visit_expression(&input.right, additional);
}
None
}
fn visit_unary(&mut self, input: &'a UnaryExpression, additional: &Self::AdditionalInput) -> Option<Self::Output> {
if let VisitResult::VisitChildren = self.visitor_ref().visit_unary(input) {
self.visit_expression(&input.receiver, additional);
}
None
}
fn visit_ternary(
&mut self,
input: &'a TernaryExpression,
additional: &Self::AdditionalInput,
) -> Option<Self::Output> {
if let VisitResult::VisitChildren = self.visitor_ref().visit_ternary(input) {
self.visit_expression(&input.condition, additional);
self.visit_expression(&input.if_true, additional);
self.visit_expression(&input.if_false, additional);
}
None
}
fn visit_call(&mut self, input: &'a CallExpression, additional: &Self::AdditionalInput) -> Option<Self::Output> {
if let VisitResult::VisitChildren = self.visitor_ref().visit_call(input) {
input.arguments.iter().for_each(|expr| {
self.visit_expression(expr, additional);
});
}
None
}
fn visit_circuit_init(
&mut self,
input: &'a CircuitInitExpression,
additional: &Self::AdditionalInput,
) -> Option<Self::Output> {
if let VisitResult::VisitChildren = self.visitor_ref().visit_circuit_init(input) {
input.members.iter().for_each(|member| {
if let Some(expr) = &member.expression {
self.visit_expression(expr, additional);
}
});
}
None
}
fn visit_err(&mut self, input: &'a ErrExpression, _additional: &Self::AdditionalInput) -> Option<Self::Output> {
self.visitor_ref().visit_err(input);
None
}
}
pub trait StatementVisitorDirector<'a>: VisitorDirector<'a> + ExpressionVisitorDirector<'a> {
fn visit_statement(&mut self, input: &'a Statement) {
if let VisitResult::VisitChildren = self.visitor_ref().visit_statement(input) {
match input {
Statement::Return(stmt) => self.visit_return(stmt),
Statement::Definition(stmt) => self.visit_definition(stmt),
Statement::Assign(stmt) => self.visit_assign(stmt),
Statement::Conditional(stmt) => self.visit_conditional(stmt),
Statement::Iteration(stmt) => self.visit_iteration(stmt),
Statement::Console(stmt) => self.visit_console(stmt),
Statement::Block(stmt) => self.visit_block(stmt),
}
}
}
fn visit_return(&mut self, input: &'a ReturnStatement) {
if let VisitResult::VisitChildren = self.visitor_ref().visit_return(input) {
self.visit_expression(&input.expression, &Default::default());
}
}
fn visit_definition(&mut self, input: &'a DefinitionStatement) {
if let VisitResult::VisitChildren = self.visitor_ref().visit_definition(input) {
self.visit_expression(&input.value, &Default::default());
}
}
fn visit_assign(&mut self, input: &'a AssignStatement) {
if let VisitResult::VisitChildren = self.visitor_ref().visit_assign(input) {
self.visit_expression(&input.value, &Default::default());
}
}
fn visit_conditional(&mut self, input: &'a ConditionalStatement) {
if let VisitResult::VisitChildren = self.visitor_ref().visit_conditional(input) {
self.visit_expression(&input.condition, &Default::default());
self.visit_block(&input.block);
if let Some(stmt) = input.next.as_ref() {
self.visit_statement(stmt);
}
}
}
fn visit_iteration(&mut self, input: &'a IterationStatement) {
if let VisitResult::VisitChildren = self.visitor_ref().visit_iteration(input) {
self.visit_expression(&input.start, &Default::default());
self.visit_expression(&input.stop, &Default::default());
self.visit_block(&input.block);
}
}
fn visit_console(&mut self, input: &'a ConsoleStatement) {
if let VisitResult::VisitChildren = self.visitor_ref().visit_console(input) {
match &input.function {
ConsoleFunction::Assert(expr) => self.visit_expression(expr, &Default::default()),
ConsoleFunction::Error(fmt) | ConsoleFunction::Log(fmt) => {
fmt.parameters.iter().for_each(|expr| {
self.visit_expression(expr, &Default::default());
});
None
}
};
}
}
fn visit_block(&mut self, input: &'a Block) {
if let VisitResult::VisitChildren = self.visitor_ref().visit_block(input) {
input.statements.iter().for_each(|stmt| self.visit_statement(stmt));
}
}
}
pub trait ProgramVisitorDirector<'a>: VisitorDirector<'a> + StatementVisitorDirector<'a> {
fn visit_program(&mut self, input: &'a Program) {
if let VisitResult::VisitChildren = self.visitor_ref().visit_program(input) {
input
.functions
.values()
.for_each(|function| self.visit_function(function));
input.circuits.values().for_each(|circuit| self.visit_circuit(circuit));
}
}
fn visit_function(&mut self, input: &'a Function) {
if let VisitResult::VisitChildren = self.visitor_ref().visit_function(input) {
self.visit_block(&input.block);
}
}
fn visit_circuit(&mut self, input: &'a Circuit) {
if let VisitResult::VisitChildren = self.visitor_ref().visit_circuit(input) {
input.members.iter().for_each(|member| {
match member {
CircuitMember::CircuitVariable(_, _) => {}
};
})
}
}
}