mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-24 07:48:04 +03:00
reducer clean up
This commit is contained in:
parent
476307fffc
commit
250c8ce5ec
@ -14,29 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// 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/>.
|
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//! This module contains the reducer which iterates through ast nodes - converting them into
|
use crate::*;
|
||||||
//! asg nodes and saving relevant information.
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
reducer::ReconstructingReducer,
|
|
||||||
Block,
|
|
||||||
CallExpression,
|
|
||||||
Circuit,
|
|
||||||
CircuitInitExpression,
|
|
||||||
CircuitMember,
|
|
||||||
CircuitMemberAccessExpression,
|
|
||||||
CircuitStaticFunctionAccessExpression,
|
|
||||||
DefinitionStatement,
|
|
||||||
Expression,
|
|
||||||
ExpressionStatement,
|
|
||||||
Function,
|
|
||||||
FunctionInput,
|
|
||||||
FunctionInputVariable,
|
|
||||||
Identifier,
|
|
||||||
ReturnStatement,
|
|
||||||
Statement,
|
|
||||||
Type,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct Canonicalizer;
|
pub struct Canonicalizer;
|
||||||
|
|
||||||
@ -45,16 +23,6 @@ impl Canonicalizer {
|
|||||||
matches!(identifier.name.as_str(), "Self")
|
matches!(identifier.name.as_str(), "Self")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _is_self_keyword(&self, function_inputs: &[FunctionInput]) -> bool {
|
|
||||||
for function_input in function_inputs {
|
|
||||||
if let FunctionInput::SelfKeyword(_) = function_input {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_self_type(&self, type_option: Option<&Type>) -> bool {
|
fn is_self_type(&self, type_option: Option<&Type>) -> bool {
|
||||||
matches!(type_option, Some(Type::SelfType))
|
matches!(type_option, Some(Type::SelfType))
|
||||||
}
|
}
|
||||||
@ -184,14 +152,6 @@ impl Canonicalizer {
|
|||||||
span: function.block.span.clone(),
|
span: function.block.span.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// probably shouldn't do this its self not Self
|
|
||||||
// if self.is_self_keyword(&input) {
|
|
||||||
// input = input
|
|
||||||
// .iter()
|
|
||||||
// .map(|function_input| self.canonicalize_function_input(function_input, circuit_name))
|
|
||||||
// .collect();
|
|
||||||
// }
|
|
||||||
|
|
||||||
if self.is_self_type(output.as_ref()) {
|
if self.is_self_type(output.as_ref()) {
|
||||||
output = Some(Type::Circuit(circuit_name.clone()));
|
output = Some(Type::Circuit(circuit_name.clone()));
|
||||||
}
|
}
|
||||||
@ -212,22 +172,15 @@ impl Canonicalizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ReconstructingReducer for Canonicalizer {
|
impl ReconstructingReducer for Canonicalizer {
|
||||||
fn reduce_circuit(
|
fn reduce_circuit(&mut self, _circuit: &Circuit, circuit_name: Identifier, members: Vec<CircuitMember>) -> Circuit {
|
||||||
&mut self,
|
Circuit {
|
||||||
_: &Circuit,
|
|
||||||
circuit_name: Identifier,
|
|
||||||
members: Vec<CircuitMember>,
|
|
||||||
) -> Option<Circuit> {
|
|
||||||
let new_circuit = Circuit {
|
|
||||||
circuit_name: circuit_name.clone(),
|
circuit_name: circuit_name.clone(),
|
||||||
members: members
|
members: members
|
||||||
.iter()
|
.iter()
|
||||||
.map(|member| self.canonicalize_circuit_member(member, &circuit_name))
|
.map(|member| self.canonicalize_circuit_member(member, &circuit_name))
|
||||||
.collect(),
|
.collect(),
|
||||||
};
|
}
|
||||||
|
|
||||||
Some(new_circuit)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO make all self/Self outside of circuit error out
|
// fn reduce_program(program: &Program, expected_input: Vec<FunctionInput>, imports: Vec<ImportStatement>, circuits: IndexMap<Identifier, Circuit>, functions: IndexMap<Identifier, Function>)
|
||||||
}
|
}
|
||||||
|
@ -14,21 +14,9 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// 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/>.
|
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//! This module contains the reducer which iterates through ast nodes - converting them into
|
|
||||||
//! asg nodes and saving relevant information.
|
|
||||||
|
|
||||||
mod canonicalization;
|
mod canonicalization;
|
||||||
pub use canonicalization::*;
|
pub use canonicalization::*;
|
||||||
|
|
||||||
mod monoid;
|
|
||||||
pub use monoid::*;
|
|
||||||
|
|
||||||
mod monoidal_director;
|
|
||||||
pub use monoidal_director::*;
|
|
||||||
|
|
||||||
mod monoidal_reducer;
|
|
||||||
pub use monoidal_reducer::*;
|
|
||||||
|
|
||||||
mod reconstructing_reducer;
|
mod reconstructing_reducer;
|
||||||
pub use reconstructing_reducer::*;
|
pub use reconstructing_reducer::*;
|
||||||
|
|
||||||
|
@ -1,68 +0,0 @@
|
|||||||
// Copyright (C) 2019-2021 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 the reducer which iterates through ast nodes - converting them into
|
|
||||||
//! asg nodes and saving relevant information.
|
|
||||||
|
|
||||||
pub trait Monoid: Default {
|
|
||||||
fn append(self, other: Self) -> Self;
|
|
||||||
|
|
||||||
fn append_all(self, others: impl Iterator<Item = Self>) -> Self {
|
|
||||||
let mut current = self;
|
|
||||||
for item in others {
|
|
||||||
current = current.append(item);
|
|
||||||
}
|
|
||||||
current
|
|
||||||
}
|
|
||||||
|
|
||||||
fn append_option(self, other: Option<Self>) -> Self {
|
|
||||||
match other {
|
|
||||||
None => self,
|
|
||||||
Some(other) => self.append(other),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct VecAppend<T>(Vec<T>);
|
|
||||||
|
|
||||||
impl<T> Default for VecAppend<T> {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self(vec![])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Monoid for VecAppend<T> {
|
|
||||||
fn append(mut self, other: Self) -> Self {
|
|
||||||
self.0.extend(other.0);
|
|
||||||
VecAppend(self.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn append_all(mut self, others: impl Iterator<Item = Self>) -> Self {
|
|
||||||
let all: Vec<Vec<T>> = others.map(|x| x.0).collect();
|
|
||||||
let total_size = all.iter().fold(0, |acc, v| acc + v.len());
|
|
||||||
self.0.reserve(total_size);
|
|
||||||
for item in all.into_iter() {
|
|
||||||
self.0.extend(item);
|
|
||||||
}
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Into<Vec<T>> for VecAppend<T> {
|
|
||||||
fn into(self) -> Vec<T> {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,433 +0,0 @@
|
|||||||
// Copyright (C) 2019-2021 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 the reducer which iterates through ast nodes - converting them into
|
|
||||||
//! asg nodes and saving relevant information.
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
reducer::*,
|
|
||||||
AssigneeAccess,
|
|
||||||
Circuit,
|
|
||||||
CircuitMember,
|
|
||||||
ConditionalStatement,
|
|
||||||
ConsoleFunction,
|
|
||||||
Expression,
|
|
||||||
Function,
|
|
||||||
FunctionInput,
|
|
||||||
FunctionInputVariable,
|
|
||||||
GroupCoordinate,
|
|
||||||
GroupValue,
|
|
||||||
Identifier,
|
|
||||||
ImportStatement,
|
|
||||||
IntegerType,
|
|
||||||
Monoid,
|
|
||||||
PackageOrPackages,
|
|
||||||
Program,
|
|
||||||
SpreadOrExpression,
|
|
||||||
Statement,
|
|
||||||
Type,
|
|
||||||
ValueExpression,
|
|
||||||
VariableName,
|
|
||||||
};
|
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
pub struct MonoidalDirector<T: Monoid, R: MonoidalReducer<T>> {
|
|
||||||
reducer: R,
|
|
||||||
_monoid: PhantomData<T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Monoid, R: MonoidalReducer<T>> MonoidalDirector<T, R> {
|
|
||||||
pub fn new(reducer: R) -> Self {
|
|
||||||
Self {
|
|
||||||
reducer,
|
|
||||||
_monoid: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reduce_program(&mut self, program: &Program) -> T {
|
|
||||||
let inputs = program
|
|
||||||
.expected_input
|
|
||||||
.iter()
|
|
||||||
.map(|x| self.reduce_function_input(x))
|
|
||||||
.collect();
|
|
||||||
let imports = program
|
|
||||||
.imports
|
|
||||||
.iter()
|
|
||||||
.map(|x| self.reduce_import_statement(x))
|
|
||||||
.collect();
|
|
||||||
let circuits = program
|
|
||||||
.circuits
|
|
||||||
.iter()
|
|
||||||
.map(|(identifier, circuit)| {
|
|
||||||
(
|
|
||||||
identifier.name.clone(),
|
|
||||||
(self.reduce_identifier(identifier), self.reduce_circuit(circuit)),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
let functions = program
|
|
||||||
.functions
|
|
||||||
.iter()
|
|
||||||
.map(|(identifier, function)| {
|
|
||||||
(
|
|
||||||
identifier.name.clone(),
|
|
||||||
(self.reduce_identifier(identifier), self.reduce_function(function)),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
self.reducer
|
|
||||||
.reduce_program(program, inputs, imports, circuits, functions)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reduce_function_input(&mut self, input: &FunctionInput) -> T {
|
|
||||||
let item = match input {
|
|
||||||
FunctionInput::InputKeyword(_) => FunctionInputItem::InputKeyword,
|
|
||||||
FunctionInput::SelfKeyword(_) => FunctionInputItem::SelfKeyword,
|
|
||||||
FunctionInput::MutSelfKeyword(_) => FunctionInputItem::MutSelfKeyword,
|
|
||||||
FunctionInput::Variable(function_input_variable) => {
|
|
||||||
FunctionInputItem::Variable(self.reduce_function_input_variable(function_input_variable))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
self.reducer.reduce_function_input(input, item)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reduce_import_statement(&mut self, import: &ImportStatement) -> T {
|
|
||||||
let package = self.reduce_package(&import.package_or_packages);
|
|
||||||
|
|
||||||
self.reducer.reduce_import_statement(import, package)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reduce_circuit(&mut self, circuit: &Circuit) -> T {
|
|
||||||
let circuit_name = self.reduce_identifier(&circuit.circuit_name);
|
|
||||||
let members = circuit.members.iter().map(|x| self.reduce_circuit_member(x)).collect();
|
|
||||||
|
|
||||||
self.reducer.reduce_circuit(circuit, circuit_name, members)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reduce_function(&mut self, function: &Function) -> T {
|
|
||||||
let identifier = self.reduce_identifier(&function.identifier);
|
|
||||||
let input = function.input.iter().map(|x| self.reduce_function_input(x)).collect();
|
|
||||||
let output = function.output.as_ref().map(|x| self.reduce_type(x));
|
|
||||||
let statements = function
|
|
||||||
.block
|
|
||||||
.statements
|
|
||||||
.iter()
|
|
||||||
.map(|x| self.reduce_statement(x))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
self.reducer
|
|
||||||
.reduce_function(function, identifier, input, output, statements)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reduce_identifier(&mut self, identifier: &Identifier) -> T {
|
|
||||||
self.reducer.reduce_identifier(identifier)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reduce_integer_type(&mut self, integer_type: &IntegerType) -> T {
|
|
||||||
self.reducer.reduce_integer_type(integer_type)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reduce_function_input_variable(&mut self, function_input_variable: &FunctionInputVariable) -> T {
|
|
||||||
let identifier = self.reduce_identifier(&function_input_variable.identifier);
|
|
||||||
let type_ = self.reduce_type(&function_input_variable.type_);
|
|
||||||
|
|
||||||
self.reducer
|
|
||||||
.reduce_function_input_variable(function_input_variable, identifier, type_)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reduce_type(&mut self, type_: &Type) -> T {
|
|
||||||
let items = match type_ {
|
|
||||||
Type::Array(type_, _) => TypeMonoidItems::Array(self.reduce_type(type_)),
|
|
||||||
Type::Tuple(types) => TypeMonoidItems::Tuple(types.iter().map(|x| self.reduce_type(x)).collect()),
|
|
||||||
Type::Circuit(identifier) => TypeMonoidItems::Identifier(self.reduce_identifier(identifier)),
|
|
||||||
_ => TypeMonoidItems::None,
|
|
||||||
};
|
|
||||||
|
|
||||||
self.reducer.reduce_type(type_, items)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reduce_package(&mut self, package_or_packages: &PackageOrPackages) -> T {
|
|
||||||
match package_or_packages {
|
|
||||||
PackageOrPackages::Package(package) => {
|
|
||||||
let name = self.reduce_identifier(&package.name);
|
|
||||||
|
|
||||||
self.reducer.reduce_package(package, name)
|
|
||||||
}
|
|
||||||
PackageOrPackages::Packages(packages) => {
|
|
||||||
let name = self.reduce_identifier(&packages.name);
|
|
||||||
|
|
||||||
self.reducer.reduce_packages(packages, name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reduce_circuit_member(&mut self, circuit_member: &CircuitMember) -> T {
|
|
||||||
let items = match circuit_member {
|
|
||||||
CircuitMember::CircuitVariable(identifier, type_) => CircuitMemberMonoidItems::Variable {
|
|
||||||
identifier: self.reduce_identifier(identifier),
|
|
||||||
type_: self.reduce_type(type_),
|
|
||||||
},
|
|
||||||
CircuitMember::CircuitFunction(function) => {
|
|
||||||
CircuitMemberMonoidItems::Function(self.reduce_function(function))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
self.reducer.reduce_circuit_member(circuit_member, items)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reduce_statement(&mut self, statement: &Statement) -> T {
|
|
||||||
let items = match statement {
|
|
||||||
Statement::Return(ret) => StatementMonoidItems::Return(self.reduce_expression(&ret.expression)),
|
|
||||||
Statement::Definition(definition) => StatementMonoidItems::Definition {
|
|
||||||
variables: self.reduce_variable_names(&definition.variable_names),
|
|
||||||
expression: self.reduce_expression(&definition.value),
|
|
||||||
},
|
|
||||||
Statement::Assign(assign) => StatementMonoidItems::Assign {
|
|
||||||
assignee: self.reduce_identifier(&assign.assignee.identifier),
|
|
||||||
assignee_accesses: assign
|
|
||||||
.assignee
|
|
||||||
.accesses
|
|
||||||
.iter()
|
|
||||||
.map(|x| self.reduce_assignee_access(x))
|
|
||||||
.collect(),
|
|
||||||
expression: self.reduce_expression(&assign.value),
|
|
||||||
},
|
|
||||||
Statement::Conditional(conditional) => {
|
|
||||||
StatementMonoidItems::Conditional(self.reduce_conditional_statement(conditional))
|
|
||||||
}
|
|
||||||
Statement::Iteration(iteration) => StatementMonoidItems::Iteration {
|
|
||||||
identifier: self.reduce_identifier(&iteration.variable),
|
|
||||||
start: self.reduce_expression(&iteration.start),
|
|
||||||
stop: self.reduce_expression(&iteration.stop),
|
|
||||||
statements: iteration
|
|
||||||
.block
|
|
||||||
.statements
|
|
||||||
.iter()
|
|
||||||
.map(|x| self.reduce_statement(x))
|
|
||||||
.collect(),
|
|
||||||
},
|
|
||||||
Statement::Console(console) => match &console.function {
|
|
||||||
ConsoleFunction::Assert(expression) => {
|
|
||||||
StatementMonoidItems::ConsoleAssert(self.reduce_expression(expression))
|
|
||||||
}
|
|
||||||
ConsoleFunction::Debug(formatted_string)
|
|
||||||
| ConsoleFunction::Error(formatted_string)
|
|
||||||
| ConsoleFunction::Log(formatted_string) => StatementMonoidItems::ConsoleFormat(
|
|
||||||
formatted_string
|
|
||||||
.parameters
|
|
||||||
.iter()
|
|
||||||
.map(|parameter| self.reduce_expression(¶meter))
|
|
||||||
.collect(),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
Statement::Expression(statement) => {
|
|
||||||
StatementMonoidItems::Expression(self.reduce_expression(&statement.expression))
|
|
||||||
}
|
|
||||||
Statement::Block(block) => StatementMonoidItems::Statements(
|
|
||||||
block
|
|
||||||
.statements
|
|
||||||
.iter()
|
|
||||||
.map(|statement| self.reduce_statement(statement))
|
|
||||||
.collect(),
|
|
||||||
),
|
|
||||||
};
|
|
||||||
|
|
||||||
self.reducer.reduce_statement(statement, items)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reduce_assignee_access(&mut self, assignee_access: &AssigneeAccess) -> T {
|
|
||||||
let item = match assignee_access {
|
|
||||||
AssigneeAccess::ArrayRange(start, stop) => {
|
|
||||||
let start_item = start.as_ref().map(|x| self.reduce_expression(x));
|
|
||||||
let stop_item = stop.as_ref().map(|x| self.reduce_expression(x));
|
|
||||||
AssigneeAccessItem::Array(RangeItem::Range(start_item, stop_item))
|
|
||||||
}
|
|
||||||
AssigneeAccess::ArrayIndex(expression) => {
|
|
||||||
AssigneeAccessItem::Array(RangeItem::Index(self.reduce_expression(expression)))
|
|
||||||
}
|
|
||||||
AssigneeAccess::Tuple(_, _) => AssigneeAccessItem::Tuple,
|
|
||||||
AssigneeAccess::Member(identifier) => {
|
|
||||||
let identifier = self.reduce_identifier(identifier);
|
|
||||||
AssigneeAccessItem::Member(identifier)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
self.reducer.reduce_assignee_access(assignee_access, item)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reduce_conditional_statement(&mut self, statement: &ConditionalStatement) -> T {
|
|
||||||
let condition = self.reduce_expression(&statement.condition);
|
|
||||||
let statements = statement
|
|
||||||
.block
|
|
||||||
.statements
|
|
||||||
.iter()
|
|
||||||
.map(|x| self.reduce_statement(x))
|
|
||||||
.collect();
|
|
||||||
let next = statement.next.as_ref().map(|x| self.reduce_statement(x));
|
|
||||||
|
|
||||||
self.reducer
|
|
||||||
.reduce_conditional_statement(statement, condition, statements, next)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reduce_variable_name(&mut self, variable_name: &VariableName) -> T {
|
|
||||||
let identifier = self.reduce_identifier(&variable_name.identifier);
|
|
||||||
|
|
||||||
self.reducer.reduce_variable_name(variable_name, identifier)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reduce_variable_names(&mut self, variable_names: &[VariableName]) -> T {
|
|
||||||
let names = variable_names
|
|
||||||
.iter()
|
|
||||||
.map(|variable_name| self.reduce_variable_name(variable_name))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
self.reducer.reduce_variable_names(names)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reduce_group_coordinate(&mut self, group_coordinate: &GroupCoordinate) -> T {
|
|
||||||
self.reducer.reduce_group_coordinate(group_coordinate)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reduce_value_expression(&mut self, value_expression: &ValueExpression) -> T {
|
|
||||||
let item = match value_expression {
|
|
||||||
ValueExpression::Address(_, _) => ValueExpressionMonoidItems::Address,
|
|
||||||
ValueExpression::Boolean(_, _) => ValueExpressionMonoidItems::Boolean,
|
|
||||||
ValueExpression::Field(_, _) => ValueExpressionMonoidItems::Field,
|
|
||||||
ValueExpression::Group(group_value) => match group_value.as_ref() {
|
|
||||||
GroupValue::Single(_, _) => ValueExpressionMonoidItems::GroupSingle,
|
|
||||||
GroupValue::Tuple(tuple) => {
|
|
||||||
let x = self.reduce_group_coordinate(&tuple.x);
|
|
||||||
let y = self.reduce_group_coordinate(&tuple.y);
|
|
||||||
ValueExpressionMonoidItems::GroupTuple(x, y)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
ValueExpression::Implicit(_, _) => ValueExpressionMonoidItems::Implicit,
|
|
||||||
ValueExpression::Integer(integer_type, _, _) => {
|
|
||||||
ValueExpressionMonoidItems::Integer(self.reduce_integer_type(integer_type))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
self.reducer.reduce_value_expression(value_expression, item)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reduce_expression(&mut self, expression: &Expression) -> T {
|
|
||||||
let items = match expression {
|
|
||||||
Expression::Identifier(identifier) => ExpressionMonoidItems::Unary(self.reduce_identifier(identifier)),
|
|
||||||
Expression::Value(value) => ExpressionMonoidItems::Value(self.reduce_value_expression(value)),
|
|
||||||
Expression::Binary(binary) => {
|
|
||||||
let left = self.reduce_expression(&binary.left);
|
|
||||||
let right = self.reduce_expression(&binary.right);
|
|
||||||
ExpressionMonoidItems::Binary(left, right)
|
|
||||||
}
|
|
||||||
Expression::Unary(unary) => ExpressionMonoidItems::Unary(self.reduce_expression(&unary.inner)),
|
|
||||||
Expression::Ternary(ternary) => {
|
|
||||||
let condition = self.reduce_expression(&ternary.condition);
|
|
||||||
let left = self.reduce_expression(&ternary.if_true);
|
|
||||||
let right = self.reduce_expression(&ternary.if_false);
|
|
||||||
ExpressionMonoidItems::Triary(condition, left, right)
|
|
||||||
}
|
|
||||||
Expression::ArrayInline(array_inline) => ExpressionMonoidItems::Var(
|
|
||||||
array_inline
|
|
||||||
.elements
|
|
||||||
.iter()
|
|
||||||
.map(|x| match x {
|
|
||||||
SpreadOrExpression::Expression(expression) | SpreadOrExpression::Spread(expression) => {
|
|
||||||
self.reduce_expression(expression)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
),
|
|
||||||
Expression::ArrayInit(array_init) => {
|
|
||||||
let element = self.reduce_expression(&array_init.element);
|
|
||||||
ExpressionMonoidItems::Unary(element)
|
|
||||||
}
|
|
||||||
Expression::ArrayAccess(array_access) => {
|
|
||||||
let array = self.reduce_expression(&array_access.array);
|
|
||||||
let index = self.reduce_expression(&array_access.index);
|
|
||||||
ExpressionMonoidItems::ArrayAccess(array, index)
|
|
||||||
}
|
|
||||||
Expression::ArrayRangeAccess(array_range_access) => {
|
|
||||||
let array = self.reduce_expression(&array_range_access.array);
|
|
||||||
|
|
||||||
match (array_range_access.left.as_ref(), array_range_access.right.as_ref()) {
|
|
||||||
(Some(left_expression), Some(right_expression)) => {
|
|
||||||
let left = self.reduce_expression(&left_expression);
|
|
||||||
let right = self.reduce_expression(&right_expression);
|
|
||||||
ExpressionMonoidItems::Triary(array, left, right)
|
|
||||||
}
|
|
||||||
(Some(left_expression), None) => {
|
|
||||||
let left = self.reduce_expression(&left_expression);
|
|
||||||
ExpressionMonoidItems::Binary(array, left)
|
|
||||||
}
|
|
||||||
(None, Some(right_expression)) => {
|
|
||||||
let right = self.reduce_expression(&right_expression);
|
|
||||||
ExpressionMonoidItems::Binary(array, right)
|
|
||||||
}
|
|
||||||
(None, None) => ExpressionMonoidItems::Unary(array),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Expression::TupleInit(tuple_init) => {
|
|
||||||
let element_items = tuple_init.elements.iter().map(|x| self.reduce_expression(x)).collect();
|
|
||||||
ExpressionMonoidItems::Var(element_items)
|
|
||||||
}
|
|
||||||
Expression::TupleAccess(tuple_access) => {
|
|
||||||
let tuple_access = self.reduce_expression(&tuple_access.tuple);
|
|
||||||
ExpressionMonoidItems::Unary(tuple_access)
|
|
||||||
}
|
|
||||||
|
|
||||||
Expression::CircuitInit(circuit_init) => {
|
|
||||||
let defined_circuit_name_item = self.reduce_identifier(&circuit_init.name);
|
|
||||||
let members = circuit_init
|
|
||||||
.members
|
|
||||||
.iter()
|
|
||||||
.map(|definition| {
|
|
||||||
let definition_identifier = self.reduce_identifier(&definition.identifier);
|
|
||||||
let definition_expression =
|
|
||||||
definition.expression.as_ref().map(|expr| self.reduce_expression(&expr));
|
|
||||||
(definition_identifier, definition_expression)
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
ExpressionMonoidItems::Circuit(defined_circuit_name_item, members)
|
|
||||||
}
|
|
||||||
Expression::CircuitMemberAccess(circuit_member_access) => {
|
|
||||||
let declared_circuit_name = self.reduce_expression(&circuit_member_access.circuit);
|
|
||||||
let circuit_member_name = self.reduce_identifier(&circuit_member_access.name);
|
|
||||||
|
|
||||||
ExpressionMonoidItems::Binary(declared_circuit_name, circuit_member_name)
|
|
||||||
}
|
|
||||||
Expression::CircuitStaticFunctionAccess(circuit_static_func_access) => {
|
|
||||||
let declared_circuit_name = self.reduce_expression(&circuit_static_func_access.circuit);
|
|
||||||
let circuit_static_function_name = self.reduce_identifier(&circuit_static_func_access.name);
|
|
||||||
|
|
||||||
ExpressionMonoidItems::Binary(declared_circuit_name, circuit_static_function_name)
|
|
||||||
}
|
|
||||||
|
|
||||||
Expression::Call(call) => {
|
|
||||||
let function = self.reduce_expression(&call.function);
|
|
||||||
let function_arguments = call.arguments.iter().map(|x| self.reduce_expression(x)).collect();
|
|
||||||
|
|
||||||
ExpressionMonoidItems::FunctionCall(function, function_arguments)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO casts?
|
|
||||||
_ => ExpressionMonoidItems::Empty,
|
|
||||||
};
|
|
||||||
self.reducer.reduce_expression(expression, items)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,315 +0,0 @@
|
|||||||
// Copyright (C) 2019-2021 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 the reducer which iterates through ast nodes - converting them into
|
|
||||||
//! asg nodes and saving relevant information.
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
AssigneeAccess,
|
|
||||||
Circuit,
|
|
||||||
CircuitMember,
|
|
||||||
ConditionalStatement,
|
|
||||||
Expression,
|
|
||||||
Function,
|
|
||||||
FunctionInput,
|
|
||||||
FunctionInputVariable,
|
|
||||||
GroupCoordinate,
|
|
||||||
Identifier,
|
|
||||||
ImportStatement,
|
|
||||||
IntegerType,
|
|
||||||
Monoid,
|
|
||||||
Package,
|
|
||||||
Packages,
|
|
||||||
Program,
|
|
||||||
Statement,
|
|
||||||
Type,
|
|
||||||
ValueExpression,
|
|
||||||
VariableName,
|
|
||||||
};
|
|
||||||
use indexmap::IndexMap;
|
|
||||||
|
|
||||||
pub enum TypeMonoidItems<T: Monoid> {
|
|
||||||
None,
|
|
||||||
Tuple(Vec<T>),
|
|
||||||
Array(T),
|
|
||||||
Identifier(T),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum CircuitMemberMonoidItems<T: Monoid> {
|
|
||||||
Variable { identifier: T, type_: T },
|
|
||||||
Function(T),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum StatementMonoidItems<T: Monoid> {
|
|
||||||
Return(T),
|
|
||||||
Definition {
|
|
||||||
variables: T,
|
|
||||||
expression: T,
|
|
||||||
},
|
|
||||||
Assign {
|
|
||||||
assignee: T,
|
|
||||||
assignee_accesses: Vec<T>,
|
|
||||||
expression: T,
|
|
||||||
},
|
|
||||||
Conditional(T),
|
|
||||||
Iteration {
|
|
||||||
identifier: T,
|
|
||||||
start: T,
|
|
||||||
stop: T,
|
|
||||||
statements: Vec<T>,
|
|
||||||
},
|
|
||||||
ConsoleAssert(T),
|
|
||||||
ConsoleFormat(Vec<T>),
|
|
||||||
Expression(T),
|
|
||||||
Statements(Vec<T>),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum AssigneeAccessItem<T: Monoid> {
|
|
||||||
Array(RangeItem<T>),
|
|
||||||
Tuple,
|
|
||||||
Member(T),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum RangeItem<T: Monoid> {
|
|
||||||
Range(Option<T>, Option<T>),
|
|
||||||
Index(T),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum ExpressionMonoidItems<T: Monoid> {
|
|
||||||
Empty,
|
|
||||||
Unary(T),
|
|
||||||
Binary(T, T),
|
|
||||||
Triary(T, T, T),
|
|
||||||
FunctionCall(T, Vec<T>),
|
|
||||||
ArrayAccess(T, T),
|
|
||||||
Circuit(T, Vec<(T, Option<T>)>),
|
|
||||||
Var(Vec<T>),
|
|
||||||
Value(T),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum ConditionStatementNextItem<T: Monoid> {
|
|
||||||
Nested(T),
|
|
||||||
End(Vec<T>),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum FunctionInputItem<T: Monoid> {
|
|
||||||
InputKeyword,
|
|
||||||
SelfKeyword,
|
|
||||||
MutSelfKeyword,
|
|
||||||
Variable(T),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum ValueExpressionMonoidItems<T: Monoid> {
|
|
||||||
Address,
|
|
||||||
Boolean,
|
|
||||||
Field,
|
|
||||||
GroupSingle,
|
|
||||||
GroupTuple(T, T),
|
|
||||||
Implicit,
|
|
||||||
Integer(T),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
|
||||||
pub trait MonoidalReducer<T: Monoid> {
|
|
||||||
fn reduce_program(
|
|
||||||
&mut self,
|
|
||||||
program: &Program,
|
|
||||||
expected_input: Vec<T>,
|
|
||||||
imports: Vec<T>,
|
|
||||||
circuits: IndexMap<String, (T, T)>,
|
|
||||||
functions: IndexMap<String, (T, T)>,
|
|
||||||
) -> T {
|
|
||||||
let mut items = T::default()
|
|
||||||
.append_all(expected_input.into_iter())
|
|
||||||
.append_all(imports.into_iter());
|
|
||||||
|
|
||||||
for (_, (identifier, value)) in circuits.into_iter() {
|
|
||||||
items = items.append(identifier).append(value);
|
|
||||||
}
|
|
||||||
for (_, (identifier, value)) in functions.into_iter() {
|
|
||||||
items = items.append(identifier).append(value);
|
|
||||||
}
|
|
||||||
items
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reduce_function_input(&mut self, input: &FunctionInput, item: FunctionInputItem<T>) -> T {
|
|
||||||
match item {
|
|
||||||
FunctionInputItem::InputKeyword | FunctionInputItem::SelfKeyword | FunctionInputItem::MutSelfKeyword => {
|
|
||||||
T::default()
|
|
||||||
}
|
|
||||||
FunctionInputItem::Variable(variable) => variable,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reduce_import_statement(&mut self, import: &ImportStatement, package: T) -> T {
|
|
||||||
package
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reduce_circuit(&mut self, circuit: &Circuit, circuit_name: T, members: Vec<T>) -> T {
|
|
||||||
circuit_name.append_all(members.into_iter())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reduce_function(
|
|
||||||
&mut self,
|
|
||||||
function: &Function,
|
|
||||||
identifier: T,
|
|
||||||
input: Vec<T>,
|
|
||||||
output: Option<T>,
|
|
||||||
statements: Vec<T>,
|
|
||||||
) -> T {
|
|
||||||
identifier
|
|
||||||
.append_all(input.into_iter())
|
|
||||||
.append_option(output)
|
|
||||||
.append_all(statements.into_iter())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reduce_identifier(&mut self, identifier: &Identifier) -> T {
|
|
||||||
T::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reduce_integer_type(&mut self, integer_type: &IntegerType) -> T {
|
|
||||||
T::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reduce_function_input_variable(
|
|
||||||
&mut self,
|
|
||||||
function_input_variable: &FunctionInputVariable,
|
|
||||||
identifier: T,
|
|
||||||
type_: T,
|
|
||||||
) -> T {
|
|
||||||
identifier.append(type_)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reduce_type(&mut self, type_: &Type, items: TypeMonoidItems<T>) -> T {
|
|
||||||
match items {
|
|
||||||
TypeMonoidItems::Tuple(items) => T::default().append_all(items.into_iter()),
|
|
||||||
TypeMonoidItems::Array(item) => item,
|
|
||||||
TypeMonoidItems::Identifier(item) => item,
|
|
||||||
TypeMonoidItems::None => T::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reduce_packages(&mut self, packages: &Packages, name: T) -> T {
|
|
||||||
name
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reduce_package(&mut self, package: &Package, name: T) -> T {
|
|
||||||
name
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reduce_circuit_member(&mut self, circuit_member: &CircuitMember, items: CircuitMemberMonoidItems<T>) -> T {
|
|
||||||
match items {
|
|
||||||
CircuitMemberMonoidItems::Variable { identifier, type_ } => identifier.append(type_),
|
|
||||||
CircuitMemberMonoidItems::Function(identifier) => identifier,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reduce_statement(&mut self, statement: &Statement, items: StatementMonoidItems<T>) -> T {
|
|
||||||
match items {
|
|
||||||
StatementMonoidItems::Return(expression) => expression,
|
|
||||||
StatementMonoidItems::Definition { variables, expression } => variables.append(expression),
|
|
||||||
StatementMonoidItems::Assign {
|
|
||||||
assignee,
|
|
||||||
assignee_accesses,
|
|
||||||
expression,
|
|
||||||
} => assignee.append_all(assignee_accesses.into_iter()).append(expression),
|
|
||||||
StatementMonoidItems::Conditional(conditional) => conditional,
|
|
||||||
StatementMonoidItems::Iteration {
|
|
||||||
identifier,
|
|
||||||
start,
|
|
||||||
stop,
|
|
||||||
statements,
|
|
||||||
} => identifier.append(start).append(stop).append_all(statements.into_iter()),
|
|
||||||
StatementMonoidItems::ConsoleAssert(expression) => expression,
|
|
||||||
StatementMonoidItems::ConsoleFormat(parameters) => T::default().append_all(parameters.into_iter()),
|
|
||||||
StatementMonoidItems::Expression(expression) => expression,
|
|
||||||
StatementMonoidItems::Statements(statements) => T::default().append_all(statements.into_iter()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reduce_assignee_access(&mut self, assignee_access: &AssigneeAccess, item: AssigneeAccessItem<T>) -> T {
|
|
||||||
match item {
|
|
||||||
AssigneeAccessItem::Array(assignee) => match assignee {
|
|
||||||
RangeItem::Index(index) => index,
|
|
||||||
RangeItem::Range(start, stop) => T::default().append_option(start).append_option(stop),
|
|
||||||
},
|
|
||||||
AssigneeAccessItem::Tuple => T::default(),
|
|
||||||
AssigneeAccessItem::Member(identifier) => identifier,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reduce_conditional_statement(
|
|
||||||
&mut self,
|
|
||||||
statement: &ConditionalStatement,
|
|
||||||
condition: T,
|
|
||||||
statements: Vec<T>,
|
|
||||||
next: Option<T>,
|
|
||||||
) -> T {
|
|
||||||
condition.append_all(statements.into_iter()).append_option(next)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reduce_variable_name(&mut self, variable_name: &VariableName, identifier: T) -> T {
|
|
||||||
identifier
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reduce_variable_names(&mut self, names: Vec<T>) -> T {
|
|
||||||
T::default().append_all(names.into_iter())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reduce_group_coordinate(&mut self, group_coordinate: &GroupCoordinate) -> T {
|
|
||||||
T::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reduce_value_expression(
|
|
||||||
&mut self,
|
|
||||||
value_expression: &ValueExpression,
|
|
||||||
value: ValueExpressionMonoidItems<T>,
|
|
||||||
) -> T {
|
|
||||||
match value {
|
|
||||||
ValueExpressionMonoidItems::GroupTuple(x, y) => x.append(y),
|
|
||||||
ValueExpressionMonoidItems::Integer(integer_type) => integer_type,
|
|
||||||
_ => T::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// please be careful matching on array access/range expressions, they can be ExpressionMonoidItems::BiTriary or ExpressionMonoidItems::Binary
|
|
||||||
fn reduce_expression(&mut self, expression: &Expression, items: ExpressionMonoidItems<T>) -> T {
|
|
||||||
match items {
|
|
||||||
ExpressionMonoidItems::Empty => T::default(),
|
|
||||||
ExpressionMonoidItems::Unary(expression) => expression,
|
|
||||||
ExpressionMonoidItems::Binary(left, right) => left.append(right),
|
|
||||||
ExpressionMonoidItems::Triary(left, center, right) => left.append(center).append(right),
|
|
||||||
ExpressionMonoidItems::ArrayAccess(identifier, index) => identifier.append(index),
|
|
||||||
ExpressionMonoidItems::FunctionCall(identifier, arguments) => identifier.append_all(arguments.into_iter()),
|
|
||||||
ExpressionMonoidItems::Circuit(identifier, arguments) => {
|
|
||||||
let mut out = identifier;
|
|
||||||
for (key, value) in arguments.into_iter() {
|
|
||||||
match value {
|
|
||||||
Some(val) => {
|
|
||||||
out = out.append(key).append(val);
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
out = out.append(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out
|
|
||||||
}
|
|
||||||
ExpressionMonoidItems::Var(items) => T::default().append_all(items.into_iter()),
|
|
||||||
ExpressionMonoidItems::Value(value) => value,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -17,49 +17,7 @@
|
|||||||
//! This module contains the reducer which iterates through ast nodes - converting them into
|
//! This module contains the reducer which iterates through ast nodes - converting them into
|
||||||
//! asg nodes and saving relevant information.
|
//! asg nodes and saving relevant information.
|
||||||
|
|
||||||
use crate::{
|
use crate::*;
|
||||||
ArrayAccessExpression,
|
|
||||||
ArrayInitExpression,
|
|
||||||
ArrayInlineExpression,
|
|
||||||
ArrayRangeAccessExpression,
|
|
||||||
AssignStatement,
|
|
||||||
Assignee,
|
|
||||||
AssigneeAccess,
|
|
||||||
BinaryExpression,
|
|
||||||
Block,
|
|
||||||
CallExpression,
|
|
||||||
Circuit,
|
|
||||||
CircuitImpliedVariableDefinition,
|
|
||||||
CircuitInitExpression,
|
|
||||||
CircuitMember,
|
|
||||||
CircuitMemberAccessExpression,
|
|
||||||
CircuitStaticFunctionAccessExpression,
|
|
||||||
ConditionalStatement,
|
|
||||||
ConsoleFunction,
|
|
||||||
ConsoleStatement,
|
|
||||||
DefinitionStatement,
|
|
||||||
Expression,
|
|
||||||
ExpressionStatement,
|
|
||||||
FormattedString,
|
|
||||||
Function,
|
|
||||||
FunctionInput,
|
|
||||||
FunctionInputVariable,
|
|
||||||
Identifier,
|
|
||||||
ImportStatement,
|
|
||||||
IterationStatement,
|
|
||||||
PackageOrPackages,
|
|
||||||
Program,
|
|
||||||
ReconstructingReducer,
|
|
||||||
ReturnStatement,
|
|
||||||
SpreadOrExpression,
|
|
||||||
Statement,
|
|
||||||
TernaryExpression,
|
|
||||||
TupleAccessExpression,
|
|
||||||
TupleInitExpression,
|
|
||||||
Type,
|
|
||||||
UnaryExpression,
|
|
||||||
VariableName,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct ReconstructingDirector<R: ReconstructingReducer> {
|
pub struct ReconstructingDirector<R: ReconstructingReducer> {
|
||||||
reducer: R,
|
reducer: R,
|
||||||
@ -70,430 +28,496 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
|||||||
Self { reducer }
|
Self { reducer }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn reduce_type(&mut self, type_: &Type) -> Type {
|
||||||
|
let new = match type_ {
|
||||||
|
// Data type wrappers
|
||||||
|
Type::Array(type_, dimensions) => Type::Array(Box::new(self.reduce_type(type_)), dimensions.clone()),
|
||||||
|
Type::Tuple(types) => Type::Tuple(types.iter().map(|type_| self.reduce_type(type_)).collect()),
|
||||||
|
Type::Circuit(identifier) => Type::Circuit(self.reduce_identifier(identifier)),
|
||||||
|
_ => type_.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
self.reducer.reduce_type(type_, new)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expressions
|
||||||
|
pub fn reduce_expression(&mut self, expression: &Expression) -> Expression {
|
||||||
|
let new = match expression {
|
||||||
|
Expression::Identifier(identifier) => Expression::Identifier(self.reduce_identifier(&identifier)),
|
||||||
|
Expression::Value(value) => Expression::Value(self.reduce_value(&value)),
|
||||||
|
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::Cast(cast) => Expression::Cast(self.reduce_cast(&cast)),
|
||||||
|
|
||||||
|
Expression::ArrayInline(array_inline) => Expression::ArrayInline(self.reduce_array_inline(&array_inline)),
|
||||||
|
Expression::ArrayInit(array_init) => Expression::ArrayInit(self.reduce_array_init(&array_init)),
|
||||||
|
Expression::ArrayAccess(array_access) => Expression::ArrayAccess(self.reduce_array_access(&array_access)),
|
||||||
|
Expression::ArrayRangeAccess(array_range_access) => {
|
||||||
|
Expression::ArrayRangeAccess(self.reduce_array_range_access(&array_range_access))
|
||||||
|
}
|
||||||
|
|
||||||
|
Expression::TupleInit(tuple_init) => Expression::TupleInit(self.reduce_tuple_init(&tuple_init)),
|
||||||
|
Expression::TupleAccess(tuple_access) => Expression::TupleAccess(self.reduce_tuple_access(&tuple_access)),
|
||||||
|
|
||||||
|
Expression::CircuitInit(circuit_init) => Expression::CircuitInit(self.reduce_circuit_init(&circuit_init)),
|
||||||
|
Expression::CircuitMemberAccess(circuit_member_access) => {
|
||||||
|
Expression::CircuitMemberAccess(self.reduce_circuit_member_access(&circuit_member_access))
|
||||||
|
}
|
||||||
|
Expression::CircuitStaticFunctionAccess(circuit_static_fn_access) => {
|
||||||
|
Expression::CircuitStaticFunctionAccess(self.reduce_circuit_static_fn_access(&circuit_static_fn_access))
|
||||||
|
}
|
||||||
|
|
||||||
|
Expression::Call(call) => Expression::Call(self.reduce_call(&call)),
|
||||||
|
};
|
||||||
|
|
||||||
|
self.reducer.reduce_expression(expression, new)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_identifier(&mut self, identifier: &Identifier) -> Identifier {
|
||||||
|
self.reducer.reduce_identifier(identifier, identifier.span.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_group_tuple(&mut self, group_tuple: &GroupTuple) -> GroupTuple {
|
||||||
|
self.reducer.reduce_group_tuple(group_tuple, group_tuple.span.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_group_value(&mut self, group_value: &GroupValue) -> GroupValue {
|
||||||
|
let new = match group_value {
|
||||||
|
GroupValue::Tuple(group_tuple) => GroupValue::Tuple(self.reduce_group_tuple(&group_tuple)),
|
||||||
|
_ => group_value.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
self.reducer.reduce_group_value(group_value, new)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_value(&mut self, value: &ValueExpression) -> ValueExpression {
|
||||||
|
let new = match value {
|
||||||
|
ValueExpression::Group(group_value) => {
|
||||||
|
ValueExpression::Group(Box::new(self.reduce_group_value(&group_value)))
|
||||||
|
}
|
||||||
|
_ => value.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
self.reducer.reduce_value(value, new)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_binary(&mut self, binary: &BinaryExpression) -> BinaryExpression {
|
||||||
|
let left = self.reduce_expression(&binary.left);
|
||||||
|
let right = self.reduce_expression(&binary.right);
|
||||||
|
|
||||||
|
self.reducer
|
||||||
|
.reduce_binary(binary, left, right, binary.op.clone(), binary.span.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_unary(&mut self, unary: &UnaryExpression) -> UnaryExpression {
|
||||||
|
let inner = self.reduce_expression(&unary.inner);
|
||||||
|
|
||||||
|
self.reducer
|
||||||
|
.reduce_unary(unary, inner, unary.op.clone(), unary.span.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_ternary(&mut self, ternary: &TernaryExpression) -> 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, ternary.span.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_cast(&mut self, cast: &CastExpression) -> CastExpression {
|
||||||
|
let inner = self.reduce_expression(&cast.inner);
|
||||||
|
let target_type = cast.target_type.clone(); // TODO reduce
|
||||||
|
|
||||||
|
self.reducer.reduce_cast(cast, inner, target_type, cast.span.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_array_inline(&mut self, array_inline: &ArrayInlineExpression) -> ArrayInlineExpression {
|
||||||
|
let elements = array_inline
|
||||||
|
.elements
|
||||||
|
.iter()
|
||||||
|
.map(|element| match element {
|
||||||
|
SpreadOrExpression::Expression(expression) => {
|
||||||
|
SpreadOrExpression::Expression(self.reduce_expression(expression))
|
||||||
|
}
|
||||||
|
SpreadOrExpression::Spread(expression) => {
|
||||||
|
SpreadOrExpression::Spread(self.reduce_expression(expression))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
self.reducer
|
||||||
|
.reduce_array_inline(array_inline, elements, array_inline.span.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_array_init(&mut self, array_init: &ArrayInitExpression) -> ArrayInitExpression {
|
||||||
|
let element = self.reduce_expression(&array_init.element);
|
||||||
|
|
||||||
|
self.reducer
|
||||||
|
.reduce_array_init(array_init, element, array_init.span.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_array_access(&mut self, array_access: &ArrayAccessExpression) -> ArrayAccessExpression {
|
||||||
|
let array = self.reduce_expression(&array_access.array);
|
||||||
|
let index = self.reduce_expression(&array_access.index);
|
||||||
|
|
||||||
|
self.reducer
|
||||||
|
.reduce_array_access(array_access, array, index, array_access.span.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_array_range_access(
|
||||||
|
&mut self,
|
||||||
|
array_range_access: &ArrayRangeAccessExpression,
|
||||||
|
) -> ArrayRangeAccessExpression {
|
||||||
|
let array = self.reduce_expression(&array_range_access.array);
|
||||||
|
let left = array_range_access
|
||||||
|
.left
|
||||||
|
.as_ref()
|
||||||
|
.map(|left| self.reduce_expression(left));
|
||||||
|
let right = array_range_access
|
||||||
|
.right
|
||||||
|
.as_ref()
|
||||||
|
.map(|right| self.reduce_expression(right));
|
||||||
|
|
||||||
|
self.reducer
|
||||||
|
.reduce_array_range_access(array_range_access, array, left, right, array_range_access.span.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_tuple_init(&mut self, tuple_init: &TupleInitExpression) -> TupleInitExpression {
|
||||||
|
let elements = tuple_init
|
||||||
|
.elements
|
||||||
|
.iter()
|
||||||
|
.map(|expr| self.reduce_expression(expr))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
self.reducer
|
||||||
|
.reduce_tuple_init(tuple_init, elements, tuple_init.span.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_tuple_access(&mut self, tuple_access: &TupleAccessExpression) -> TupleAccessExpression {
|
||||||
|
let tuple = self.reduce_expression(&tuple_access.tuple);
|
||||||
|
|
||||||
|
self.reducer
|
||||||
|
.reduce_tuple_access(tuple_access, tuple, tuple_access.span.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_circuit_init(&mut self, circuit_init: &CircuitInitExpression) -> CircuitInitExpression {
|
||||||
|
let name = self.reduce_identifier(&circuit_init.name);
|
||||||
|
let members = circuit_init
|
||||||
|
.members
|
||||||
|
.iter()
|
||||||
|
.map(|definition| {
|
||||||
|
let identifier = self.reduce_identifier(&definition.identifier);
|
||||||
|
let expression = definition.expression.as_ref().map(|expr| self.reduce_expression(expr));
|
||||||
|
|
||||||
|
CircuitImpliedVariableDefinition { identifier, expression }
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
self.reducer
|
||||||
|
.reduce_circuit_init(circuit_init, name, members, circuit_init.span.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_circuit_member_access(
|
||||||
|
&mut self,
|
||||||
|
circuit_member_access: &CircuitMemberAccessExpression,
|
||||||
|
) -> CircuitMemberAccessExpression {
|
||||||
|
let circuit = self.reduce_expression(&circuit_member_access.circuit);
|
||||||
|
let name = self.reduce_identifier(&circuit_member_access.name);
|
||||||
|
|
||||||
|
self.reducer.reduce_circuit_member_access(
|
||||||
|
circuit_member_access,
|
||||||
|
circuit,
|
||||||
|
name,
|
||||||
|
circuit_member_access.span.clone(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_circuit_static_fn_access(
|
||||||
|
&mut self,
|
||||||
|
circuit_static_fn_access: &CircuitStaticFunctionAccessExpression,
|
||||||
|
) -> CircuitStaticFunctionAccessExpression {
|
||||||
|
let circuit = self.reduce_expression(&circuit_static_fn_access.circuit);
|
||||||
|
let name = self.reduce_identifier(&circuit_static_fn_access.name);
|
||||||
|
|
||||||
|
self.reducer.reduce_circuit_static_fn_access(
|
||||||
|
circuit_static_fn_access,
|
||||||
|
circuit,
|
||||||
|
name,
|
||||||
|
circuit_static_fn_access.span.clone(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_call(&mut self, call: &CallExpression) -> CallExpression {
|
||||||
|
let function = self.reduce_expression(&call.function);
|
||||||
|
let arguments = call.arguments.iter().map(|expr| self.reduce_expression(expr)).collect();
|
||||||
|
|
||||||
|
self.reducer.reduce_call(call, function, arguments, call.span.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Statements
|
||||||
|
pub fn reduce_statement(&mut self, statement: &Statement) -> 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(self.reduce_assign(&assign)),
|
||||||
|
Statement::Conditional(conditional) => Statement::Conditional(self.reduce_conditional(&conditional)),
|
||||||
|
Statement::Iteration(iteration) => Statement::Iteration(self.reduce_iteration(&iteration)),
|
||||||
|
Statement::Console(console) => Statement::Console(self.reduce_console(&console)),
|
||||||
|
Statement::Expression(expression) => Statement::Expression(self.reduce_expression_statement(&expression)),
|
||||||
|
Statement::Block(block) => Statement::Block(self.reduce_block(&block)),
|
||||||
|
};
|
||||||
|
|
||||||
|
self.reducer.reduce_statement(statement, new)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_return(&mut self, return_statement: &ReturnStatement) -> ReturnStatement {
|
||||||
|
let expression = self.reduce_expression(&return_statement.expression);
|
||||||
|
|
||||||
|
self.reducer
|
||||||
|
.reduce_return(return_statement, expression, return_statement.span.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_variable_name(&mut self, variable_name: &VariableName) -> VariableName {
|
||||||
|
let identifier = self.reduce_identifier(&variable_name.identifier);
|
||||||
|
|
||||||
|
self.reducer
|
||||||
|
.reduce_variable_name(variable_name, identifier, variable_name.span.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_definition(&mut self, definition: &DefinitionStatement) -> DefinitionStatement {
|
||||||
|
let variable_names = definition
|
||||||
|
.variable_names
|
||||||
|
.iter()
|
||||||
|
.map(|variable_name| self.reduce_variable_name(variable_name))
|
||||||
|
.collect();
|
||||||
|
let type_ = definition.type_.as_ref().map(|inner| self.reduce_type(inner));
|
||||||
|
let value = self.reduce_expression(&definition.value);
|
||||||
|
|
||||||
|
self.reducer
|
||||||
|
.reduce_definition(definition, variable_names, type_, value, definition.span.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_assignee_access(&mut self, access: &AssigneeAccess) -> AssigneeAccess {
|
||||||
|
let new = match access {
|
||||||
|
AssigneeAccess::ArrayRange(left, right) => AssigneeAccess::ArrayRange(
|
||||||
|
left.as_ref().map(|expr| self.reduce_expression(expr)),
|
||||||
|
right.as_ref().map(|expr| self.reduce_expression(expr)),
|
||||||
|
),
|
||||||
|
AssigneeAccess::ArrayIndex(index) => AssigneeAccess::ArrayIndex(self.reduce_expression(&index)),
|
||||||
|
AssigneeAccess::Member(identifier) => AssigneeAccess::Member(self.reduce_identifier(&identifier)),
|
||||||
|
_ => access.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
self.reducer.reduce_assignee_access(access, new)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_assignee(&mut self, assignee: &Assignee) -> Assignee {
|
||||||
|
let identifier = self.reduce_identifier(&assignee.identifier);
|
||||||
|
let accesses = assignee
|
||||||
|
.accesses
|
||||||
|
.iter()
|
||||||
|
.map(|access| self.reduce_assignee_access(access))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
self.reducer
|
||||||
|
.reduce_assignee(assignee, identifier, accesses, assignee.span.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_assign(&mut self, assign: &AssignStatement) -> AssignStatement {
|
||||||
|
let assignee = self.reduce_assignee(&assign.assignee);
|
||||||
|
let value = self.reduce_expression(&assign.value);
|
||||||
|
|
||||||
|
self.reducer.reduce_assign(assign, assignee, value, assign.span.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_conditional(&mut self, conditional: &ConditionalStatement) -> 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));
|
||||||
|
|
||||||
|
self.reducer
|
||||||
|
.reduce_conditional(conditional, condition, block, next, conditional.span.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_iteration(&mut self, iteration: &IterationStatement) -> IterationStatement {
|
||||||
|
let variable = self.reduce_identifier(&iteration.variable);
|
||||||
|
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, start, stop, block, iteration.span.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_console(&mut self, console_function_call: &ConsoleStatement) -> ConsoleStatement {
|
||||||
|
let function = match &console_function_call.function {
|
||||||
|
ConsoleFunction::Assert(expression) => ConsoleFunction::Assert(self.reduce_expression(expression)),
|
||||||
|
ConsoleFunction::Debug(format) | ConsoleFunction::Error(format) | ConsoleFunction::Log(format) => {
|
||||||
|
let formatted = FormattedString {
|
||||||
|
parts: format.parts.clone(),
|
||||||
|
parameters: format
|
||||||
|
.parameters
|
||||||
|
.iter()
|
||||||
|
.map(|parameter| self.reduce_expression(parameter))
|
||||||
|
.collect(),
|
||||||
|
span: format.span.clone(),
|
||||||
|
};
|
||||||
|
match &console_function_call.function {
|
||||||
|
ConsoleFunction::Debug(_) => ConsoleFunction::Debug(formatted),
|
||||||
|
ConsoleFunction::Error(_) => ConsoleFunction::Error(formatted),
|
||||||
|
ConsoleFunction::Log(_) => ConsoleFunction::Log(formatted),
|
||||||
|
_ => unimplemented!(), // impossible
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
self.reducer
|
||||||
|
.reduce_console(console_function_call, function, console_function_call.span.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_expression_statement(&mut self, expression: &ExpressionStatement) -> ExpressionStatement {
|
||||||
|
let inner_expression = self.reduce_expression(&expression.expression);
|
||||||
|
self.reducer
|
||||||
|
.reduce_expression_statement(expression, inner_expression, expression.span.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_block(&mut self, block: &Block) -> Block {
|
||||||
|
let statements = block
|
||||||
|
.statements
|
||||||
|
.iter()
|
||||||
|
.map(|statement| self.reduce_statement(statement))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
self.reducer.reduce_block(block, statements, block.span.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Program
|
||||||
pub fn reduce_program(&mut self, program: &Program) -> Program {
|
pub fn reduce_program(&mut self, program: &Program) -> Program {
|
||||||
let inputs = program
|
let inputs = program
|
||||||
.expected_input
|
.expected_input
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|x| self.reduce_function_input(x))
|
.map(|input| self.reduce_function_input(input))
|
||||||
.collect();
|
.collect();
|
||||||
let imports = program
|
let imports = program
|
||||||
.imports
|
.imports
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|x| self.reduce_import_statement(x))
|
.map(|import| self.reduce_import(import))
|
||||||
.collect();
|
.collect();
|
||||||
let circuits = program
|
let circuits = program
|
||||||
.circuits
|
.circuits
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|(identifier, circuit)| {
|
.map(|(identifier, circuit)| (self.reduce_identifier(identifier), self.reduce_circuit(circuit)))
|
||||||
Some((self.reduce_identifier(identifier), self.reduce_circuit(circuit)?))
|
|
||||||
})
|
|
||||||
.collect();
|
.collect();
|
||||||
let functions = program
|
let functions = program
|
||||||
.functions
|
.functions
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|(identifier, function)| {
|
.map(|(identifier, function)| (self.reduce_identifier(identifier), self.reduce_function(function)))
|
||||||
Some((self.reduce_identifier(identifier), self.reduce_function(function)?))
|
|
||||||
})
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
self.reducer
|
self.reducer
|
||||||
.reduce_program(program, inputs, imports, circuits, functions)
|
.reduce_program(program, inputs, imports, circuits, functions)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reduce_function_input(&mut self, input: &FunctionInput) -> Option<FunctionInput> {
|
pub fn reduce_function_input_variable(&mut self, variable: &FunctionInputVariable) -> FunctionInputVariable {
|
||||||
let item = match input {
|
let identifier = self.reduce_identifier(&variable.identifier);
|
||||||
FunctionInput::InputKeyword(input_keyword) => FunctionInput::InputKeyword(input_keyword.clone()),
|
let type_ = self.reduce_type(&variable.type_);
|
||||||
FunctionInput::SelfKeyword(self_keyword) => FunctionInput::SelfKeyword(self_keyword.clone()),
|
|
||||||
FunctionInput::MutSelfKeyword(mut_self_keyword) => FunctionInput::MutSelfKeyword(mut_self_keyword.clone()),
|
self.reducer
|
||||||
|
.reduce_function_input_variable(variable, identifier, type_, variable.span.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_function_input(&mut self, input: &FunctionInput) -> FunctionInput {
|
||||||
|
let new = match input {
|
||||||
FunctionInput::Variable(function_input_variable) => {
|
FunctionInput::Variable(function_input_variable) => {
|
||||||
FunctionInput::Variable(self.reduce_function_input_variable(function_input_variable))
|
FunctionInput::Variable(self.reduce_function_input_variable(function_input_variable))
|
||||||
}
|
}
|
||||||
|
_ => input.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.reducer.reduce_function_input(input, item)
|
self.reducer.reduce_function_input(input, new)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reduce_import_statement(&mut self, import: &ImportStatement) -> Option<ImportStatement> {
|
pub fn reduce_package_or_packages(&mut self, package_or_packages: &PackageOrPackages) -> PackageOrPackages {
|
||||||
let package = self.reduce_package(&import.package_or_packages);
|
let new = match package_or_packages {
|
||||||
|
PackageOrPackages::Package(package) => PackageOrPackages::Package(Package {
|
||||||
|
name: self.reduce_identifier(&package.name),
|
||||||
|
access: package.access.clone(),
|
||||||
|
span: package.span.clone(),
|
||||||
|
}),
|
||||||
|
PackageOrPackages::Packages(packages) => PackageOrPackages::Packages(Packages {
|
||||||
|
name: self.reduce_identifier(&packages.name),
|
||||||
|
accesses: packages.accesses.clone(),
|
||||||
|
span: packages.span.clone(),
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
self.reducer.reduce_import_statement(import, package)
|
self.reducer.reduce_package_or_packages(package_or_packages, new)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reduce_circuit(&mut self, circuit: &Circuit) -> Option<Circuit> {
|
pub fn reduce_import(&mut self, import: &ImportStatement) -> ImportStatement {
|
||||||
|
let package_or_packages = self.reduce_package_or_packages(&import.package_or_packages);
|
||||||
|
|
||||||
|
self.reducer
|
||||||
|
.reduce_import(import, package_or_packages, import.span.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_circuit_member(&mut self, circuit_member: &CircuitMember) -> CircuitMember {
|
||||||
|
let new = match circuit_member {
|
||||||
|
CircuitMember::CircuitVariable(identifier, type_) => {
|
||||||
|
CircuitMember::CircuitVariable(self.reduce_identifier(&identifier), self.reduce_type(&type_))
|
||||||
|
}
|
||||||
|
CircuitMember::CircuitFunction(function) => CircuitMember::CircuitFunction(self.reduce_function(&function)),
|
||||||
|
};
|
||||||
|
|
||||||
|
self.reducer.reduce_circuit_member(circuit_member, new)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_circuit(&mut self, circuit: &Circuit) -> Circuit {
|
||||||
let circuit_name = self.reduce_identifier(&circuit.circuit_name);
|
let circuit_name = self.reduce_identifier(&circuit.circuit_name);
|
||||||
let members = circuit
|
let members = circuit
|
||||||
.members
|
.members
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|x| self.reduce_circuit_member(x))
|
.map(|member| self.reduce_circuit_member(member))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
self.reducer.reduce_circuit(circuit, circuit_name, members)
|
self.reducer.reduce_circuit(circuit, circuit_name, members)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reduce_function(&mut self, function: &Function) -> Option<Function> {
|
fn reduce_annotation(&mut self, annotation: &Annotation) -> Annotation {
|
||||||
|
let name = self.reduce_identifier(&annotation.name);
|
||||||
|
|
||||||
|
self.reducer
|
||||||
|
.reduce_annotation(annotation, annotation.span.clone(), name)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reduce_function(&mut self, function: &Function) -> Function {
|
||||||
let identifier = self.reduce_identifier(&function.identifier);
|
let identifier = self.reduce_identifier(&function.identifier);
|
||||||
let annotations = function.annotations.clone(); // TODO reduce
|
let annotations = function
|
||||||
|
.annotations
|
||||||
|
.iter()
|
||||||
|
.map(|annotation| self.reduce_annotation(annotation))
|
||||||
|
.collect();
|
||||||
let input = function
|
let input = function
|
||||||
.input
|
.input
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|x| self.reduce_function_input(x))
|
.map(|input| self.reduce_function_input(input))
|
||||||
.collect();
|
.collect();
|
||||||
let output = function.output.as_ref().map(|x| self.reduce_type(x));
|
let output = function.output.as_ref().map(|output| self.reduce_type(output));
|
||||||
let block = Block {
|
let block = self.reduce_block(&function.block);
|
||||||
statements: function
|
|
||||||
.block
|
|
||||||
.statements
|
|
||||||
.iter()
|
|
||||||
.map(|x| self.reduce_statement(x))
|
|
||||||
.collect(),
|
|
||||||
span: function.block.span.clone(),
|
|
||||||
};
|
|
||||||
|
|
||||||
self.reducer
|
self.reducer.reduce_function(
|
||||||
.reduce_function(function, annotations, identifier, input, output, block)
|
function,
|
||||||
}
|
identifier,
|
||||||
|
annotations,
|
||||||
pub fn reduce_identifier(&mut self, identifier: &Identifier) -> Identifier {
|
input,
|
||||||
self.reducer.reduce_identifier(identifier)
|
output,
|
||||||
}
|
block,
|
||||||
|
function.span.clone(),
|
||||||
pub fn reduce_function_input_variable(
|
)
|
||||||
&mut self,
|
|
||||||
function_input_variable: &FunctionInputVariable,
|
|
||||||
) -> FunctionInputVariable {
|
|
||||||
let identifier = self.reduce_identifier(&function_input_variable.identifier);
|
|
||||||
let type_ = self.reduce_type(&function_input_variable.type_);
|
|
||||||
|
|
||||||
self.reducer
|
|
||||||
.reduce_function_input_variable(function_input_variable, identifier, type_)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reduce_type(&mut self, type_: &Type) -> Type {
|
|
||||||
let items = match type_ {
|
|
||||||
// Data type wrappers
|
|
||||||
Type::Array(type_, dimensions) => Type::Array(Box::new(self.reduce_type(type_)), dimensions.clone()),
|
|
||||||
Type::Tuple(types) => Type::Tuple(types.iter().map(|x| self.reduce_type(x)).collect()),
|
|
||||||
Type::Circuit(identifier) => Type::Circuit(self.reduce_identifier(identifier)),
|
|
||||||
_ => type_.clone(),
|
|
||||||
};
|
|
||||||
|
|
||||||
self.reducer.reduce_type(type_, items)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reduce_package(&mut self, package_or_packages: &PackageOrPackages) -> PackageOrPackages {
|
|
||||||
self.reducer.reduce_package(package_or_packages)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reduce_circuit_member(&mut self, circuit_member: &CircuitMember) -> Option<CircuitMember> {
|
|
||||||
let items = match circuit_member {
|
|
||||||
CircuitMember::CircuitVariable(identifier, type_) => {
|
|
||||||
CircuitMember::CircuitVariable(self.reduce_identifier(identifier), self.reduce_type(type_))
|
|
||||||
}
|
|
||||||
CircuitMember::CircuitFunction(function) => CircuitMember::CircuitFunction(self.reduce_function(function)?),
|
|
||||||
};
|
|
||||||
|
|
||||||
self.reducer.reduce_circuit_member(circuit_member, items)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reduce_statement(&mut self, statement: &Statement) -> Statement {
|
|
||||||
let items = match statement {
|
|
||||||
Statement::Return(return_statement) => Statement::Return(ReturnStatement {
|
|
||||||
expression: self.reduce_expression(&return_statement.expression),
|
|
||||||
span: return_statement.span.clone(),
|
|
||||||
}),
|
|
||||||
Statement::Definition(definition) => Statement::Definition(DefinitionStatement {
|
|
||||||
declaration_type: definition.declaration_type.clone(),
|
|
||||||
variable_names: definition
|
|
||||||
.variable_names
|
|
||||||
.iter()
|
|
||||||
.map(|variable_name| self.reduce_variable_name(variable_name))
|
|
||||||
.collect(),
|
|
||||||
type_: definition.type_.as_ref().map(|inner| self.reduce_type(&inner)),
|
|
||||||
value: self.reduce_expression(&definition.value),
|
|
||||||
span: definition.span.clone(),
|
|
||||||
}),
|
|
||||||
Statement::Assign(assign) => Statement::Assign(AssignStatement {
|
|
||||||
operation: assign.operation.clone(),
|
|
||||||
assignee: Assignee {
|
|
||||||
identifier: self.reduce_identifier(&assign.assignee.identifier),
|
|
||||||
accesses: assign
|
|
||||||
.assignee
|
|
||||||
.accesses
|
|
||||||
.iter()
|
|
||||||
.filter_map(|x| self.reduce_assignee_access(x))
|
|
||||||
.collect(),
|
|
||||||
span: assign.assignee.span.clone(),
|
|
||||||
},
|
|
||||||
value: self.reduce_expression(&assign.value),
|
|
||||||
span: assign.span.clone(),
|
|
||||||
}),
|
|
||||||
Statement::Conditional(conditional) => {
|
|
||||||
Statement::Conditional(self.reduce_conditional_statement(conditional))
|
|
||||||
}
|
|
||||||
Statement::Iteration(iteration) => {
|
|
||||||
Statement::Iteration(IterationStatement {
|
|
||||||
variable: self.reduce_identifier(&iteration.variable),
|
|
||||||
start: self.reduce_expression(&iteration.start),
|
|
||||||
stop: self.reduce_expression(&iteration.stop),
|
|
||||||
block: Block {
|
|
||||||
statements: iteration
|
|
||||||
.block
|
|
||||||
.statements
|
|
||||||
.iter()
|
|
||||||
.map(|statement| self.reduce_statement(statement))
|
|
||||||
.collect(),
|
|
||||||
span: iteration.block.span.clone(),
|
|
||||||
}, // TODO reduce block that isn't in a statement
|
|
||||||
span: iteration.span.clone(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Statement::Console(console_function_call) => {
|
|
||||||
let function = match &console_function_call.function {
|
|
||||||
ConsoleFunction::Assert(expression) => ConsoleFunction::Assert(self.reduce_expression(expression)),
|
|
||||||
ConsoleFunction::Debug(format) | ConsoleFunction::Error(format) | ConsoleFunction::Log(format) => {
|
|
||||||
let formatted = FormattedString {
|
|
||||||
parts: format.parts.clone(),
|
|
||||||
parameters: format
|
|
||||||
.parameters
|
|
||||||
.iter()
|
|
||||||
.map(|parameter| self.reduce_expression(¶meter))
|
|
||||||
.collect(),
|
|
||||||
span: format.span.clone(),
|
|
||||||
};
|
|
||||||
match &console_function_call.function {
|
|
||||||
ConsoleFunction::Debug(_) => ConsoleFunction::Debug(formatted),
|
|
||||||
ConsoleFunction::Error(_) => ConsoleFunction::Error(formatted),
|
|
||||||
ConsoleFunction::Log(_) => ConsoleFunction::Log(formatted),
|
|
||||||
_ => unimplemented!(), // impossible
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Statement::Console(ConsoleStatement {
|
|
||||||
function,
|
|
||||||
span: console_function_call.span.clone(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Statement::Expression(expression) => Statement::Expression(ExpressionStatement {
|
|
||||||
expression: self.reduce_expression(&expression.expression),
|
|
||||||
span: expression.span.clone(),
|
|
||||||
}),
|
|
||||||
Statement::Block(block) => Statement::Block(Block {
|
|
||||||
statements: block
|
|
||||||
.statements
|
|
||||||
.iter()
|
|
||||||
.map(|statement| self.reduce_statement(statement))
|
|
||||||
.collect(),
|
|
||||||
span: block.span.clone(),
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
self.reducer.reduce_statement(statement, items)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reduce_assignee_access(&mut self, assignee_access: &AssigneeAccess) -> Option<AssigneeAccess> {
|
|
||||||
let item = match assignee_access {
|
|
||||||
AssigneeAccess::ArrayRange(start, stop) => {
|
|
||||||
let start_item = start.as_ref().map(|x| self.reduce_expression(x));
|
|
||||||
let stop_item = stop.as_ref().map(|x| self.reduce_expression(x));
|
|
||||||
AssigneeAccess::ArrayRange(start_item, stop_item)
|
|
||||||
}
|
|
||||||
AssigneeAccess::ArrayIndex(expression) => AssigneeAccess::ArrayIndex(self.reduce_expression(&expression)),
|
|
||||||
AssigneeAccess::Tuple(number, span) => AssigneeAccess::Tuple(number.clone(), span.clone()),
|
|
||||||
AssigneeAccess::Member(identifier) => {
|
|
||||||
let identifier = self.reduce_identifier(identifier);
|
|
||||||
AssigneeAccess::Member(identifier)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
self.reducer.reduce_assignee_access(assignee_access, item)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reduce_conditional_statement(&mut self, statement: &ConditionalStatement) -> ConditionalStatement {
|
|
||||||
let condition = self.reduce_expression(&statement.condition);
|
|
||||||
let statements = Block {
|
|
||||||
statements: statement
|
|
||||||
.block
|
|
||||||
.statements
|
|
||||||
.iter()
|
|
||||||
.map(|x| self.reduce_statement(x))
|
|
||||||
.collect(),
|
|
||||||
span: statement.block.span.clone(),
|
|
||||||
};
|
|
||||||
let next = statement.next.as_ref().map(|x| self.reduce_statement(x));
|
|
||||||
|
|
||||||
self.reducer
|
|
||||||
.reduce_conditional_statement(statement, condition, statements, next)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reduce_variable_name(&mut self, variable_name: &VariableName) -> VariableName {
|
|
||||||
let identifier = self.reduce_identifier(&variable_name.identifier);
|
|
||||||
|
|
||||||
self.reducer.reduce_variable_name(variable_name, identifier)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reduce_expression(&mut self, expression: &Expression) -> Expression {
|
|
||||||
let items = match expression {
|
|
||||||
Expression::Identifier(identifier) => Expression::Identifier(self.reduce_identifier(identifier)),
|
|
||||||
// Expression::Value(value) => Expression::Value(self.reduce_expression(value.))
|
|
||||||
Expression::Binary(binary) => {
|
|
||||||
let left = Box::new(self.reduce_expression(&binary.left));
|
|
||||||
let right = Box::new(self.reduce_expression(&binary.right));
|
|
||||||
|
|
||||||
Expression::Binary(BinaryExpression {
|
|
||||||
left,
|
|
||||||
right,
|
|
||||||
op: binary.op.clone(),
|
|
||||||
span: binary.span.clone(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Expression::Unary(unary) => {
|
|
||||||
let inner = Box::new(self.reduce_expression(&unary.inner));
|
|
||||||
|
|
||||||
Expression::Unary(UnaryExpression {
|
|
||||||
inner,
|
|
||||||
op: unary.op.clone(),
|
|
||||||
span: unary.span.clone(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Expression::Ternary(ternary) => {
|
|
||||||
let condition = Box::new(self.reduce_expression(&ternary.condition));
|
|
||||||
let if_true = Box::new(self.reduce_expression(&ternary.if_true));
|
|
||||||
let if_false = Box::new(self.reduce_expression(&ternary.if_false));
|
|
||||||
|
|
||||||
Expression::Ternary(TernaryExpression {
|
|
||||||
condition,
|
|
||||||
if_true,
|
|
||||||
if_false,
|
|
||||||
span: ternary.span.clone(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
Expression::ArrayInline(array_inline) => {
|
|
||||||
let elements = array_inline
|
|
||||||
.elements
|
|
||||||
.iter()
|
|
||||||
.map(|x| match x {
|
|
||||||
SpreadOrExpression::Expression(expression) => {
|
|
||||||
SpreadOrExpression::Expression(self.reduce_expression(expression))
|
|
||||||
}
|
|
||||||
SpreadOrExpression::Spread(expression) => {
|
|
||||||
SpreadOrExpression::Spread(self.reduce_expression(expression))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
Expression::ArrayInline(ArrayInlineExpression {
|
|
||||||
elements,
|
|
||||||
span: array_inline.span.clone(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Expression::ArrayInit(array_init) => {
|
|
||||||
let element = Box::new(self.reduce_expression(&array_init.element));
|
|
||||||
|
|
||||||
Expression::ArrayInit(ArrayInitExpression {
|
|
||||||
element,
|
|
||||||
dimensions: array_init.dimensions.clone(),
|
|
||||||
span: array_init.span.clone(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Expression::ArrayAccess(array_access) => {
|
|
||||||
let array = Box::new(self.reduce_expression(&array_access.array));
|
|
||||||
let index = Box::new(self.reduce_expression(&array_access.index));
|
|
||||||
Expression::ArrayAccess(ArrayAccessExpression {
|
|
||||||
array,
|
|
||||||
index,
|
|
||||||
span: array_access.span.clone(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Expression::ArrayRangeAccess(array_range_access) => {
|
|
||||||
let array = Box::new(self.reduce_expression(&array_range_access.array));
|
|
||||||
let left = array_range_access
|
|
||||||
.left
|
|
||||||
.as_ref()
|
|
||||||
.map(|left| Box::new(self.reduce_expression(&left)));
|
|
||||||
let right = array_range_access
|
|
||||||
.right
|
|
||||||
.as_ref()
|
|
||||||
.map(|right| Box::new(self.reduce_expression(&right)));
|
|
||||||
|
|
||||||
Expression::ArrayRangeAccess(ArrayRangeAccessExpression {
|
|
||||||
array,
|
|
||||||
left,
|
|
||||||
right,
|
|
||||||
span: array_range_access.span.clone(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
Expression::TupleInit(tuple_init) => {
|
|
||||||
let elements = tuple_init.elements.iter().map(|x| self.reduce_expression(x)).collect();
|
|
||||||
|
|
||||||
Expression::TupleInit(TupleInitExpression {
|
|
||||||
elements,
|
|
||||||
span: tuple_init.span.clone(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Expression::TupleAccess(tuple_access) => {
|
|
||||||
let tuple = Box::new(self.reduce_expression(&tuple_access.tuple));
|
|
||||||
|
|
||||||
Expression::TupleAccess(TupleAccessExpression {
|
|
||||||
tuple,
|
|
||||||
index: tuple_access.index.clone(),
|
|
||||||
span: tuple_access.span.clone(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Expression::CircuitInit(circuit_init) => {
|
|
||||||
let name = self.reduce_identifier(&circuit_init.name);
|
|
||||||
let members = circuit_init
|
|
||||||
.members
|
|
||||||
.iter()
|
|
||||||
.map(|definition| {
|
|
||||||
let identifier = self.reduce_identifier(&definition.identifier);
|
|
||||||
let expression = definition.expression.as_ref().map(|expr| self.reduce_expression(&expr));
|
|
||||||
|
|
||||||
CircuitImpliedVariableDefinition { identifier, expression }
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
Expression::CircuitInit(CircuitInitExpression {
|
|
||||||
name,
|
|
||||||
members,
|
|
||||||
span: circuit_init.span.clone(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Expression::CircuitMemberAccess(circuit_member_access) => {
|
|
||||||
let circuit = Box::new(self.reduce_expression(&circuit_member_access.circuit));
|
|
||||||
let name = self.reduce_identifier(&circuit_member_access.name);
|
|
||||||
|
|
||||||
Expression::CircuitMemberAccess(CircuitMemberAccessExpression {
|
|
||||||
circuit,
|
|
||||||
name,
|
|
||||||
span: circuit_member_access.span.clone(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Expression::CircuitStaticFunctionAccess(circuit_static_func_access) => {
|
|
||||||
let circuit = Box::new(self.reduce_expression(&circuit_static_func_access.circuit));
|
|
||||||
let name = self.reduce_identifier(&circuit_static_func_access.name);
|
|
||||||
|
|
||||||
Expression::CircuitStaticFunctionAccess(CircuitStaticFunctionAccessExpression {
|
|
||||||
circuit,
|
|
||||||
name,
|
|
||||||
span: circuit_static_func_access.span.clone(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Expression::Call(call) => {
|
|
||||||
let function = Box::new(self.reduce_expression(&call.function));
|
|
||||||
let arguments = call.arguments.iter().map(|x| self.reduce_expression(x)).collect();
|
|
||||||
|
|
||||||
Expression::Call(CallExpression {
|
|
||||||
function,
|
|
||||||
arguments,
|
|
||||||
span: call.span.clone(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
x => x.clone(), // leaf nodes we dont reconstruct
|
|
||||||
};
|
|
||||||
|
|
||||||
self.reducer.reduce_expression(expression, items)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,36 +14,364 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// 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/>.
|
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//! This module contains the reducer which iterates through ast nodes - converting them into
|
use crate::*;
|
||||||
//! asg nodes and saving relevant information.
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
Annotation,
|
|
||||||
AssigneeAccess,
|
|
||||||
Block,
|
|
||||||
Circuit,
|
|
||||||
CircuitMember,
|
|
||||||
ConditionalStatement,
|
|
||||||
Expression,
|
|
||||||
Function,
|
|
||||||
FunctionInput,
|
|
||||||
FunctionInputVariable,
|
|
||||||
Identifier,
|
|
||||||
ImportStatement,
|
|
||||||
Package,
|
|
||||||
PackageOrPackages,
|
|
||||||
Packages,
|
|
||||||
Program,
|
|
||||||
Statement,
|
|
||||||
Type,
|
|
||||||
VariableName,
|
|
||||||
};
|
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
// Needed to fix clippy bug.
|
||||||
#[allow(clippy::redundant_closure)] // Clippy bug line 188
|
#[allow(clippy::redudant_closure)]
|
||||||
pub trait ReconstructingReducer {
|
pub trait ReconstructingReducer {
|
||||||
// ciruits/functions/tests map identifier -> (identifier_item, value_item)
|
fn reduce_type(&mut self, _type_: &Type, new: Type) -> Type {
|
||||||
|
new
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expressions
|
||||||
|
fn reduce_expression(&mut self, _expression: &Expression, new: Expression) -> Expression {
|
||||||
|
new
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_identifier(&mut self, identifier: &Identifier, span: Span) -> Identifier {
|
||||||
|
Identifier {
|
||||||
|
name: identifier.name.clone(),
|
||||||
|
span,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_group_tuple(&mut self, group_tuple: &GroupTuple, span: Span) -> GroupTuple {
|
||||||
|
GroupTuple {
|
||||||
|
x: group_tuple.x.clone(),
|
||||||
|
y: group_tuple.y.clone(),
|
||||||
|
span,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_group_value(&mut self, _group_value: &GroupValue, new: GroupValue) -> GroupValue {
|
||||||
|
new
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_value(&mut self, _value: &ValueExpression, new: ValueExpression) -> ValueExpression {
|
||||||
|
new
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_binary(
|
||||||
|
&mut self,
|
||||||
|
_binary: &BinaryExpression,
|
||||||
|
left: Expression,
|
||||||
|
right: Expression,
|
||||||
|
op: BinaryOperation,
|
||||||
|
span: Span,
|
||||||
|
) -> BinaryExpression {
|
||||||
|
BinaryExpression {
|
||||||
|
left: Box::new(left),
|
||||||
|
right: Box::new(right),
|
||||||
|
op,
|
||||||
|
span,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_unary(
|
||||||
|
&mut self,
|
||||||
|
_unary: &UnaryExpression,
|
||||||
|
inner: Expression,
|
||||||
|
op: UnaryOperation,
|
||||||
|
span: Span,
|
||||||
|
) -> UnaryExpression {
|
||||||
|
UnaryExpression {
|
||||||
|
inner: Box::new(inner),
|
||||||
|
op,
|
||||||
|
span,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_ternary(
|
||||||
|
&mut self,
|
||||||
|
_ternary: &TernaryExpression,
|
||||||
|
condition: Expression,
|
||||||
|
if_true: Expression,
|
||||||
|
if_false: Expression,
|
||||||
|
span: Span,
|
||||||
|
) -> TernaryExpression {
|
||||||
|
TernaryExpression {
|
||||||
|
condition: Box::new(condition),
|
||||||
|
if_true: Box::new(if_true),
|
||||||
|
if_false: Box::new(if_false),
|
||||||
|
span,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_cast(
|
||||||
|
&mut self,
|
||||||
|
_cast: &CastExpression,
|
||||||
|
inner: Expression,
|
||||||
|
target_type: Type,
|
||||||
|
span: Span,
|
||||||
|
) -> CastExpression {
|
||||||
|
CastExpression {
|
||||||
|
inner: Box::new(inner),
|
||||||
|
target_type,
|
||||||
|
span,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_array_inline(
|
||||||
|
&mut self,
|
||||||
|
_array_inline: &ArrayInlineExpression,
|
||||||
|
elements: Vec<SpreadOrExpression>,
|
||||||
|
span: Span,
|
||||||
|
) -> ArrayInlineExpression {
|
||||||
|
ArrayInlineExpression { elements, span }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_array_init(
|
||||||
|
&mut self,
|
||||||
|
array_init: &ArrayInitExpression,
|
||||||
|
element: Expression,
|
||||||
|
span: Span,
|
||||||
|
) -> ArrayInitExpression {
|
||||||
|
ArrayInitExpression {
|
||||||
|
element: Box::new(element),
|
||||||
|
dimensions: array_init.dimensions.clone(),
|
||||||
|
span,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_array_access(
|
||||||
|
&mut self,
|
||||||
|
_array_access: &ArrayAccessExpression,
|
||||||
|
array: Expression,
|
||||||
|
index: Expression,
|
||||||
|
span: Span,
|
||||||
|
) -> ArrayAccessExpression {
|
||||||
|
ArrayAccessExpression {
|
||||||
|
array: Box::new(array),
|
||||||
|
index: Box::new(index),
|
||||||
|
span,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_array_range_access(
|
||||||
|
&mut self,
|
||||||
|
_array_rage_access: &ArrayRangeAccessExpression,
|
||||||
|
array: Expression,
|
||||||
|
left: Option<Expression>,
|
||||||
|
right: Option<Expression>,
|
||||||
|
span: Span,
|
||||||
|
) -> ArrayRangeAccessExpression {
|
||||||
|
ArrayRangeAccessExpression {
|
||||||
|
array: Box::new(array),
|
||||||
|
left: left.map(|expr| Box::new(expr)),
|
||||||
|
right: right.map(|expr| Box::new(expr)),
|
||||||
|
span,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_tuple_init(
|
||||||
|
&mut self,
|
||||||
|
_tuple_init: &TupleInitExpression,
|
||||||
|
elements: Vec<Expression>,
|
||||||
|
span: Span,
|
||||||
|
) -> TupleInitExpression {
|
||||||
|
TupleInitExpression { elements, span }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_tuple_access(
|
||||||
|
&mut self,
|
||||||
|
tuple_access: &TupleAccessExpression,
|
||||||
|
tuple: Expression,
|
||||||
|
span: Span,
|
||||||
|
) -> TupleAccessExpression {
|
||||||
|
TupleAccessExpression {
|
||||||
|
tuple: Box::new(tuple),
|
||||||
|
index: tuple_access.index.clone(),
|
||||||
|
span,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_circuit_init(
|
||||||
|
&mut self,
|
||||||
|
_circuit_init: &CircuitInitExpression,
|
||||||
|
name: Identifier,
|
||||||
|
members: Vec<CircuitImpliedVariableDefinition>,
|
||||||
|
span: Span,
|
||||||
|
) -> CircuitInitExpression {
|
||||||
|
CircuitInitExpression { name, members, span }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_circuit_member_access(
|
||||||
|
&mut self,
|
||||||
|
_circuit_member_access: &CircuitMemberAccessExpression,
|
||||||
|
circuit: Expression,
|
||||||
|
name: Identifier,
|
||||||
|
span: Span,
|
||||||
|
) -> CircuitMemberAccessExpression {
|
||||||
|
CircuitMemberAccessExpression {
|
||||||
|
circuit: Box::new(circuit),
|
||||||
|
name,
|
||||||
|
span,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_circuit_static_fn_access(
|
||||||
|
&mut self,
|
||||||
|
_circuit_static_fn_access: &CircuitStaticFunctionAccessExpression,
|
||||||
|
circuit: Expression,
|
||||||
|
name: Identifier,
|
||||||
|
span: Span,
|
||||||
|
) -> CircuitStaticFunctionAccessExpression {
|
||||||
|
CircuitStaticFunctionAccessExpression {
|
||||||
|
circuit: Box::new(circuit),
|
||||||
|
name,
|
||||||
|
span,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_call(
|
||||||
|
&mut self,
|
||||||
|
_call: &CallExpression,
|
||||||
|
function: Expression,
|
||||||
|
arguments: Vec<Expression>,
|
||||||
|
span: Span,
|
||||||
|
) -> CallExpression {
|
||||||
|
CallExpression {
|
||||||
|
function: Box::new(function),
|
||||||
|
arguments,
|
||||||
|
span,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Statements
|
||||||
|
fn reduce_statement(&mut self, _statement: &Statement, new: Statement) -> Statement {
|
||||||
|
new
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_return(
|
||||||
|
&mut self,
|
||||||
|
_return_statement: &ReturnStatement,
|
||||||
|
expression: Expression,
|
||||||
|
span: Span,
|
||||||
|
) -> ReturnStatement {
|
||||||
|
ReturnStatement { expression, span }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_variable_name(
|
||||||
|
&mut self,
|
||||||
|
variable_name: &VariableName,
|
||||||
|
identifier: Identifier,
|
||||||
|
span: Span,
|
||||||
|
) -> VariableName {
|
||||||
|
VariableName {
|
||||||
|
mutable: variable_name.mutable.clone(),
|
||||||
|
identifier,
|
||||||
|
span,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_definition(
|
||||||
|
&mut self,
|
||||||
|
definition: &DefinitionStatement,
|
||||||
|
variable_names: Vec<VariableName>,
|
||||||
|
type_: Option<Type>,
|
||||||
|
value: Expression,
|
||||||
|
span: Span,
|
||||||
|
) -> DefinitionStatement {
|
||||||
|
DefinitionStatement {
|
||||||
|
declaration_type: definition.declaration_type.clone(),
|
||||||
|
variable_names,
|
||||||
|
type_,
|
||||||
|
value,
|
||||||
|
span,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_assignee_access(&mut self, _access: &AssigneeAccess, new: AssigneeAccess) -> AssigneeAccess {
|
||||||
|
new
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_assignee(
|
||||||
|
&mut self,
|
||||||
|
_assignee: &Assignee,
|
||||||
|
identifier: Identifier,
|
||||||
|
accesses: Vec<AssigneeAccess>,
|
||||||
|
span: Span,
|
||||||
|
) -> Assignee {
|
||||||
|
Assignee {
|
||||||
|
identifier,
|
||||||
|
accesses,
|
||||||
|
span,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_assign(
|
||||||
|
&mut self,
|
||||||
|
assign: &AssignStatement,
|
||||||
|
assignee: Assignee,
|
||||||
|
value: Expression,
|
||||||
|
span: Span,
|
||||||
|
) -> AssignStatement {
|
||||||
|
AssignStatement {
|
||||||
|
operation: assign.operation.clone(),
|
||||||
|
assignee,
|
||||||
|
value,
|
||||||
|
span,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_conditional(
|
||||||
|
&mut self,
|
||||||
|
_conditional: &ConditionalStatement,
|
||||||
|
condition: Expression,
|
||||||
|
block: Block,
|
||||||
|
statement: Option<Statement>,
|
||||||
|
span: Span,
|
||||||
|
) -> ConditionalStatement {
|
||||||
|
ConditionalStatement {
|
||||||
|
condition,
|
||||||
|
block,
|
||||||
|
next: statement.map(|statement| Box::new(statement)),
|
||||||
|
span,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_iteration(
|
||||||
|
&mut self,
|
||||||
|
_iteration: &IterationStatement,
|
||||||
|
variable: Identifier,
|
||||||
|
start: Expression,
|
||||||
|
stop: Expression,
|
||||||
|
block: Block,
|
||||||
|
span: Span,
|
||||||
|
) -> IterationStatement {
|
||||||
|
IterationStatement {
|
||||||
|
variable,
|
||||||
|
start,
|
||||||
|
stop,
|
||||||
|
block,
|
||||||
|
span,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_console(
|
||||||
|
&mut self,
|
||||||
|
_console: &ConsoleStatement,
|
||||||
|
function: ConsoleFunction,
|
||||||
|
span: Span,
|
||||||
|
) -> ConsoleStatement {
|
||||||
|
ConsoleStatement { function, span }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_expression_statement(
|
||||||
|
&mut self,
|
||||||
|
_expression_statement: &ExpressionStatement,
|
||||||
|
expression: Expression,
|
||||||
|
span: Span,
|
||||||
|
) -> ExpressionStatement {
|
||||||
|
ExpressionStatement { expression, span }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_block(&mut self, _block: &Block, statements: Vec<Statement>, span: Span) -> Block {
|
||||||
|
Block { statements, span }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Program
|
||||||
fn reduce_program(
|
fn reduce_program(
|
||||||
&mut self,
|
&mut self,
|
||||||
program: &Program,
|
program: &Program,
|
||||||
@ -61,135 +389,80 @@ pub trait ReconstructingReducer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reduce_function_input(&mut self, input: &FunctionInput, item: FunctionInput) -> Option<FunctionInput> {
|
|
||||||
Some(item)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reduce_import_statement(
|
|
||||||
&mut self,
|
|
||||||
import: &ImportStatement,
|
|
||||||
package_or_packages: PackageOrPackages,
|
|
||||||
) -> Option<ImportStatement> {
|
|
||||||
Some(ImportStatement {
|
|
||||||
package_or_packages,
|
|
||||||
span: import.span.clone(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reduce_circuit(
|
|
||||||
&mut self,
|
|
||||||
circuit: &Circuit,
|
|
||||||
circuit_name: Identifier,
|
|
||||||
members: Vec<CircuitMember>,
|
|
||||||
) -> Option<Circuit> {
|
|
||||||
Some(Circuit { circuit_name, members })
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reduce_function(
|
|
||||||
&mut self,
|
|
||||||
function: &Function,
|
|
||||||
annotations: Vec<Annotation>,
|
|
||||||
identifier: Identifier,
|
|
||||||
input: Vec<FunctionInput>,
|
|
||||||
output: Option<Type>,
|
|
||||||
block: Block,
|
|
||||||
) -> Option<Function> {
|
|
||||||
Some(Function {
|
|
||||||
annotations,
|
|
||||||
identifier,
|
|
||||||
input,
|
|
||||||
output,
|
|
||||||
block,
|
|
||||||
span: function.span.clone(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reduce_identifier(&mut self, identifier: &Identifier) -> Identifier {
|
|
||||||
identifier.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reduce_function_input_variable(
|
fn reduce_function_input_variable(
|
||||||
&mut self,
|
&mut self,
|
||||||
function_input_variable: &FunctionInputVariable,
|
variable: &FunctionInputVariable,
|
||||||
identifier: Identifier,
|
identifier: Identifier,
|
||||||
type_: Type,
|
type_: Type,
|
||||||
|
span: Span,
|
||||||
) -> FunctionInputVariable {
|
) -> FunctionInputVariable {
|
||||||
FunctionInputVariable {
|
FunctionInputVariable {
|
||||||
identifier,
|
identifier,
|
||||||
const_: function_input_variable.const_,
|
const_: variable.const_.clone(),
|
||||||
mutable: function_input_variable.mutable,
|
mutable: variable.mutable,
|
||||||
type_,
|
type_,
|
||||||
span: function_input_variable.span.clone(),
|
span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reduce_type(&mut self, type_: &Type, items: Type) -> Type {
|
fn reduce_function_input(&mut self, _input: &FunctionInput, new: FunctionInput) -> FunctionInput {
|
||||||
items
|
new
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reduce_package(&mut self, package_or_packages: &PackageOrPackages) -> PackageOrPackages {
|
fn reduce_package_or_packages(
|
||||||
match package_or_packages {
|
&mut self,
|
||||||
PackageOrPackages::Package(package) => {
|
_package_or_packages: &PackageOrPackages,
|
||||||
let name = self.reduce_identifier(&package.name);
|
new: PackageOrPackages,
|
||||||
|
) -> PackageOrPackages {
|
||||||
|
new
|
||||||
|
}
|
||||||
|
|
||||||
PackageOrPackages::Package(Package {
|
fn reduce_import(
|
||||||
name,
|
&mut self,
|
||||||
access: package.access.clone(),
|
_import: &ImportStatement,
|
||||||
span: package.span.clone(),
|
package_or_packages: PackageOrPackages,
|
||||||
})
|
span: Span,
|
||||||
}
|
) -> ImportStatement {
|
||||||
PackageOrPackages::Packages(packages) => {
|
ImportStatement {
|
||||||
let name = self.reduce_identifier(&packages.name);
|
package_or_packages,
|
||||||
|
span,
|
||||||
PackageOrPackages::Packages(Packages {
|
|
||||||
name,
|
|
||||||
accesses: packages.accesses.clone(),
|
|
||||||
span: packages.span.clone(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reduce_circuit_member(&mut self, circuit_member: &CircuitMember, items: CircuitMember) -> Option<CircuitMember> {
|
fn reduce_circuit_member(&mut self, _circuit_member: &CircuitMember, new: CircuitMember) -> CircuitMember {
|
||||||
Some(items)
|
new
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reduce_statement(&mut self, statement: &Statement, items: Statement) -> Statement {
|
fn reduce_circuit(&mut self, _circuit: &Circuit, circuit_name: Identifier, members: Vec<CircuitMember>) -> Circuit {
|
||||||
items
|
Circuit { circuit_name, members }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reduce_assignee_access(
|
fn reduce_annotation(&mut self, annotation: &Annotation, span: Span, name: Identifier) -> Annotation {
|
||||||
|
Annotation {
|
||||||
|
span,
|
||||||
|
name,
|
||||||
|
arguments: annotation.arguments.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
fn reduce_function(
|
||||||
&mut self,
|
&mut self,
|
||||||
assignee_access: &AssigneeAccess,
|
_function: &Function,
|
||||||
item: AssigneeAccess,
|
identifier: Identifier,
|
||||||
) -> Option<AssigneeAccess> {
|
annotations: Vec<Annotation>,
|
||||||
Some(item)
|
input: Vec<FunctionInput>,
|
||||||
}
|
output: Option<Type>,
|
||||||
|
|
||||||
fn reduce_conditional_statement(
|
|
||||||
&mut self,
|
|
||||||
statement: &ConditionalStatement,
|
|
||||||
condition: Expression,
|
|
||||||
block: Block,
|
block: Block,
|
||||||
next: Option<Statement>,
|
span: Span,
|
||||||
) -> ConditionalStatement {
|
) -> Function {
|
||||||
ConditionalStatement {
|
Function {
|
||||||
condition,
|
|
||||||
block,
|
|
||||||
next: next.map(|item| Box::new(item)),
|
|
||||||
span: statement.span.clone(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reduce_variable_name(&mut self, variable_name: &VariableName, identifier: Identifier) -> VariableName {
|
|
||||||
VariableName {
|
|
||||||
mutable: variable_name.mutable,
|
|
||||||
identifier,
|
identifier,
|
||||||
span: variable_name.span.clone(),
|
annotations,
|
||||||
|
input,
|
||||||
|
output,
|
||||||
|
block,
|
||||||
|
span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reduce_expression(&mut self, expression: &Expression, items: Expression) -> Expression {
|
|
||||||
items
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user