mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-24 02:31:44 +03:00
Removed old Visitor and Reducer files
This commit is contained in:
parent
e6794a0dec
commit
a60439eb8a
@ -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::*;
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
@ -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() })
|
||||
}
|
||||
}
|
@ -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(_, _) => {}
|
||||
};
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user