diff --git a/compiler/src/expression/conditional/mod.rs b/compiler/src/expression/conditional/mod.rs new file mode 100644 index 0000000000..66600b3a6d --- /dev/null +++ b/compiler/src/expression/conditional/mod.rs @@ -0,0 +1,2 @@ +pub mod ternary; +pub use self::ternary::*; diff --git a/compiler/src/expression/conditional/ternary.rs b/compiler/src/expression/conditional/ternary.rs new file mode 100644 index 0000000000..6efd6a7c10 --- /dev/null +++ b/compiler/src/expression/conditional/ternary.rs @@ -0,0 +1,63 @@ +//! Methods to enforce constraints on ternary expressions in a compiled Leo program. + +use crate::{errors::ExpressionError, program::ConstrainedProgram, value::ConstrainedValue, GroupType}; +use leo_types::{Expression, Span, Type}; + +use snarkos_models::{ + curves::{Field, PrimeField}, + gadgets::{r1cs::ConstraintSystem, utilities::select::CondSelectGadget}, +}; + +impl> ConstrainedProgram { + /// Enforce ternary conditional expression + pub fn enforce_conditional_expression>( + &mut self, + cs: &mut CS, + file_scope: String, + function_scope: String, + expected_types: &Vec, + conditional: Expression, + first: Expression, + second: Expression, + span: Span, + ) -> Result, ExpressionError> { + let conditional_value = match self.enforce_expression( + cs, + file_scope.clone(), + function_scope.clone(), + &vec![Type::Boolean], + conditional, + )? { + ConstrainedValue::Boolean(resolved) => resolved, + value => return Err(ExpressionError::conditional_boolean(value.to_string(), span)), + }; + + let first_value = self.enforce_expression_value( + cs, + file_scope.clone(), + function_scope.clone(), + expected_types, + first, + span.clone(), + )?; + + let second_value = self.enforce_expression_value( + cs, + file_scope.clone(), + function_scope.clone(), + expected_types, + second, + span.clone(), + )?; + + let unique_namespace = cs.ns(|| { + format!( + "select {} or {} {}:{}", + first_value, second_value, span.line, span.start + ) + }); + + ConstrainedValue::conditionally_select(unique_namespace, &conditional_value, &first_value, &second_value) + .map_err(|e| ExpressionError::cannot_enforce(format!("conditional select"), e, span)) + } +} diff --git a/compiler/src/expression/expression.rs b/compiler/src/expression/expression.rs index c1e0f7e82d..7af2751c22 100644 --- a/compiler/src/expression/expression.rs +++ b/compiler/src/expression/expression.rs @@ -26,7 +26,7 @@ use leo_types::{ use snarkos_models::{ curves::{Field, PrimeField}, - gadgets::{r1cs::ConstraintSystem, utilities::select::CondSelectGadget}, + gadgets::r1cs::ConstraintSystem, }; static SELF_KEYWORD: &'static str = "self"; @@ -67,58 +67,6 @@ impl> ConstrainedProgram { Ok(result_value) } - /// Enforce ternary conditional expression - fn enforce_conditional_expression>( - &mut self, - cs: &mut CS, - file_scope: String, - function_scope: String, - expected_types: &Vec, - conditional: Expression, - first: Expression, - second: Expression, - span: Span, - ) -> Result, ExpressionError> { - let conditional_value = match self.enforce_expression( - cs, - file_scope.clone(), - function_scope.clone(), - &vec![Type::Boolean], - conditional, - )? { - ConstrainedValue::Boolean(resolved) => resolved, - value => return Err(ExpressionError::conditional_boolean(value.to_string(), span)), - }; - - let first_value = self.enforce_expression_value( - cs, - file_scope.clone(), - function_scope.clone(), - expected_types, - first, - span.clone(), - )?; - - let second_value = self.enforce_expression_value( - cs, - file_scope.clone(), - function_scope.clone(), - expected_types, - second, - span.clone(), - )?; - - let unique_namespace = cs.ns(|| { - format!( - "select {} or {} {}:{}", - first_value, second_value, span.line, span.start - ) - }); - - ConstrainedValue::conditionally_select(unique_namespace, &conditional_value, &first_value, &second_value) - .map_err(|e| ExpressionError::cannot_enforce(format!("conditional select"), e, span)) - } - /// Enforce array expressions fn enforce_array_expression>( &mut self, diff --git a/compiler/src/expression/mod.rs b/compiler/src/expression/mod.rs index a936dd0ae7..b365a92c09 100644 --- a/compiler/src/expression/mod.rs +++ b/compiler/src/expression/mod.rs @@ -3,6 +3,9 @@ pub mod arithmetic; pub use self::arithmetic::*; +pub mod conditional; +pub use self::conditional::*; + pub mod expression; pub use self::expression::*;