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
use crate::{errors::FunctionError, program::ConstrainedProgram, GroupType, OutputBytes};
use leo_asg::{Expression, FunctionBody, FunctionQualifier};
use leo_ast::Input;
use std::sync::Arc;
use snarkvm_models::{
curves::{Field, PrimeField},
gadgets::r1cs::ConstraintSystem,
};
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
pub fn enforce_main_function<CS: ConstraintSystem<F>>(
&mut self,
cs: &mut CS,
function: &Arc<FunctionBody>,
input: &Input,
) -> Result<OutputBytes, FunctionError> {
let registers = input.get_registers();
if function.function.has_input {
let asg_input = function
.scope
.borrow()
.resolve_input()
.expect("no input variable in scope when function is qualified");
let value = self.allocate_input_keyword(
cs,
function.function.name.borrow().span.clone(),
&asg_input.container_circuit,
input,
)?;
self.store(asg_input.container.borrow().id, value);
}
match function.function.qualifier {
FunctionQualifier::SelfRef | FunctionQualifier::MutSelfRef => {
unimplemented!("cannot access self variable in main function")
}
FunctionQualifier::Static => (),
}
let mut arguments = vec![];
for input_variable in function.arguments.iter() {
{
let input_variable = input_variable.borrow();
let name = input_variable.name.name.clone();
let input_option = input.get(&name).ok_or_else(|| {
FunctionError::input_not_found(name.clone(), function.span.clone().unwrap_or_default())
})?;
let input_value = self.allocate_main_function_input(
cs,
&input_variable.type_,
&name,
input_option,
&function.span.clone().unwrap_or_default(),
)?;
self.store(input_variable.id, input_value);
}
arguments.push(Arc::new(Expression::VariableRef(leo_asg::VariableRef {
parent: std::cell::RefCell::new(None),
span: Some(input_variable.borrow().name.span.clone()),
variable: input_variable.clone(),
})));
}
let span = function.span.clone().unwrap_or_default();
let result_value = self.enforce_function(cs, function, None, &arguments)?;
let output_bytes = OutputBytes::new_from_constrained_value(&self.asg, registers, result_value, span)?;
Ok(output_bytes)
}
}