mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-26 11:45:00 +03:00
convert functions to span with error
This commit is contained in:
parent
f3e81184c1
commit
2743b23e1e
@ -8,7 +8,7 @@ use crate::{
|
|||||||
group_from_input,
|
group_from_input,
|
||||||
GroupType,
|
GroupType,
|
||||||
};
|
};
|
||||||
use leo_types::{Expression, Function, InputValue, Integer, Program, Type};
|
use leo_types::{Expression, Function, InputValue, Integer, Program, Span, Type};
|
||||||
|
|
||||||
use snarkos_models::{
|
use snarkos_models::{
|
||||||
curves::{Field, PrimeField},
|
curves::{Field, PrimeField},
|
||||||
@ -16,10 +16,10 @@ use snarkos_models::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||||
fn check_arguments_length(expected: usize, actual: usize) -> Result<(), FunctionError> {
|
fn check_arguments_length(expected: usize, actual: usize, span: Span) -> Result<(), FunctionError> {
|
||||||
// Make sure we are given the correct number of arguments
|
// Make sure we are given the correct number of arguments
|
||||||
if expected != actual {
|
if expected != actual {
|
||||||
Err(FunctionError::ArgumentsLength(expected, actual))
|
Err(FunctionError::arguments_length(expected, actual, span))
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -55,7 +55,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
let function_name = new_scope(scope.clone(), function.get_name());
|
let function_name = new_scope(scope.clone(), function.get_name());
|
||||||
|
|
||||||
// Make sure we are given the correct number of inputs
|
// Make sure we are given the correct number of inputs
|
||||||
Self::check_arguments_length(function.inputs.len(), inputs.len())?;
|
Self::check_arguments_length(function.inputs.len(), inputs.len(), function.span.clone())?;
|
||||||
|
|
||||||
// Store input values as new variables in resolved program
|
// Store input values as new variables in resolved program
|
||||||
for (input_model, input_expression) in function.inputs.clone().iter().zip(inputs.into_iter()) {
|
for (input_model, input_expression) in function.inputs.clone().iter().zip(inputs.into_iter()) {
|
||||||
@ -97,7 +97,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let ConstrainedValue::Return(ref returns) = return_values {
|
if let ConstrainedValue::Return(ref returns) = return_values {
|
||||||
Self::check_arguments_length(function.returns.len(), returns.len())?;
|
Self::check_arguments_length(function.returns.len(), returns.len(), function.span.clone())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(return_values)
|
Ok(return_values)
|
||||||
@ -110,6 +110,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
array_type: Type,
|
array_type: Type,
|
||||||
array_dimensions: Vec<usize>,
|
array_dimensions: Vec<usize>,
|
||||||
input_value: Option<InputValue>,
|
input_value: Option<InputValue>,
|
||||||
|
span: Span,
|
||||||
) -> Result<ConstrainedValue<F, G>, FunctionError> {
|
) -> Result<ConstrainedValue<F, G>, FunctionError> {
|
||||||
let expected_length = array_dimensions[0];
|
let expected_length = array_dimensions[0];
|
||||||
let mut array_value = vec![];
|
let mut array_value = vec![];
|
||||||
@ -117,14 +118,20 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
match input_value {
|
match input_value {
|
||||||
Some(InputValue::Array(arr)) => {
|
Some(InputValue::Array(arr)) => {
|
||||||
// Check the dimension of the array
|
// Check the dimension of the array
|
||||||
Self::check_arguments_length(expected_length, arr.len())?;
|
Self::check_arguments_length(expected_length, arr.len(), span.clone())?;
|
||||||
|
|
||||||
// Allocate each value in the current row
|
// Allocate each value in the current row
|
||||||
for (i, value) in arr.into_iter().enumerate() {
|
for (i, value) in arr.into_iter().enumerate() {
|
||||||
let value_name = new_scope(name.clone(), i.to_string());
|
let value_name = new_scope(name.clone(), i.to_string());
|
||||||
let value_type = array_type.outer_dimension(&array_dimensions);
|
let value_type = array_type.outer_dimension(&array_dimensions);
|
||||||
|
|
||||||
array_value.push(self.allocate_main_function_input(cs, value_type, value_name, Some(value))?)
|
array_value.push(self.allocate_main_function_input(
|
||||||
|
cs,
|
||||||
|
value_type,
|
||||||
|
value_name,
|
||||||
|
Some(value),
|
||||||
|
span.clone(),
|
||||||
|
)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
@ -133,10 +140,16 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
let value_name = new_scope(name.clone(), i.to_string());
|
let value_name = new_scope(name.clone(), i.to_string());
|
||||||
let value_type = array_type.outer_dimension(&array_dimensions);
|
let value_type = array_type.outer_dimension(&array_dimensions);
|
||||||
|
|
||||||
array_value.push(self.allocate_main_function_input(cs, value_type, value_name, None)?);
|
array_value.push(self.allocate_main_function_input(
|
||||||
|
cs,
|
||||||
|
value_type,
|
||||||
|
value_name,
|
||||||
|
None,
|
||||||
|
span.clone(),
|
||||||
|
)?);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => return Err(FunctionError::InvalidArray(input_value.unwrap().to_string())),
|
_ => return Err(FunctionError::invalid_array(input_value.unwrap().to_string(), span)),
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ConstrainedValue::Array(array_value))
|
Ok(ConstrainedValue::Array(array_value))
|
||||||
@ -148,6 +161,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
_type: Type,
|
_type: Type,
|
||||||
name: String,
|
name: String,
|
||||||
input_value: Option<InputValue>,
|
input_value: Option<InputValue>,
|
||||||
|
span: Span,
|
||||||
) -> Result<ConstrainedValue<F, G>, FunctionError> {
|
) -> Result<ConstrainedValue<F, G>, FunctionError> {
|
||||||
match _type {
|
match _type {
|
||||||
Type::IntegerType(integer_type) => Ok(ConstrainedValue::Integer(Integer::from_input(
|
Type::IntegerType(integer_type) => Ok(ConstrainedValue::Integer(Integer::from_input(
|
||||||
@ -159,7 +173,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
Type::Field => Ok(field_from_input(cs, name, input_value)?),
|
Type::Field => Ok(field_from_input(cs, name, input_value)?),
|
||||||
Type::Group => Ok(group_from_input(cs, name, input_value)?),
|
Type::Group => Ok(group_from_input(cs, name, input_value)?),
|
||||||
Type::Boolean => Ok(self.bool_from_input(cs, name, input_value)?),
|
Type::Boolean => Ok(self.bool_from_input(cs, name, input_value)?),
|
||||||
Type::Array(_type, dimensions) => self.allocate_array(cs, name, *_type, dimensions, input_value),
|
Type::Array(_type, dimensions) => self.allocate_array(cs, name, *_type, dimensions, input_value, span),
|
||||||
_ => unimplemented!("main function input not implemented for type"),
|
_ => unimplemented!("main function input not implemented for type"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -174,14 +188,19 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
|||||||
let function_name = new_scope(scope.clone(), function.get_name());
|
let function_name = new_scope(scope.clone(), function.get_name());
|
||||||
|
|
||||||
// Make sure we are given the correct number of inputs
|
// Make sure we are given the correct number of inputs
|
||||||
Self::check_arguments_length(function.inputs.len(), inputs.len())?;
|
Self::check_arguments_length(function.inputs.len(), inputs.len(), function.span.clone())?;
|
||||||
|
|
||||||
// Iterate over main function inputs and allocate new passed-by variable values
|
// Iterate over main function inputs and allocate new passed-by variable values
|
||||||
let mut input_variables = vec![];
|
let mut input_variables = vec![];
|
||||||
for (input_model, input_option) in function.inputs.clone().into_iter().zip(inputs.into_iter()) {
|
for (input_model, input_option) in function.inputs.clone().into_iter().zip(inputs.into_iter()) {
|
||||||
let input_name = new_scope(function_name.clone(), input_model.identifier.name.clone());
|
let input_name = new_scope(function_name.clone(), input_model.identifier.name.clone());
|
||||||
let input_value =
|
let input_value = self.allocate_main_function_input(
|
||||||
self.allocate_main_function_input(cs, input_model._type, input_name.clone(), input_option)?;
|
cs,
|
||||||
|
input_model._type,
|
||||||
|
input_name.clone(),
|
||||||
|
input_option,
|
||||||
|
function.span.clone(),
|
||||||
|
)?;
|
||||||
|
|
||||||
// Store a new variable for every allocated main function input
|
// Store a new variable for every allocated main function input
|
||||||
self.store(input_name.clone(), input_value);
|
self.store(input_name.clone(), input_value);
|
||||||
|
@ -7,10 +7,10 @@ use std::num::ParseIntError;
|
|||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum ExpressionError {
|
pub enum ExpressionError {
|
||||||
#[error("{}", _0)]
|
#[error("{}", _0)]
|
||||||
Error(#[from] FormattedError),
|
BooleanError(#[from] BooleanError),
|
||||||
|
|
||||||
#[error("{}", _0)]
|
#[error("{}", _0)]
|
||||||
BooleanError(#[from] BooleanError),
|
Error(#[from] FormattedError),
|
||||||
|
|
||||||
#[error("{}", _0)]
|
#[error("{}", _0)]
|
||||||
IntegerError(#[from] IntegerError),
|
IntegerError(#[from] IntegerError),
|
||||||
@ -18,23 +18,20 @@ pub enum ExpressionError {
|
|||||||
#[error("{}", _0)]
|
#[error("{}", _0)]
|
||||||
FieldError(#[from] FieldError),
|
FieldError(#[from] FieldError),
|
||||||
|
|
||||||
|
#[error("{}", _0)]
|
||||||
|
FunctionError(#[from] Box<FunctionError>),
|
||||||
|
|
||||||
#[error("{}", _0)]
|
#[error("{}", _0)]
|
||||||
GroupError(#[from] GroupError),
|
GroupError(#[from] GroupError),
|
||||||
|
|
||||||
#[error("{}", _0)]
|
#[error("{}", _0)]
|
||||||
ParseIntError(#[from] ParseIntError),
|
ParseIntError(#[from] ParseIntError),
|
||||||
|
|
||||||
#[error("{}", _0)]
|
|
||||||
ValueError(#[from] ValueError),
|
|
||||||
|
|
||||||
#[error("{}", _0)]
|
|
||||||
FunctionError(#[from] Box<FunctionError>),
|
|
||||||
// Conditionals
|
|
||||||
#[error("If, else statements.conditional must resolve to a boolean, got {}", _0)]
|
|
||||||
IfElseConditional(String),
|
|
||||||
|
|
||||||
#[error("{}", _0)]
|
#[error("{}", _0)]
|
||||||
SynthesisError(#[from] SynthesisError),
|
SynthesisError(#[from] SynthesisError),
|
||||||
|
|
||||||
|
#[error("{}", _0)]
|
||||||
|
ValueError(#[from] ValueError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExpressionError {
|
impl ExpressionError {
|
||||||
|
@ -1,17 +1,25 @@
|
|||||||
use crate::errors::{BooleanError, ExpressionError, FieldError, GroupError, StatementError, ValueError};
|
use crate::errors::{
|
||||||
use leo_types::IntegerError;
|
BooleanError,
|
||||||
|
Error as FormattedError,
|
||||||
|
ExpressionError,
|
||||||
|
FieldError,
|
||||||
|
GroupError,
|
||||||
|
StatementError,
|
||||||
|
ValueError,
|
||||||
|
};
|
||||||
|
use leo_types::{IntegerError, Span};
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum FunctionError {
|
pub enum FunctionError {
|
||||||
#[error("Function expected {} inputs, got {}", _0, _1)]
|
|
||||||
ArgumentsLength(usize, usize),
|
|
||||||
|
|
||||||
#[error("{}", _0)]
|
#[error("{}", _0)]
|
||||||
BooleanError(#[from] BooleanError),
|
BooleanError(#[from] BooleanError),
|
||||||
|
|
||||||
#[error("{}", _0)]
|
#[error("{}", _0)]
|
||||||
ExpressionError(#[from] ExpressionError),
|
ExpressionError(#[from] ExpressionError),
|
||||||
|
|
||||||
|
#[error("{}", _0)]
|
||||||
|
Error(#[from] FormattedError),
|
||||||
|
|
||||||
#[error("{}", _0)]
|
#[error("{}", _0)]
|
||||||
FieldError(#[from] FieldError),
|
FieldError(#[from] FieldError),
|
||||||
|
|
||||||
@ -21,12 +29,27 @@ pub enum FunctionError {
|
|||||||
#[error("{}", _0)]
|
#[error("{}", _0)]
|
||||||
IntegerError(#[from] IntegerError),
|
IntegerError(#[from] IntegerError),
|
||||||
|
|
||||||
#[error("Expected function input array, got {}", _0)]
|
|
||||||
InvalidArray(String),
|
|
||||||
|
|
||||||
#[error("{}", _0)]
|
#[error("{}", _0)]
|
||||||
StatementError(#[from] StatementError),
|
StatementError(#[from] StatementError),
|
||||||
|
|
||||||
#[error("{}", _0)]
|
#[error("{}", _0)]
|
||||||
ValueError(#[from] ValueError),
|
ValueError(#[from] ValueError),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FunctionError {
|
||||||
|
fn new_from_span(message: String, span: Span) -> Self {
|
||||||
|
FunctionError::Error(FormattedError::new_from_span(message, span))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn arguments_length(expected: usize, actual: usize, span: Span) -> Self {
|
||||||
|
let message = format!("function expected {} inputs, found {} inputs", expected, actual);
|
||||||
|
|
||||||
|
Self::new_from_span(message, span)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn invalid_array(actual: String, span: Span) -> Self {
|
||||||
|
let message = format!("Expected function input array, found `{}`", actual);
|
||||||
|
|
||||||
|
Self::new_from_span(message, span)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::{FunctionInput, Identifier, Statement, Type};
|
use crate::{FunctionInput, Identifier, Span, Statement, Type};
|
||||||
use leo_ast::functions::Function as AstFunction;
|
use leo_ast::functions::Function as AstFunction;
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -9,6 +9,7 @@ pub struct Function {
|
|||||||
pub inputs: Vec<FunctionInput>,
|
pub inputs: Vec<FunctionInput>,
|
||||||
pub returns: Vec<Type>,
|
pub returns: Vec<Type>,
|
||||||
pub statements: Vec<Statement>,
|
pub statements: Vec<Statement>,
|
||||||
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ast> From<AstFunction<'ast>> for Function {
|
impl<'ast> From<AstFunction<'ast>> for Function {
|
||||||
@ -35,6 +36,7 @@ impl<'ast> From<AstFunction<'ast>> for Function {
|
|||||||
inputs: parameters,
|
inputs: parameters,
|
||||||
returns,
|
returns,
|
||||||
statements,
|
statements,
|
||||||
|
span: Span::from(function_definition.span),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user