mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-14 02:44:34 +03:00
add definition statement module
This commit is contained in:
parent
51ee4894c7
commit
6d4a34d0ec
28
compiler/src/definitions/definition.rs
Normal file
28
compiler/src/definitions/definition.rs
Normal file
@ -0,0 +1,28 @@
|
||||
//! Stores all defined names in a compiled Leo program.
|
||||
|
||||
use crate::{
|
||||
program::{new_scope, ConstrainedProgram},
|
||||
value::ConstrainedValue,
|
||||
GroupType,
|
||||
};
|
||||
use leo_types::Variable;
|
||||
|
||||
use snarkos_models::curves::{Field, PrimeField};
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
pub fn store_definition(
|
||||
&mut self,
|
||||
function_scope: String,
|
||||
variable: Variable,
|
||||
mut value: ConstrainedValue<F, G>,
|
||||
) -> () {
|
||||
// Store with given mutability
|
||||
if variable.mutable {
|
||||
value = ConstrainedValue::Mutable(Box::new(value));
|
||||
}
|
||||
|
||||
let variable_program_identifier = new_scope(function_scope, variable.identifier.name);
|
||||
|
||||
self.store(variable_program_identifier, value);
|
||||
}
|
||||
}
|
@ -12,11 +12,7 @@ use leo_types::Program;
|
||||
use snarkos_models::curves::{Field, PrimeField};
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
pub(crate) fn store_definitions(
|
||||
&mut self,
|
||||
program: Program,
|
||||
imported_programs: &ImportParser,
|
||||
) -> Result<(), ImportError> {
|
||||
pub fn store_definitions(&mut self, program: Program, imported_programs: &ImportParser) -> Result<(), ImportError> {
|
||||
let program_name = program.name.clone();
|
||||
|
||||
// evaluate all import statements and store imported definitions
|
||||
|
@ -1,2 +1,5 @@
|
||||
pub mod definition;
|
||||
pub use self::definition::*;
|
||||
|
||||
pub mod definitions;
|
||||
pub use self::definitions::*;
|
||||
|
47
compiler/src/statement/definition/definition.rs
Normal file
47
compiler/src/statement/definition/definition.rs
Normal file
@ -0,0 +1,47 @@
|
||||
//! Enforces a definition statement in a compiled Leo program.
|
||||
|
||||
use crate::{errors::StatementError, program::ConstrainedProgram, GroupType};
|
||||
use leo_types::{Declare, Expression, Span, Variable};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::r1cs::ConstraintSystem,
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
pub fn enforce_definition_statement<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
declare: Declare,
|
||||
variable: Variable,
|
||||
expression: Expression,
|
||||
span: Span,
|
||||
) -> Result<(), StatementError> {
|
||||
let mut expected_types = vec![];
|
||||
if let Some(ref _type) = variable._type {
|
||||
expected_types.push(_type.clone());
|
||||
}
|
||||
let mut value = self.enforce_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
&expected_types,
|
||||
expression,
|
||||
)?;
|
||||
|
||||
match declare {
|
||||
Declare::Let => value.allocate_value(cs, span)?,
|
||||
Declare::Const => {
|
||||
if variable.mutable {
|
||||
return Err(StatementError::immutable_assign(variable.to_string(), span));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.store_definition(function_scope, variable, value);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
7
compiler/src/statement/definition/mod.rs
Normal file
7
compiler/src/statement/definition/mod.rs
Normal file
@ -0,0 +1,7 @@
|
||||
//! Methods to enforce constraints on definition statements in a compiled Leo program.
|
||||
|
||||
pub mod definition;
|
||||
pub use self::definition::*;
|
||||
|
||||
pub mod multiple;
|
||||
pub use self::multiple::*;
|
54
compiler/src/statement/definition/multiple.rs
Normal file
54
compiler/src/statement/definition/multiple.rs
Normal file
@ -0,0 +1,54 @@
|
||||
//! Enforces a multiple definition statement in a compiled Leo program.
|
||||
|
||||
use crate::{errors::StatementError, program::ConstrainedProgram, value::ConstrainedValue, GroupType};
|
||||
use leo_types::{Expression, Span, Variable};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::r1cs::ConstraintSystem,
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
pub fn enforce_multiple_definition_statement<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
variables: Vec<Variable>,
|
||||
function: Expression,
|
||||
span: Span,
|
||||
) -> Result<(), StatementError> {
|
||||
let mut expected_types = vec![];
|
||||
for variable in variables.iter() {
|
||||
if let Some(ref _type) = variable._type {
|
||||
expected_types.push(_type.clone());
|
||||
}
|
||||
}
|
||||
|
||||
// Expect return values from function
|
||||
let return_values = match self.enforce_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
&expected_types,
|
||||
function,
|
||||
)? {
|
||||
ConstrainedValue::Return(values) => values,
|
||||
value => unimplemented!("multiple assignment only implemented for functions, got {}", value),
|
||||
};
|
||||
|
||||
if variables.len() != return_values.len() {
|
||||
return Err(StatementError::invalid_number_of_definitions(
|
||||
variables.len(),
|
||||
return_values.len(),
|
||||
span,
|
||||
));
|
||||
}
|
||||
|
||||
for (variable, value) in variables.into_iter().zip(return_values.into_iter()) {
|
||||
self.store_definition(function_scope.clone(), variable, value);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
@ -1,3 +1,6 @@
|
||||
pub mod definition;
|
||||
pub use self::definition::*;
|
||||
|
||||
pub mod return_;
|
||||
pub use self::return_::*;
|
||||
|
||||
|
@ -12,14 +12,12 @@ use leo_types::{
|
||||
Assignee,
|
||||
ConditionalNestedOrEndStatement,
|
||||
ConditionalStatement,
|
||||
Declare,
|
||||
Expression,
|
||||
Identifier,
|
||||
RangeOrExpression,
|
||||
Span,
|
||||
Statement,
|
||||
Type,
|
||||
Variable,
|
||||
};
|
||||
|
||||
use snarkos_models::{
|
||||
@ -237,100 +235,6 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
}
|
||||
}
|
||||
|
||||
fn store_definition(
|
||||
&mut self,
|
||||
function_scope: String,
|
||||
variable: Variable,
|
||||
mut value: ConstrainedValue<F, G>,
|
||||
) -> Result<(), StatementError> {
|
||||
// Store with given mutability
|
||||
if variable.mutable {
|
||||
value = ConstrainedValue::Mutable(Box::new(value));
|
||||
}
|
||||
|
||||
let variable_program_identifier = new_scope(function_scope, variable.identifier.name);
|
||||
|
||||
self.store(variable_program_identifier, value);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn enforce_definition_statement<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
declare: Declare,
|
||||
variable: Variable,
|
||||
expression: Expression,
|
||||
span: Span,
|
||||
) -> Result<(), StatementError> {
|
||||
let mut expected_types = vec![];
|
||||
if let Some(ref _type) = variable._type {
|
||||
expected_types.push(_type.clone());
|
||||
}
|
||||
let mut value = self.enforce_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
&expected_types,
|
||||
expression,
|
||||
)?;
|
||||
|
||||
match declare {
|
||||
Declare::Let => value.allocate_value(cs, span)?,
|
||||
Declare::Const => {
|
||||
if variable.mutable {
|
||||
return Err(StatementError::immutable_assign(variable.to_string(), span));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.store_definition(function_scope, variable, value)
|
||||
}
|
||||
|
||||
fn enforce_multiple_definition_statement<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
variables: Vec<Variable>,
|
||||
function: Expression,
|
||||
span: Span,
|
||||
) -> Result<(), StatementError> {
|
||||
let mut expected_types = vec![];
|
||||
for variable in variables.iter() {
|
||||
if let Some(ref _type) = variable._type {
|
||||
expected_types.push(_type.clone());
|
||||
}
|
||||
}
|
||||
|
||||
// Expect return values from function
|
||||
let return_values = match self.enforce_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
&expected_types,
|
||||
function,
|
||||
)? {
|
||||
ConstrainedValue::Return(values) => values,
|
||||
value => unimplemented!("multiple assignment only implemented for functions, got {}", value),
|
||||
};
|
||||
|
||||
if variables.len() != return_values.len() {
|
||||
return Err(StatementError::invalid_number_of_definitions(
|
||||
variables.len(),
|
||||
return_values.len(),
|
||||
span,
|
||||
));
|
||||
}
|
||||
|
||||
for (variable, value) in variables.into_iter().zip(return_values.into_iter()) {
|
||||
self.store_definition(function_scope.clone(), variable, value)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn evaluate_branch<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
|
Loading…
Reference in New Issue
Block a user