mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-25 11:12:48 +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,
|
||||
GroupType,
|
||||
};
|
||||
use leo_types::{Expression, Function, InputValue, Integer, Program, Type};
|
||||
use leo_types::{Expression, Function, InputValue, Integer, Program, Span, Type};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
@ -16,10 +16,10 @@ use snarkos_models::{
|
||||
};
|
||||
|
||||
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
|
||||
if expected != actual {
|
||||
Err(FunctionError::ArgumentsLength(expected, actual))
|
||||
Err(FunctionError::arguments_length(expected, actual, span))
|
||||
} else {
|
||||
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());
|
||||
|
||||
// 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
|
||||
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 {
|
||||
Self::check_arguments_length(function.returns.len(), returns.len())?;
|
||||
Self::check_arguments_length(function.returns.len(), returns.len(), function.span.clone())?;
|
||||
}
|
||||
|
||||
Ok(return_values)
|
||||
@ -110,6 +110,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
array_type: Type,
|
||||
array_dimensions: Vec<usize>,
|
||||
input_value: Option<InputValue>,
|
||||
span: Span,
|
||||
) -> Result<ConstrainedValue<F, G>, FunctionError> {
|
||||
let expected_length = array_dimensions[0];
|
||||
let mut array_value = vec![];
|
||||
@ -117,14 +118,20 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
match input_value {
|
||||
Some(InputValue::Array(arr)) => {
|
||||
// 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
|
||||
for (i, value) in arr.into_iter().enumerate() {
|
||||
let value_name = new_scope(name.clone(), i.to_string());
|
||||
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 => {
|
||||
@ -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_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))
|
||||
@ -148,6 +161,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
_type: Type,
|
||||
name: String,
|
||||
input_value: Option<InputValue>,
|
||||
span: Span,
|
||||
) -> Result<ConstrainedValue<F, G>, FunctionError> {
|
||||
match _type {
|
||||
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::Group => Ok(group_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"),
|
||||
}
|
||||
}
|
||||
@ -174,14 +188,19 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
let function_name = new_scope(scope.clone(), function.get_name());
|
||||
|
||||
// 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
|
||||
let mut input_variables = vec![];
|
||||
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_value =
|
||||
self.allocate_main_function_input(cs, input_model._type, input_name.clone(), input_option)?;
|
||||
let input_value = self.allocate_main_function_input(
|
||||
cs,
|
||||
input_model._type,
|
||||
input_name.clone(),
|
||||
input_option,
|
||||
function.span.clone(),
|
||||
)?;
|
||||
|
||||
// Store a new variable for every allocated main function input
|
||||
self.store(input_name.clone(), input_value);
|
||||
|
@ -7,10 +7,10 @@ use std::num::ParseIntError;
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ExpressionError {
|
||||
#[error("{}", _0)]
|
||||
Error(#[from] FormattedError),
|
||||
BooleanError(#[from] BooleanError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
BooleanError(#[from] BooleanError),
|
||||
Error(#[from] FormattedError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
IntegerError(#[from] IntegerError),
|
||||
@ -18,23 +18,20 @@ pub enum ExpressionError {
|
||||
#[error("{}", _0)]
|
||||
FieldError(#[from] FieldError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
FunctionError(#[from] Box<FunctionError>),
|
||||
|
||||
#[error("{}", _0)]
|
||||
GroupError(#[from] GroupError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
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)]
|
||||
SynthesisError(#[from] SynthesisError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
ValueError(#[from] ValueError),
|
||||
}
|
||||
|
||||
impl ExpressionError {
|
||||
|
@ -1,17 +1,25 @@
|
||||
use crate::errors::{BooleanError, ExpressionError, FieldError, GroupError, StatementError, ValueError};
|
||||
use leo_types::IntegerError;
|
||||
use crate::errors::{
|
||||
BooleanError,
|
||||
Error as FormattedError,
|
||||
ExpressionError,
|
||||
FieldError,
|
||||
GroupError,
|
||||
StatementError,
|
||||
ValueError,
|
||||
};
|
||||
use leo_types::{IntegerError, Span};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum FunctionError {
|
||||
#[error("Function expected {} inputs, got {}", _0, _1)]
|
||||
ArgumentsLength(usize, usize),
|
||||
|
||||
#[error("{}", _0)]
|
||||
BooleanError(#[from] BooleanError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
ExpressionError(#[from] ExpressionError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
Error(#[from] FormattedError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
FieldError(#[from] FieldError),
|
||||
|
||||
@ -21,12 +29,27 @@ pub enum FunctionError {
|
||||
#[error("{}", _0)]
|
||||
IntegerError(#[from] IntegerError),
|
||||
|
||||
#[error("Expected function input array, got {}", _0)]
|
||||
InvalidArray(String),
|
||||
|
||||
#[error("{}", _0)]
|
||||
StatementError(#[from] StatementError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
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 std::fmt;
|
||||
@ -9,6 +9,7 @@ pub struct Function {
|
||||
pub inputs: Vec<FunctionInput>,
|
||||
pub returns: Vec<Type>,
|
||||
pub statements: Vec<Statement>,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl<'ast> From<AstFunction<'ast>> for Function {
|
||||
@ -35,6 +36,7 @@ impl<'ast> From<AstFunction<'ast>> for Function {
|
||||
inputs: parameters,
|
||||
returns,
|
||||
statements,
|
||||
span: Span::from(function_definition.span),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user