1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
use crate::{errors::StatementError, program::ConstrainedProgram, value::ConstrainedValue, GroupType};
use leo_typed::{Statement, Type};
use snarkos_models::{
curves::{Field, PrimeField},
gadgets::{r1cs::ConstraintSystem, utilities::boolean::Boolean},
};
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
pub fn enforce_statement<CS: ConstraintSystem<F>>(
&mut self,
cs: &mut CS,
file_scope: String,
function_scope: String,
indicator: Option<Boolean>,
statement: Statement,
return_type: Option<Type>,
) -> Result<Vec<(Option<Boolean>, ConstrainedValue<F, G>)>, StatementError> {
let mut results = vec![];
match statement {
Statement::Return(expression, span) => {
let return_value = (
indicator,
self.enforce_return_statement(cs, file_scope, function_scope, expression, return_type, span)?,
);
results.push(return_value);
}
Statement::Definition(declare, variables, expressions, span) => {
self.enforce_definition_statement(
cs,
file_scope,
function_scope,
declare,
variables,
expressions,
span,
)?;
}
Statement::Assign(variable, expression, span) => {
self.enforce_assign_statement(cs, file_scope, function_scope, indicator, variable, expression, span)?;
}
Statement::Conditional(statement, span) => {
let mut result = self.enforce_conditional_statement(
cs,
file_scope,
function_scope,
indicator,
statement,
return_type,
span,
)?;
results.append(&mut result);
}
Statement::Iteration(index, start, stop, statements, span) => {
let mut result = self.enforce_iteration_statement(
cs,
file_scope,
function_scope,
indicator,
index,
start,
stop,
statements,
return_type,
span,
)?;
results.append(&mut result);
}
Statement::Console(console) => {
self.evaluate_console_function_call(cs, file_scope, function_scope, indicator, console)?;
}
Statement::Expression(expression, span) => {
let expression_string = expression.to_string();
let value = self.enforce_expression(cs, file_scope, function_scope, None, expression)?;
match &value {
ConstrainedValue::Tuple(values) => {
if !values.is_empty() {
return Err(StatementError::unassigned(expression_string, span));
}
}
_ => return Err(StatementError::unassigned(expression_string, span)),
}
let result = (indicator, value);
results.push(result);
}
};
Ok(results)
}
}