add identifier expression module

This commit is contained in:
collin 2020-07-08 00:04:05 -07:00
parent ba239921b9
commit c1a560f0ec
4 changed files with 56 additions and 37 deletions

View File

@ -4,7 +4,7 @@ use crate::{
arithmetic::*,
errors::ExpressionError,
logical::*,
program::{new_scope, ConstrainedProgram},
program::ConstrainedProgram,
relational::*,
value::{boolean::input::new_bool_constant, ConstrainedValue},
Address,
@ -12,7 +12,7 @@ use crate::{
GroupType,
Integer,
};
use leo_types::{Expression, Identifier, Span, Type};
use leo_types::{Expression, Span, Type};
use snarkos_models::{
curves::{Field, PrimeField},
@ -20,41 +20,6 @@ use snarkos_models::{
};
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
/// Enforce a variable expression by getting the resolved value
pub(crate) fn evaluate_identifier(
&mut self,
file_scope: String,
function_scope: String,
expected_types: &Vec<Type>,
unresolved_identifier: Identifier,
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
// Evaluate the identifier name in the current function scope
let variable_name = new_scope(function_scope.clone(), unresolved_identifier.to_string());
let identifier_name = new_scope(file_scope, unresolved_identifier.to_string());
let mut result_value = if let Some(value) = self.get(&variable_name) {
// Reassigning variable to another variable
value.clone()
} else if let Some(value) = self.get(&identifier_name) {
// Check global scope (function and circuit names)
value.clone()
} else if let Some(value) = self.get(&unresolved_identifier.name) {
// Check imported file scope
value.clone()
} else if expected_types.contains(&Type::Address) {
// If we expect an address type, try to return an address
let address = Address::new(unresolved_identifier.name, unresolved_identifier.span)?;
return Ok(ConstrainedValue::Address(address));
} else {
return Err(ExpressionError::undefined_identifier(unresolved_identifier));
};
result_value.resolve_type(expected_types, unresolved_identifier.span.clone())?;
Ok(result_value)
}
pub(crate) fn enforce_number_implicit(
expected_types: &Vec<Type>,
value: String,

View File

@ -0,0 +1,49 @@
//! Methods to enforce constraints on expressions in a compiled Leo program.
use crate::{
errors::ExpressionError,
program::{new_scope, ConstrainedProgram},
value::ConstrainedValue,
Address,
GroupType,
};
use leo_types::{Identifier, Type};
use snarkos_models::curves::{Field, PrimeField};
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
/// Enforce a variable expression by getting the resolved value
pub fn evaluate_identifier(
&mut self,
file_scope: String,
function_scope: String,
expected_types: &Vec<Type>,
unresolved_identifier: Identifier,
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
// Evaluate the identifier name in the current function scope
let variable_name = new_scope(function_scope.clone(), unresolved_identifier.to_string());
let identifier_name = new_scope(file_scope, unresolved_identifier.to_string());
let mut result_value = if let Some(value) = self.get(&variable_name) {
// Reassigning variable to another variable
value.clone()
} else if let Some(value) = self.get(&identifier_name) {
// Check global scope (function and circuit names)
value.clone()
} else if let Some(value) = self.get(&unresolved_identifier.name) {
// Check imported file scope
value.clone()
} else if expected_types.contains(&Type::Address) {
// If we expect an address type, try to return an address
let address = Address::new(unresolved_identifier.name, unresolved_identifier.span)?;
return Ok(ConstrainedValue::Address(address));
} else {
return Err(ExpressionError::undefined_identifier(unresolved_identifier));
};
result_value.resolve_type(expected_types, unresolved_identifier.span.clone())?;
Ok(result_value)
}
}

View File

@ -0,0 +1,2 @@
pub mod identifier;
pub use self::identifier::*;

View File

@ -18,6 +18,9 @@ pub use self::expression::*;
pub mod function;
pub use self::function::*;
pub mod identifier;
pub use self::identifier::*;
pub mod logical;
pub use self::logical::*;