mirror of
https://github.com/AleoHQ/leo.git
synced 2025-01-04 16:15:11 +03:00
add identifier expression module
This commit is contained in:
parent
ba239921b9
commit
c1a560f0ec
@ -4,7 +4,7 @@ use crate::{
|
|||||||
arithmetic::*,
|
arithmetic::*,
|
||||||
errors::ExpressionError,
|
errors::ExpressionError,
|
||||||
logical::*,
|
logical::*,
|
||||||
program::{new_scope, ConstrainedProgram},
|
program::ConstrainedProgram,
|
||||||
relational::*,
|
relational::*,
|
||||||
value::{boolean::input::new_bool_constant, ConstrainedValue},
|
value::{boolean::input::new_bool_constant, ConstrainedValue},
|
||||||
Address,
|
Address,
|
||||||
@ -12,7 +12,7 @@ use crate::{
|
|||||||
GroupType,
|
GroupType,
|
||||||
Integer,
|
Integer,
|
||||||
};
|
};
|
||||||
use leo_types::{Expression, Identifier, Span, Type};
|
use leo_types::{Expression, Span, Type};
|
||||||
|
|
||||||
use snarkos_models::{
|
use snarkos_models::{
|
||||||
curves::{Field, PrimeField},
|
curves::{Field, PrimeField},
|
||||||
@ -20,41 +20,6 @@ use snarkos_models::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
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(
|
pub(crate) fn enforce_number_implicit(
|
||||||
expected_types: &Vec<Type>,
|
expected_types: &Vec<Type>,
|
||||||
value: String,
|
value: String,
|
||||||
|
49
compiler/src/expression/identifier/identifier.rs
Normal file
49
compiler/src/expression/identifier/identifier.rs
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
2
compiler/src/expression/identifier/mod.rs
Normal file
2
compiler/src/expression/identifier/mod.rs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
pub mod identifier;
|
||||||
|
pub use self::identifier::*;
|
@ -18,6 +18,9 @@ pub use self::expression::*;
|
|||||||
pub mod function;
|
pub mod function;
|
||||||
pub use self::function::*;
|
pub use self::function::*;
|
||||||
|
|
||||||
|
pub mod identifier;
|
||||||
|
pub use self::identifier::*;
|
||||||
|
|
||||||
pub mod logical;
|
pub mod logical;
|
||||||
pub use self::logical::*;
|
pub use self::logical::*;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user