From 3a1c29e3b2d986ee5158aea4331f8279b1bd096c Mon Sep 17 00:00:00 2001 From: gluax Date: Fri, 12 Mar 2021 20:41:49 -0500 Subject: [PATCH] ready to return real errors, fixed Self outside circuit bugs --- Cargo.lock | 1 + ast/Cargo.toml | 3 + ast/src/lib.rs | 7 + ast/src/reducer/canonicalization.rs | 56 +- ast/src/reducer/reconstructing_director.rs | 598 ++++++++++++--------- ast/src/reducer/reconstructing_reducer.rs | 302 +++++++---- 6 files changed, 586 insertions(+), 381 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 58b0d5dade..fd2e0d86d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1209,6 +1209,7 @@ dependencies = [ name = "leo-ast" version = "1.2.3" dependencies = [ + "anyhow", "criterion", "indexmap", "leo-input", diff --git a/ast/Cargo.toml b/ast/Cargo.toml index 3ec4548606..28a2b8e277 100644 --- a/ast/Cargo.toml +++ b/ast/Cargo.toml @@ -35,6 +35,9 @@ features = ["derive", "rc"] [dependencies.serde_json] version = "1.0" +[dependencies.anyhow] +version = "1.0" + [dependencies.thiserror] version = "1.0" diff --git a/ast/src/lib.rs b/ast/src/lib.rs index 078fda8de0..6800701560 100644 --- a/ast/src/lib.rs +++ b/ast/src/lib.rs @@ -61,6 +61,8 @@ pub use self::types::*; mod node; pub use node::*; +use anyhow::Result; + /// The abstract syntax tree (AST) for a Leo program. /// /// The [`Ast`] type represents a Leo program as a series of recursive data types. @@ -78,6 +80,11 @@ impl Ast { Self { ast: program } } + pub fn canonicalize(&mut self) -> Result<()> { + self.ast = ReconstructingDirector::new(Canonicalizer).reduce_program(self.as_repr())?; + Ok(()) + } + /// Returns a reference to the inner program AST representation. pub fn as_repr(&self) -> &Program { &self.ast diff --git a/ast/src/reducer/canonicalization.rs b/ast/src/reducer/canonicalization.rs index 4ddbf0e232..9dde3a1886 100644 --- a/ast/src/reducer/canonicalization.rs +++ b/ast/src/reducer/canonicalization.rs @@ -15,7 +15,7 @@ // along with the Leo library. If not, see . use crate::*; -// use indexmap::IndexMap; +use anyhow::Result; pub struct Canonicalizer; @@ -143,7 +143,7 @@ impl Canonicalizer { } impl ReconstructingReducer for Canonicalizer { - fn reduce_type(&mut self, _type_: &Type, new: Type, in_circuit: bool) -> Type { + fn reduce_type(&mut self, _type_: &Type, new: Type, in_circuit: bool) -> Result { match new { Type::Array(_, mut dimensions) => { // TODO need to throw errors in all these. @@ -166,17 +166,22 @@ impl ReconstructingReducer for Canonicalizer { next = array.clone(); } - array + Ok(array) } Type::SelfType if !in_circuit => { println!("Brrr bad Self"); - new.clone() + Ok(new.clone()) } - _ => new.clone(), + _ => Ok(new.clone()), } } - fn reduce_array_init(&mut self, array_init: &ArrayInitExpression, element: Expression) -> ArrayInitExpression { + fn reduce_array_init( + &mut self, + array_init: &ArrayInitExpression, + element: Expression, + _in_circuit: bool, + ) -> Result { // TODO ERROR HERE if len is 0 // if array_init.dimensions.0.len() == 0 { @@ -185,11 +190,11 @@ impl ReconstructingReducer for Canonicalizer { let element = Box::new(element); if array_init.dimensions.0.len() == 1 { - return ArrayInitExpression { + return Ok(ArrayInitExpression { element, dimensions: array_init.dimensions.clone(), span: array_init.span.clone(), - }; + }); } let mut dimensions = array_init.dimensions.clone(); @@ -214,14 +219,20 @@ impl ReconstructingReducer for Canonicalizer { outer_element = Box::new(next.clone()); } - ArrayInitExpression { + Ok(ArrayInitExpression { element: outer_element, dimensions: ArrayDimensions(vec![dimensions.remove_first().unwrap()]), span: array_init.span.clone(), - } + }) } - fn reduce_assign(&mut self, assign: &AssignStatement, assignee: Assignee, value: Expression) -> AssignStatement { + fn reduce_assign( + &mut self, + assign: &AssignStatement, + assignee: Assignee, + value: Expression, + _in_circuit: bool, + ) -> Result { match value { Expression::Value(value) => { let left = Box::new(Expression::Identifier(assignee.identifier.clone())); @@ -251,14 +262,14 @@ impl ReconstructingReducer for Canonicalizer { span: assign.span.clone(), }); - AssignStatement { + Ok(AssignStatement { operation: assign.operation.clone(), assignee, value, span: assign.span.clone(), - } + }) } - _ => assign.clone(), + _ => Ok(assign.clone()), } } @@ -271,29 +282,34 @@ impl ReconstructingReducer for Canonicalizer { output: Option, block: Block, _in_circuit: bool, - ) -> Function { + ) -> Result { let new_output = match output { None => Some(Type::Tuple(vec![])), _ => output, }; - Function { + Ok(Function { identifier, annotations, input, output: new_output, block, span: function.span.clone(), - } + }) } - fn reduce_circuit(&mut self, _circuit: &Circuit, circuit_name: Identifier, members: Vec) -> Circuit { - Circuit { + fn reduce_circuit( + &mut self, + _circuit: &Circuit, + circuit_name: Identifier, + members: Vec, + ) -> Result { + Ok(Circuit { circuit_name: circuit_name.clone(), members: members .iter() .map(|member| self.canonicalize_circuit_member(member, &circuit_name)) .collect(), - } + }) } } diff --git a/ast/src/reducer/reconstructing_director.rs b/ast/src/reducer/reconstructing_director.rs index 102e7e3dfc..3ba7f7de91 100644 --- a/ast/src/reducer/reconstructing_director.rs +++ b/ast/src/reducer/reconstructing_director.rs @@ -18,6 +18,8 @@ //! asg nodes and saving relevant information. use crate::*; +use anyhow::Result; +use indexmap::IndexMap; pub struct ReconstructingDirector { reducer: R, @@ -28,14 +30,20 @@ impl ReconstructingDirector { Self { reducer } } - pub fn reduce_type(&mut self, type_: &Type, in_circuit: bool) -> Type { + pub fn reduce_type(&mut self, type_: &Type, in_circuit: bool) -> Result { let new = match type_ { - // Data type wrappers Type::Array(type_, dimensions) => { - Type::Array(Box::new(self.reduce_type(type_, in_circuit)), dimensions.clone()) + Type::Array(Box::new(self.reduce_type(type_, in_circuit)?), dimensions.clone()) } - Type::Tuple(types) => Type::Tuple(types.iter().map(|type_| self.reduce_type(type_, in_circuit)).collect()), - Type::Circuit(identifier) => Type::Circuit(self.reduce_identifier(identifier)), + Type::Tuple(types) => { + let mut reduced_types = vec![]; + for type_ in types.iter() { + reduced_types.push(self.reduce_type(type_, in_circuit)?); + } + + Type::Tuple(reduced_types) + } + Type::Circuit(identifier) => Type::Circuit(self.reduce_identifier(identifier)?), _ => type_.clone(), }; @@ -43,60 +51,74 @@ impl ReconstructingDirector { } // Expressions - pub fn reduce_expression(&mut self, expression: &Expression) -> Expression { + pub fn reduce_expression(&mut self, expression: &Expression, in_circuit: bool) -> Result { 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::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, in_circuit)?), + Expression::Unary(unary) => Expression::Unary(self.reduce_unary(&unary, in_circuit)?), + Expression::Ternary(ternary) => Expression::Ternary(self.reduce_ternary(&ternary, in_circuit)?), + Expression::Cast(cast) => Expression::Cast(self.reduce_cast(&cast, in_circuit)?), - 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::ArrayInline(array_inline) => { + Expression::ArrayInline(self.reduce_array_inline(&array_inline, in_circuit)?) + } + Expression::ArrayInit(array_init) => { + Expression::ArrayInit(self.reduce_array_init(&array_init, in_circuit)?) + } + Expression::ArrayAccess(array_access) => { + Expression::ArrayAccess(self.reduce_array_access(&array_access, in_circuit)?) + } Expression::ArrayRangeAccess(array_range_access) => { - Expression::ArrayRangeAccess(self.reduce_array_range_access(&array_range_access)) + Expression::ArrayRangeAccess(self.reduce_array_range_access(&array_range_access, in_circuit)?) } - 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::TupleInit(tuple_init) => { + Expression::TupleInit(self.reduce_tuple_init(&tuple_init, in_circuit)?) + } + Expression::TupleAccess(tuple_access) => { + Expression::TupleAccess(self.reduce_tuple_access(&tuple_access, in_circuit)?) + } - Expression::CircuitInit(circuit_init) => Expression::CircuitInit(self.reduce_circuit_init(&circuit_init)), + Expression::CircuitInit(circuit_init) => { + Expression::CircuitInit(self.reduce_circuit_init(&circuit_init, in_circuit)?) + } Expression::CircuitMemberAccess(circuit_member_access) => { - Expression::CircuitMemberAccess(self.reduce_circuit_member_access(&circuit_member_access)) + Expression::CircuitMemberAccess(self.reduce_circuit_member_access(&circuit_member_access, in_circuit)?) } Expression::CircuitStaticFunctionAccess(circuit_static_fn_access) => { - Expression::CircuitStaticFunctionAccess(self.reduce_circuit_static_fn_access(&circuit_static_fn_access)) + Expression::CircuitStaticFunctionAccess( + self.reduce_circuit_static_fn_access(&circuit_static_fn_access, in_circuit)?, + ) } - Expression::Call(call) => Expression::Call(self.reduce_call(&call)), + Expression::Call(call) => Expression::Call(self.reduce_call(&call, in_circuit)?), }; - self.reducer.reduce_expression(expression, new) + self.reducer.reduce_expression(expression, new, in_circuit) } - pub fn reduce_identifier(&mut self, identifier: &Identifier) -> Identifier { + pub fn reduce_identifier(&mut self, identifier: &Identifier) -> Result { self.reducer.reduce_identifier(identifier) } - pub fn reduce_group_tuple(&mut self, group_tuple: &GroupTuple) -> GroupTuple { + pub fn reduce_group_tuple(&mut self, group_tuple: &GroupTuple) -> Result { self.reducer.reduce_group_tuple(group_tuple) } - pub fn reduce_group_value(&mut self, group_value: &GroupValue) -> GroupValue { + pub fn reduce_group_value(&mut self, group_value: &GroupValue) -> Result { let new = match group_value { - GroupValue::Tuple(group_tuple) => GroupValue::Tuple(self.reduce_group_tuple(&group_tuple)), + 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 { + pub fn reduce_value(&mut self, value: &ValueExpression) -> Result { let new = match value { ValueExpression::Group(group_value) => { - ValueExpression::Group(Box::new(self.reduce_group_value(&group_value))) + ValueExpression::Group(Box::new(self.reduce_group_value(&group_value)?)) } _ => value.clone(), }; @@ -104,256 +126,333 @@ impl ReconstructingDirector { 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); + pub fn reduce_binary(&mut self, binary: &BinaryExpression, in_circuit: bool) -> Result { + let left = self.reduce_expression(&binary.left, in_circuit)?; + let right = self.reduce_expression(&binary.right, in_circuit)?; - self.reducer.reduce_binary(binary, left, right, binary.op.clone()) + self.reducer + .reduce_binary(binary, left, right, binary.op.clone(), in_circuit) } - pub fn reduce_unary(&mut self, unary: &UnaryExpression) -> UnaryExpression { - let inner = self.reduce_expression(&unary.inner); + pub fn reduce_unary(&mut self, unary: &UnaryExpression, in_circuit: bool) -> Result { + let inner = self.reduce_expression(&unary.inner, in_circuit)?; - self.reducer.reduce_unary(unary, inner, unary.op.clone()) + self.reducer.reduce_unary(unary, inner, unary.op.clone(), in_circuit) } - 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); + pub fn reduce_ternary(&mut self, ternary: &TernaryExpression, in_circuit: bool) -> Result { + let condition = self.reduce_expression(&ternary.condition, in_circuit)?; + let if_true = self.reduce_expression(&ternary.if_true, in_circuit)?; + let if_false = self.reduce_expression(&ternary.if_false, in_circuit)?; - self.reducer.reduce_ternary(ternary, condition, if_true, if_false) + self.reducer + .reduce_ternary(ternary, condition, if_true, if_false, in_circuit) } - 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 + pub fn reduce_cast(&mut self, cast: &CastExpression, in_circuit: bool) -> Result { + let inner = self.reduce_expression(&cast.inner, in_circuit)?; + let target_type = self.reduce_type(&cast.target_type, in_circuit)?; - self.reducer.reduce_cast(cast, inner, target_type) + self.reducer.reduce_cast(cast, inner, target_type, in_circuit) } - pub fn reduce_array_inline(&mut self, array_inline: &ArrayInlineExpression) -> ArrayInlineExpression { - let elements = array_inline - .elements - .iter() - .map(|element| match element { + pub fn reduce_array_inline( + &mut self, + array_inline: &ArrayInlineExpression, + in_circuit: bool, + ) -> Result { + let mut elements = vec![]; + for element in array_inline.elements.iter() { + let reduced_element = match element { SpreadOrExpression::Expression(expression) => { - SpreadOrExpression::Expression(self.reduce_expression(expression)) + SpreadOrExpression::Expression(self.reduce_expression(expression, in_circuit)?) } SpreadOrExpression::Spread(expression) => { - SpreadOrExpression::Spread(self.reduce_expression(expression)) + SpreadOrExpression::Spread(self.reduce_expression(expression, in_circuit)?) } - }) - .collect(); + }; - self.reducer.reduce_array_inline(array_inline, elements) + elements.push(reduced_element); + } + + self.reducer.reduce_array_inline(array_inline, elements, in_circuit) } - pub fn reduce_array_init(&mut self, array_init: &ArrayInitExpression) -> ArrayInitExpression { - let element = self.reduce_expression(&array_init.element); + pub fn reduce_array_init( + &mut self, + array_init: &ArrayInitExpression, + in_circuit: bool, + ) -> Result { + let element = self.reduce_expression(&array_init.element, in_circuit)?; - self.reducer.reduce_array_init(array_init, element) + self.reducer.reduce_array_init(array_init, element, in_circuit) } - 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); + pub fn reduce_array_access( + &mut self, + array_access: &ArrayAccessExpression, + in_circuit: bool, + ) -> Result { + let array = self.reduce_expression(&array_access.array, in_circuit)?; + let index = self.reduce_expression(&array_access.index, in_circuit)?; - self.reducer.reduce_array_access(array_access, array, index) + self.reducer.reduce_array_access(array_access, array, index, in_circuit) } 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)); + in_circuit: bool, + ) -> Result { + let array = self.reduce_expression(&array_range_access.array, in_circuit)?; + let left = match array_range_access.left.as_ref() { + Some(left) => Some(self.reduce_expression(left, in_circuit)?), + None => None, + }; + let right = match array_range_access.right.as_ref() { + Some(right) => Some(self.reduce_expression(right, in_circuit)?), + None => None, + }; self.reducer - .reduce_array_range_access(array_range_access, array, left, right) + .reduce_array_range_access(array_range_access, array, left, right, in_circuit) } - pub fn reduce_tuple_init(&mut self, tuple_init: &TupleInitExpression) -> TupleInitExpression { - let elements = tuple_init - .elements - .iter() - .map(|expr| self.reduce_expression(expr)) - .collect(); + pub fn reduce_tuple_init( + &mut self, + tuple_init: &TupleInitExpression, + in_circuit: bool, + ) -> Result { + let mut elements = vec![]; + for element in tuple_init.elements.iter() { + elements.push(self.reduce_expression(element, in_circuit)?); + } - self.reducer.reduce_tuple_init(tuple_init, elements) + self.reducer.reduce_tuple_init(tuple_init, elements, in_circuit) } - pub fn reduce_tuple_access(&mut self, tuple_access: &TupleAccessExpression) -> TupleAccessExpression { - let tuple = self.reduce_expression(&tuple_access.tuple); + pub fn reduce_tuple_access( + &mut self, + tuple_access: &TupleAccessExpression, + in_circuit: bool, + ) -> Result { + let tuple = self.reduce_expression(&tuple_access.tuple, in_circuit)?; - self.reducer.reduce_tuple_access(tuple_access, tuple) + self.reducer.reduce_tuple_access(tuple_access, tuple, in_circuit) } - 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)); + pub fn reduce_circuit_implied_variable_definition( + &mut self, + variable: &CircuitImpliedVariableDefinition, + in_circuit: bool, + ) -> Result { + let identifier = self.reduce_identifier(&variable.identifier)?; + let expression = match variable.expression.as_ref() { + Some(expr) => Some(self.reduce_expression(expr, in_circuit)?), + None => None, + }; - CircuitImpliedVariableDefinition { identifier, expression } - }) - .collect(); + self.reducer + .reduce_circuit_implied_variable_definition(variable, identifier, expression, in_circuit) + } - self.reducer.reduce_circuit_init(circuit_init, name, members) + pub fn reduce_circuit_init( + &mut self, + circuit_init: &CircuitInitExpression, + in_circuit: bool, + ) -> Result { + let name = self.reduce_identifier(&circuit_init.name)?; + + let mut members = vec![]; + for member in circuit_init.members.iter() { + members.push(self.reduce_circuit_implied_variable_definition(member, in_circuit)?); + } + + self.reducer + .reduce_circuit_init(circuit_init, name, members, in_circuit) } 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); + in_circuit: bool, + ) -> Result { + let circuit = self.reduce_expression(&circuit_member_access.circuit, in_circuit)?; + let name = self.reduce_identifier(&circuit_member_access.name)?; self.reducer - .reduce_circuit_member_access(circuit_member_access, circuit, name) + .reduce_circuit_member_access(circuit_member_access, circuit, name, in_circuit) } 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); + in_circuit: bool, + ) -> Result { + let circuit = self.reduce_expression(&circuit_static_fn_access.circuit, in_circuit)?; + let name = self.reduce_identifier(&circuit_static_fn_access.name)?; self.reducer - .reduce_circuit_static_fn_access(circuit_static_fn_access, circuit, name) + .reduce_circuit_static_fn_access(circuit_static_fn_access, circuit, name, in_circuit) } - 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(); + pub fn reduce_call(&mut self, call: &CallExpression, in_circuit: bool) -> Result { + let function = self.reduce_expression(&call.function, in_circuit)?; - self.reducer.reduce_call(call, function, arguments) + let mut arguments = vec![]; + for argument in call.arguments.iter() { + arguments.push(self.reduce_expression(argument, in_circuit)?); + } + + self.reducer.reduce_call(call, function, arguments, in_circuit) } // Statements - pub fn reduce_statement(&mut self, statement: &Statement, in_circuit: bool) -> Statement { + pub fn reduce_statement(&mut self, statement: &Statement, in_circuit: bool) -> Result { let new = match statement { - Statement::Return(return_statement) => Statement::Return(self.reduce_return(&return_statement)), - Statement::Definition(definition) => Statement::Definition(self.reduce_definition(&definition, in_circuit)), - Statement::Assign(assign) => Statement::Assign(self.reduce_assign(&assign)), - Statement::Conditional(conditional) => { - Statement::Conditional(self.reduce_conditional(&conditional, in_circuit)) + Statement::Return(return_statement) => { + Statement::Return(self.reduce_return(&return_statement, in_circuit)?) } - Statement::Iteration(iteration) => Statement::Iteration(self.reduce_iteration(&iteration, in_circuit)), - 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, in_circuit)), + Statement::Definition(definition) => { + Statement::Definition(self.reduce_definition(&definition, in_circuit)?) + } + Statement::Assign(assign) => Statement::Assign(self.reduce_assign(&assign, in_circuit)?), + Statement::Conditional(conditional) => { + Statement::Conditional(self.reduce_conditional(&conditional, in_circuit)?) + } + Statement::Iteration(iteration) => Statement::Iteration(self.reduce_iteration(&iteration, in_circuit)?), + Statement::Console(console) => Statement::Console(self.reduce_console(&console, in_circuit)?), + Statement::Expression(expression) => { + Statement::Expression(self.reduce_expression_statement(&expression, in_circuit)?) + } + Statement::Block(block) => Statement::Block(self.reduce_block(&block, in_circuit)?), }; self.reducer.reduce_statement(statement, new, in_circuit) } - pub fn reduce_return(&mut self, return_statement: &ReturnStatement) -> ReturnStatement { - let expression = self.reduce_expression(&return_statement.expression); + pub fn reduce_return(&mut self, return_statement: &ReturnStatement, in_circuit: bool) -> Result { + let expression = self.reduce_expression(&return_statement.expression, in_circuit)?; - self.reducer.reduce_return(return_statement, expression) + self.reducer.reduce_return(return_statement, expression, in_circuit) } - pub fn reduce_variable_name(&mut self, variable_name: &VariableName) -> VariableName { - let identifier = self.reduce_identifier(&variable_name.identifier); + pub fn reduce_variable_name(&mut self, variable_name: &VariableName) -> Result { + let identifier = self.reduce_identifier(&variable_name.identifier)?; self.reducer.reduce_variable_name(variable_name, identifier) } - pub fn reduce_definition(&mut self, definition: &DefinitionStatement, in_circuit: bool) -> 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, in_circuit)); - let value = self.reduce_expression(&definition.value); + pub fn reduce_definition( + &mut self, + definition: &DefinitionStatement, + in_circuit: bool, + ) -> Result { + let mut variable_names = vec![]; + for variable_name in definition.variable_names.iter() { + variable_names.push(self.reduce_variable_name(variable_name)?); + } + + let type_ = match definition.type_.as_ref() { + Some(inner) => Some(self.reduce_type(inner, in_circuit)?), + None => None, + }; + + let value = self.reduce_expression(&definition.value, in_circuit)?; self.reducer .reduce_definition(definition, variable_names, type_, value, in_circuit) } - pub fn reduce_assignee_access(&mut self, access: &AssigneeAccess) -> AssigneeAccess { + pub fn reduce_assignee_access(&mut self, access: &AssigneeAccess, in_circuit: bool) -> Result { 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)), + AssigneeAccess::ArrayRange(left, right) => { + let left = match left.as_ref() { + Some(left) => Some(self.reduce_expression(left, in_circuit)?), + None => None, + }; + let right = match right.as_ref() { + Some(right) => Some(self.reduce_expression(right, in_circuit)?), + None => None, + }; + + AssigneeAccess::ArrayRange(left, right) + } + AssigneeAccess::ArrayIndex(index) => { + AssigneeAccess::ArrayIndex(self.reduce_expression(&index, in_circuit)?) + } + AssigneeAccess::Member(identifier) => AssigneeAccess::Member(self.reduce_identifier(&identifier)?), _ => access.clone(), }; - self.reducer.reduce_assignee_access(access, new) + self.reducer.reduce_assignee_access(access, new, in_circuit) } - 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(); + pub fn reduce_assignee(&mut self, assignee: &Assignee, in_circuit: bool) -> Result { + let identifier = self.reduce_identifier(&assignee.identifier)?; - self.reducer.reduce_assignee(assignee, identifier, accesses) + let mut accesses = vec![]; + for access in assignee.accesses.iter() { + accesses.push(self.reduce_assignee_access(access, in_circuit)?); + } + + self.reducer.reduce_assignee(assignee, identifier, accesses, in_circuit) } - pub fn reduce_assign(&mut self, assign: &AssignStatement) -> AssignStatement { - let assignee = self.reduce_assignee(&assign.assignee); - let value = self.reduce_expression(&assign.value); + pub fn reduce_assign(&mut self, assign: &AssignStatement, in_circuit: bool) -> Result { + let assignee = self.reduce_assignee(&assign.assignee, in_circuit)?; + let value = self.reduce_expression(&assign.value, in_circuit)?; - self.reducer.reduce_assign(assign, assignee, value) + self.reducer.reduce_assign(assign, assignee, value, in_circuit) } - pub fn reduce_conditional(&mut self, conditional: &ConditionalStatement, in_circuit: bool) -> ConditionalStatement { - let condition = self.reduce_expression(&conditional.condition); - let block = self.reduce_block(&conditional.block, in_circuit); - let next = conditional - .next - .as_ref() - .map(|condition| self.reduce_statement(condition, in_circuit)); + pub fn reduce_conditional( + &mut self, + conditional: &ConditionalStatement, + in_circuit: bool, + ) -> Result { + let condition = self.reduce_expression(&conditional.condition, in_circuit)?; + let block = self.reduce_block(&conditional.block, in_circuit)?; + let next = match conditional.next.as_ref() { + Some(condition) => Some(self.reduce_statement(condition, in_circuit)?), + None => None, + }; self.reducer .reduce_conditional(conditional, condition, block, next, in_circuit) } - pub fn reduce_iteration(&mut self, iteration: &IterationStatement, in_circuit: bool) -> 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, in_circuit); + pub fn reduce_iteration(&mut self, iteration: &IterationStatement, in_circuit: bool) -> Result { + let variable = self.reduce_identifier(&iteration.variable)?; + let start = self.reduce_expression(&iteration.start, in_circuit)?; + let stop = self.reduce_expression(&iteration.stop, in_circuit)?; + let block = self.reduce_block(&iteration.block, in_circuit)?; self.reducer .reduce_iteration(iteration, variable, start, stop, block, in_circuit) } - pub fn reduce_console(&mut self, console_function_call: &ConsoleStatement) -> ConsoleStatement { + pub fn reduce_console( + &mut self, + console_function_call: &ConsoleStatement, + in_circuit: bool, + ) -> Result { let function = match &console_function_call.function { - ConsoleFunction::Assert(expression) => ConsoleFunction::Assert(self.reduce_expression(expression)), + ConsoleFunction::Assert(expression) => { + ConsoleFunction::Assert(self.reduce_expression(expression, in_circuit)?) + } ConsoleFunction::Debug(format) | ConsoleFunction::Error(format) | ConsoleFunction::Log(format) => { + let mut parameters = vec![]; + for parameter in format.parameters.iter() { + parameters.push(self.reduce_expression(parameter, in_circuit)?); + } + let formatted = FormattedString { parts: format.parts.clone(), - parameters: format - .parameters - .iter() - .map(|parameter| self.reduce_expression(parameter)) - .collect(), + parameters, span: format.span.clone(), }; + match &console_function_call.function { ConsoleFunction::Debug(_) => ConsoleFunction::Debug(formatted), ConsoleFunction::Error(_) => ConsoleFunction::Error(formatted), @@ -363,51 +462,52 @@ impl ReconstructingDirector { } }; - self.reducer.reduce_console(console_function_call, function) + self.reducer.reduce_console(console_function_call, function, in_circuit) } - 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) + pub fn reduce_expression_statement( + &mut self, + expression: &ExpressionStatement, + in_circuit: bool, + ) -> Result { + let inner_expression = self.reduce_expression(&expression.expression, in_circuit)?; + self.reducer + .reduce_expression_statement(expression, inner_expression, in_circuit) } - pub fn reduce_block(&mut self, block: &Block, in_circuit: bool) -> Block { - let statements = block - .statements - .iter() - .map(|statement| self.reduce_statement(statement, in_circuit)) - .collect(); + pub fn reduce_block(&mut self, block: &Block, in_circuit: bool) -> Result { + let mut statements = vec![]; + for statement in block.statements.iter() { + statements.push(self.reduce_statement(statement, in_circuit)?); + } self.reducer.reduce_block(block, statements, in_circuit) } // Program - pub fn reduce_program(&mut self, program: &Program) -> Program { - let inputs = program - .expected_input - .iter() - .map(|input| self.reduce_function_input(input, false)) - .collect(); - let imports = program - .imports - .iter() - .map(|import| self.reduce_import(import)) - .collect(); - let circuits = program - .circuits - .iter() - .map(|(identifier, circuit)| (self.reduce_identifier(identifier), self.reduce_circuit(circuit))) - .collect(); - let functions = program - .functions - .iter() - .map(|(identifier, function)| { - ( - self.reduce_identifier(identifier), - self.reduce_function(function, false), - ) - }) - .collect(); + pub fn reduce_program(&mut self, program: &Program) -> Result { + let mut inputs = vec![]; + for input in program.expected_input.iter() { + inputs.push(self.reduce_function_input(input, false)?); + } + + let mut imports = vec![]; + for import in program.imports.iter() { + imports.push(self.reduce_import(import)?); + } + + let mut circuits = IndexMap::new(); + for (identifier, circuit) in program.circuits.iter() { + circuits.insert(self.reduce_identifier(identifier)?, self.reduce_circuit(circuit)?); + } + + let mut functions = IndexMap::new(); + for (identifier, function) in program.functions.iter() { + functions.insert( + self.reduce_identifier(identifier)?, + self.reduce_function(function, false)?, + ); + } self.reducer .reduce_program(program, inputs, imports, circuits, functions) @@ -417,18 +517,18 @@ impl ReconstructingDirector { &mut self, variable: &FunctionInputVariable, in_circuit: bool, - ) -> FunctionInputVariable { - let identifier = self.reduce_identifier(&variable.identifier); - let type_ = self.reduce_type(&variable.type_, in_circuit); + ) -> Result { + let identifier = self.reduce_identifier(&variable.identifier)?; + let type_ = self.reduce_type(&variable.type_, in_circuit)?; self.reducer .reduce_function_input_variable(variable, identifier, type_, in_circuit) } - pub fn reduce_function_input(&mut self, input: &FunctionInput, in_circuit: bool) -> FunctionInput { + pub fn reduce_function_input(&mut self, input: &FunctionInput, in_circuit: bool) -> Result { let new = match input { FunctionInput::Variable(function_input_variable) => { - FunctionInput::Variable(self.reduce_function_input_variable(function_input_variable, in_circuit)) + FunctionInput::Variable(self.reduce_function_input_variable(function_input_variable, in_circuit)?) } _ => input.clone(), }; @@ -436,15 +536,15 @@ impl ReconstructingDirector { self.reducer.reduce_function_input(input, new, in_circuit) } - pub fn reduce_package_or_packages(&mut self, package_or_packages: &PackageOrPackages) -> PackageOrPackages { + pub fn reduce_package_or_packages(&mut self, package_or_packages: &PackageOrPackages) -> Result { let new = match package_or_packages { PackageOrPackages::Package(package) => PackageOrPackages::Package(Package { - name: self.reduce_identifier(&package.name), + 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), + name: self.reduce_identifier(&packages.name)?, accesses: packages.accesses.clone(), span: packages.span.clone(), }), @@ -453,61 +553,63 @@ impl ReconstructingDirector { self.reducer.reduce_package_or_packages(package_or_packages, new) } - pub fn reduce_import(&mut self, import: &ImportStatement) -> ImportStatement { - let package_or_packages = self.reduce_package_or_packages(&import.package_or_packages); + pub fn reduce_import(&mut self, import: &ImportStatement) -> Result { + let package_or_packages = self.reduce_package_or_packages(&import.package_or_packages)?; self.reducer.reduce_import(import, package_or_packages) } - pub fn reduce_circuit_member(&mut self, circuit_member: &CircuitMember) -> CircuitMember { + pub fn reduce_circuit_member(&mut self, circuit_member: &CircuitMember) -> Result { let new = match circuit_member { CircuitMember::CircuitVariable(identifier, type_) => { - CircuitMember::CircuitVariable(self.reduce_identifier(&identifier), self.reduce_type(&type_, true)) + CircuitMember::CircuitVariable(self.reduce_identifier(&identifier)?, self.reduce_type(&type_, true)?) } CircuitMember::CircuitFunction(function) => { - CircuitMember::CircuitFunction(self.reduce_function(&function, true)) + CircuitMember::CircuitFunction(self.reduce_function(&function, true)?) } }; 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 members = circuit - .members - .iter() - .map(|member| self.reduce_circuit_member(member)) - .collect(); + pub fn reduce_circuit(&mut self, circuit: &Circuit) -> Result { + let circuit_name = self.reduce_identifier(&circuit.circuit_name)?; + + let mut members = vec![]; + for member in circuit.members.iter() { + members.push(self.reduce_circuit_member(member)?); + } self.reducer.reduce_circuit(circuit, circuit_name, members) } - fn reduce_annotation(&mut self, annotation: &Annotation) -> Annotation { - let name = self.reduce_identifier(&annotation.name); + fn reduce_annotation(&mut self, annotation: &Annotation) -> Result { + let name = self.reduce_identifier(&annotation.name)?; self.reducer.reduce_annotation(annotation, name) } - pub fn reduce_function(&mut self, function: &Function, in_circuit: bool) -> Function { - let identifier = self.reduce_identifier(&function.identifier); - let annotations = function - .annotations - .iter() - .map(|annotation| self.reduce_annotation(annotation)) - .collect(); - let input = function - .input - .iter() - .map(|input| self.reduce_function_input(input, false)) - .collect(); - let output = function - .output - .as_ref() - .map(|output| self.reduce_type(output, in_circuit)); - let block = self.reduce_block(&function.block, false); + pub fn reduce_function(&mut self, function: &Function, in_circuit: bool) -> Result { + let identifier = self.reduce_identifier(&function.identifier)?; + + let mut annotations = vec![]; + for annotation in function.annotations.iter() { + annotations.push(self.reduce_annotation(annotation)?); + } + + let mut inputs = vec![]; + for input in function.input.iter() { + inputs.push(self.reduce_function_input(input, false)?); + } + + let output = match function.output.as_ref() { + Some(type_) => Some(self.reduce_type(type_, in_circuit)?), + None => None, + }; + + let block = self.reduce_block(&function.block, false)?; self.reducer - .reduce_function(function, identifier, annotations, input, output, block, in_circuit) + .reduce_function(function, identifier, annotations, inputs, output, block, in_circuit) } } diff --git a/ast/src/reducer/reconstructing_reducer.rs b/ast/src/reducer/reconstructing_reducer.rs index 2cc4945449..be5b39aeac 100644 --- a/ast/src/reducer/reconstructing_reducer.rs +++ b/ast/src/reducer/reconstructing_reducer.rs @@ -15,41 +15,47 @@ // along with the Leo library. If not, see . use crate::*; +use anyhow::Result; use indexmap::IndexMap; // Needed to fix clippy bug. #[allow(clippy::redundant_closure)] pub trait ReconstructingReducer { - fn reduce_type(&mut self, _type_: &Type, new: Type, _in_circuit: bool) -> Type { - new + fn reduce_type(&mut self, _type_: &Type, new: Type, _in_circuit: bool) -> Result { + Ok(new) } // Expressions - fn reduce_expression(&mut self, _expression: &Expression, new: Expression) -> Expression { - new + fn reduce_expression( + &mut self, + _expression: &Expression, + new: Expression, + _in_circuit: bool, + ) -> Result { + Ok(new) } - fn reduce_identifier(&mut self, identifier: &Identifier) -> Identifier { - Identifier { + fn reduce_identifier(&mut self, identifier: &Identifier) -> Result { + Ok(Identifier { name: identifier.name.clone(), span: identifier.span.clone(), - } + }) } - fn reduce_group_tuple(&mut self, group_tuple: &GroupTuple) -> GroupTuple { - GroupTuple { + fn reduce_group_tuple(&mut self, group_tuple: &GroupTuple) -> Result { + Ok(GroupTuple { x: group_tuple.x.clone(), y: group_tuple.y.clone(), span: group_tuple.span.clone(), - } + }) } - fn reduce_group_value(&mut self, _group_value: &GroupValue, new: GroupValue) -> GroupValue { - new + fn reduce_group_value(&mut self, _group_value: &GroupValue, new: GroupValue) -> Result { + Ok(new) } - fn reduce_value(&mut self, _value: &ValueExpression, new: ValueExpression) -> ValueExpression { - new + fn reduce_value(&mut self, _value: &ValueExpression, new: ValueExpression) -> Result { + Ok(new) } fn reduce_binary( @@ -58,21 +64,28 @@ pub trait ReconstructingReducer { left: Expression, right: Expression, op: BinaryOperation, - ) -> BinaryExpression { - BinaryExpression { + _in_circuit: bool, + ) -> Result { + Ok(BinaryExpression { left: Box::new(left), right: Box::new(right), op, span: binary.span.clone(), - } + }) } - fn reduce_unary(&mut self, unary: &UnaryExpression, inner: Expression, op: UnaryOperation) -> UnaryExpression { - UnaryExpression { + fn reduce_unary( + &mut self, + unary: &UnaryExpression, + inner: Expression, + op: UnaryOperation, + _in_circuit: bool, + ) -> Result { + Ok(UnaryExpression { inner: Box::new(inner), op, span: unary.span.clone(), - } + }) } fn reduce_ternary( @@ -81,40 +94,53 @@ pub trait ReconstructingReducer { condition: Expression, if_true: Expression, if_false: Expression, - ) -> TernaryExpression { - TernaryExpression { + _in_circuit: bool, + ) -> Result { + Ok(TernaryExpression { condition: Box::new(condition), if_true: Box::new(if_true), if_false: Box::new(if_false), span: ternary.span.clone(), - } + }) } - fn reduce_cast(&mut self, cast: &CastExpression, inner: Expression, target_type: Type) -> CastExpression { - CastExpression { + fn reduce_cast( + &mut self, + cast: &CastExpression, + inner: Expression, + target_type: Type, + _in_circuit: bool, + ) -> Result { + Ok(CastExpression { inner: Box::new(inner), target_type, span: cast.span.clone(), - } + }) } fn reduce_array_inline( &mut self, array_inline: &ArrayInlineExpression, elements: Vec, - ) -> ArrayInlineExpression { - ArrayInlineExpression { + _in_circuit: bool, + ) -> Result { + Ok(ArrayInlineExpression { elements, span: array_inline.span.clone(), - } + }) } - fn reduce_array_init(&mut self, array_init: &ArrayInitExpression, element: Expression) -> ArrayInitExpression { - ArrayInitExpression { + fn reduce_array_init( + &mut self, + array_init: &ArrayInitExpression, + element: Expression, + _in_circuit: bool, + ) -> Result { + Ok(ArrayInitExpression { element: Box::new(element), dimensions: array_init.dimensions.clone(), span: array_init.span.clone(), - } + }) } fn reduce_array_access( @@ -122,12 +148,13 @@ pub trait ReconstructingReducer { array_access: &ArrayAccessExpression, array: Expression, index: Expression, - ) -> ArrayAccessExpression { - ArrayAccessExpression { + _in_circuit: bool, + ) -> Result { + Ok(ArrayAccessExpression { array: Box::new(array), index: Box::new(index), span: array_access.span.clone(), - } + }) } fn reduce_array_range_access( @@ -136,36 +163,49 @@ pub trait ReconstructingReducer { array: Expression, left: Option, right: Option, - ) -> ArrayRangeAccessExpression { - ArrayRangeAccessExpression { + _in_circuit: bool, + ) -> Result { + Ok(ArrayRangeAccessExpression { array: Box::new(array), left: left.map(|expr| Box::new(expr)), right: right.map(|expr| Box::new(expr)), span: array_rage_access.span.clone(), - } + }) } fn reduce_tuple_init( &mut self, tuple_init: &TupleInitExpression, elements: Vec, - ) -> TupleInitExpression { - TupleInitExpression { + _in_circuit: bool, + ) -> Result { + Ok(TupleInitExpression { elements, span: tuple_init.span.clone(), - } + }) } fn reduce_tuple_access( &mut self, tuple_access: &TupleAccessExpression, tuple: Expression, - ) -> TupleAccessExpression { - TupleAccessExpression { + _in_circuit: bool, + ) -> Result { + Ok(TupleAccessExpression { tuple: Box::new(tuple), index: tuple_access.index.clone(), span: tuple_access.span.clone(), - } + }) + } + + fn reduce_circuit_implied_variable_definition( + &mut self, + _variable: &CircuitImpliedVariableDefinition, + identifier: Identifier, + expression: Option, + _in_circuit: bool, + ) -> Result { + Ok(CircuitImpliedVariableDefinition { identifier, expression }) } fn reduce_circuit_init( @@ -173,12 +213,13 @@ pub trait ReconstructingReducer { circuit_init: &CircuitInitExpression, name: Identifier, members: Vec, - ) -> CircuitInitExpression { - CircuitInitExpression { + _in_circuit: bool, + ) -> Result { + Ok(CircuitInitExpression { name, members, span: circuit_init.span.clone(), - } + }) } fn reduce_circuit_member_access( @@ -186,12 +227,13 @@ pub trait ReconstructingReducer { circuit_member_access: &CircuitMemberAccessExpression, circuit: Expression, name: Identifier, - ) -> CircuitMemberAccessExpression { - CircuitMemberAccessExpression { + _in_circuit: bool, + ) -> Result { + Ok(CircuitMemberAccessExpression { circuit: Box::new(circuit), name, span: circuit_member_access.span.clone(), - } + }) } fn reduce_circuit_static_fn_access( @@ -199,12 +241,13 @@ pub trait ReconstructingReducer { circuit_static_fn_access: &CircuitStaticFunctionAccessExpression, circuit: Expression, name: Identifier, - ) -> CircuitStaticFunctionAccessExpression { - CircuitStaticFunctionAccessExpression { + _in_circuit: bool, + ) -> Result { + Ok(CircuitStaticFunctionAccessExpression { circuit: Box::new(circuit), name, span: circuit_static_fn_access.span.clone(), - } + }) } fn reduce_call( @@ -212,32 +255,38 @@ pub trait ReconstructingReducer { call: &CallExpression, function: Expression, arguments: Vec, - ) -> CallExpression { - CallExpression { + _in_circuit: bool, + ) -> Result { + Ok(CallExpression { function: Box::new(function), arguments, span: call.span.clone(), - } + }) } // Statements - fn reduce_statement(&mut self, _statement: &Statement, new: Statement, _in_circuit: bool) -> Statement { - new + fn reduce_statement(&mut self, _statement: &Statement, new: Statement, _in_circuit: bool) -> Result { + Ok(new) } - fn reduce_return(&mut self, return_statement: &ReturnStatement, expression: Expression) -> ReturnStatement { - ReturnStatement { + fn reduce_return( + &mut self, + return_statement: &ReturnStatement, + expression: Expression, + _in_circuit: bool, + ) -> Result { + Ok(ReturnStatement { expression, span: return_statement.span.clone(), - } + }) } - fn reduce_variable_name(&mut self, variable_name: &VariableName, identifier: Identifier) -> VariableName { - VariableName { + fn reduce_variable_name(&mut self, variable_name: &VariableName, identifier: Identifier) -> Result { + Ok(VariableName { mutable: variable_name.mutable, identifier, span: variable_name.span.clone(), - } + }) } fn reduce_definition( @@ -247,18 +296,23 @@ pub trait ReconstructingReducer { type_: Option, value: Expression, _in_circuit: bool, - ) -> DefinitionStatement { - DefinitionStatement { + ) -> Result { + Ok(DefinitionStatement { declaration_type: definition.declaration_type.clone(), variable_names, type_, value, span: definition.span.clone(), - } + }) } - fn reduce_assignee_access(&mut self, _access: &AssigneeAccess, new: AssigneeAccess) -> AssigneeAccess { - new + fn reduce_assignee_access( + &mut self, + _access: &AssigneeAccess, + new: AssigneeAccess, + _in_circuit: bool, + ) -> Result { + Ok(new) } fn reduce_assignee( @@ -266,21 +320,28 @@ pub trait ReconstructingReducer { assignee: &Assignee, identifier: Identifier, accesses: Vec, - ) -> Assignee { - Assignee { + _in_circuit: bool, + ) -> Result { + Ok(Assignee { identifier, accesses, span: assignee.span.clone(), - } + }) } - fn reduce_assign(&mut self, assign: &AssignStatement, assignee: Assignee, value: Expression) -> AssignStatement { - AssignStatement { + fn reduce_assign( + &mut self, + assign: &AssignStatement, + assignee: Assignee, + value: Expression, + _in_circuit: bool, + ) -> Result { + Ok(AssignStatement { operation: assign.operation.clone(), assignee, value, span: assign.span.clone(), - } + }) } fn reduce_conditional( @@ -290,13 +351,13 @@ pub trait ReconstructingReducer { block: Block, statement: Option, _in_circuit: bool, - ) -> ConditionalStatement { - ConditionalStatement { + ) -> Result { + Ok(ConditionalStatement { condition, block, next: statement.map(|statement| Box::new(statement)), span: conditional.span.clone(), - } + }) } fn reduce_iteration( @@ -307,39 +368,45 @@ pub trait ReconstructingReducer { stop: Expression, block: Block, _in_circuit: bool, - ) -> IterationStatement { - IterationStatement { + ) -> Result { + Ok(IterationStatement { variable, start, stop, block, span: iteration.span.clone(), - } + }) } - fn reduce_console(&mut self, console: &ConsoleStatement, function: ConsoleFunction) -> ConsoleStatement { - ConsoleStatement { + fn reduce_console( + &mut self, + console: &ConsoleStatement, + function: ConsoleFunction, + _in_circuit: bool, + ) -> Result { + Ok(ConsoleStatement { function, span: console.span.clone(), - } + }) } fn reduce_expression_statement( &mut self, expression_statement: &ExpressionStatement, expression: Expression, - ) -> ExpressionStatement { - ExpressionStatement { + _in_circuit: bool, + ) -> Result { + Ok(ExpressionStatement { expression, span: expression_statement.span.clone(), - } + }) } - fn reduce_block(&mut self, block: &Block, statements: Vec, _in_circuit: bool) -> Block { - Block { + fn reduce_block(&mut self, block: &Block, statements: Vec, _in_circuit: bool) -> Result { + Ok(Block { statements, span: block.span.clone(), - } + }) } // Program @@ -350,14 +417,14 @@ pub trait ReconstructingReducer { imports: Vec, circuits: IndexMap, functions: IndexMap, - ) -> Program { - Program { + ) -> Result { + Ok(Program { name: program.name.clone(), expected_input, imports, circuits, functions, - } + }) } fn reduce_function_input_variable( @@ -366,14 +433,14 @@ pub trait ReconstructingReducer { identifier: Identifier, type_: Type, _in_circuit: bool, - ) -> FunctionInputVariable { - FunctionInputVariable { + ) -> Result { + Ok(FunctionInputVariable { identifier, const_: variable.const_, mutable: variable.mutable, type_, span: variable.span.clone(), - } + }) } fn reduce_function_input( @@ -381,39 +448,48 @@ pub trait ReconstructingReducer { _input: &FunctionInput, new: FunctionInput, _in_circuit: bool, - ) -> FunctionInput { - new + ) -> Result { + Ok(new) } fn reduce_package_or_packages( &mut self, _package_or_packages: &PackageOrPackages, new: PackageOrPackages, - ) -> PackageOrPackages { - new + ) -> Result { + Ok(new) } - fn reduce_import(&mut self, import: &ImportStatement, package_or_packages: PackageOrPackages) -> ImportStatement { - ImportStatement { + fn reduce_import( + &mut self, + import: &ImportStatement, + package_or_packages: PackageOrPackages, + ) -> Result { + Ok(ImportStatement { package_or_packages, span: import.span.clone(), - } + }) } - fn reduce_circuit_member(&mut self, _circuit_member: &CircuitMember, new: CircuitMember) -> CircuitMember { - new + fn reduce_circuit_member(&mut self, _circuit_member: &CircuitMember, new: CircuitMember) -> Result { + Ok(new) } - fn reduce_circuit(&mut self, _circuit: &Circuit, circuit_name: Identifier, members: Vec) -> Circuit { - Circuit { circuit_name, members } + fn reduce_circuit( + &mut self, + _circuit: &Circuit, + circuit_name: Identifier, + members: Vec, + ) -> Result { + Ok(Circuit { circuit_name, members }) } - fn reduce_annotation(&mut self, annotation: &Annotation, name: Identifier) -> Annotation { - Annotation { + fn reduce_annotation(&mut self, annotation: &Annotation, name: Identifier) -> Result { + Ok(Annotation { span: annotation.span.clone(), name, arguments: annotation.arguments.clone(), - } + }) } #[allow(clippy::too_many_arguments)] @@ -426,14 +502,14 @@ pub trait ReconstructingReducer { output: Option, block: Block, _in_circuit: bool, - ) -> Function { - Function { + ) -> Result { + Ok(Function { identifier, annotations, input, output, block, span: function.span.clone(), - } + }) } }