mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-24 07:48:04 +03:00
add ternary expression module
This commit is contained in:
parent
ada42fdcf4
commit
c989061ab1
2
compiler/src/expression/conditional/mod.rs
Normal file
2
compiler/src/expression/conditional/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
pub mod ternary;
|
||||
pub use self::ternary::*;
|
63
compiler/src/expression/conditional/ternary.rs
Normal file
63
compiler/src/expression/conditional/ternary.rs
Normal file
@ -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<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
/// Enforce ternary conditional expression
|
||||
pub fn enforce_conditional_expression<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
expected_types: &Vec<Type>,
|
||||
conditional: Expression,
|
||||
first: Expression,
|
||||
second: Expression,
|
||||
span: Span,
|
||||
) -> Result<ConstrainedValue<F, G>, 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))
|
||||
}
|
||||
}
|
@ -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<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
Ok(result_value)
|
||||
}
|
||||
|
||||
/// Enforce ternary conditional expression
|
||||
fn enforce_conditional_expression<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
expected_types: &Vec<Type>,
|
||||
conditional: Expression,
|
||||
first: Expression,
|
||||
second: Expression,
|
||||
span: Span,
|
||||
) -> Result<ConstrainedValue<F, G>, 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<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
|
@ -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::*;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user