move function input length check to type checking phase

This commit is contained in:
collin 2020-11-30 13:34:21 -05:00
parent d4d5f336c4
commit 04081beb4b
5 changed files with 27 additions and 21 deletions

View File

@ -82,12 +82,6 @@ impl FunctionError {
FunctionError::Error(FormattedError::new_from_span(message, span))
}
pub fn arguments_length(expected: usize, actual: usize, span: Span) -> Self {
let message = format!("function expected {} input variables, found {}", 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);

View File

@ -23,22 +23,13 @@ use crate::{
GroupType,
};
use leo_ast::{Expression, Function, FunctionInput, Span, Type};
use leo_ast::{Expression, Function, FunctionInput, Type};
use snarkos_models::{
curves::{Field, PrimeField},
gadgets::r1cs::ConstraintSystem,
};
pub 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::arguments_length(expected, actual, span.to_owned()))
} else {
Ok(())
}
}
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
pub(crate) fn enforce_function<CS: ConstraintSystem<F>>(
&mut self,
@ -51,9 +42,6 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
) -> Result<ConstrainedValue<F, G>, FunctionError> {
let function_name = new_scope(scope, function.get_name());
// Make sure we are given the correct number of input variables
check_arguments_length(function.input.len(), input.len(), &function.span)?;
// Store input values as new variables in resolved program
for (input_model, input_expression) in function.input.iter().zip(input.into_iter()) {
let (name, value) = match input_model {

View File

@ -119,6 +119,16 @@ impl FunctionType {
Ok(())
}
///
/// Returns the number of input variables to the function.
/// The `self` and `mut self` keywords are not counted as input variables.
///
pub fn num_inputs(&self) -> usize {
self.inputs
.iter()
.fold(0, |acc, function_input| acc + function_input.count())
}
}
impl PartialEq for FunctionType {

View File

@ -64,6 +64,20 @@ impl FunctionInputType {
}
}
///
/// Returns `1` if a variable must be provided in a call to the function.
/// Returns `0` if the function input is a `self` or `mut self` keyword which does not have to
/// provided in a call to the function.
///
pub fn count(&self) -> usize {
match self {
FunctionInputType::InputKeyword(_) => 1,
FunctionInputType::SelfKeyword(_) => 0,
FunctionInputType::MutSelfKeyword(_) => 0,
FunctionInputType::Variable(_) => 1,
}
}
///
/// Return a new `FunctionInputType` from a given `FunctionInput`.
///

View File

@ -1097,8 +1097,8 @@ impl Frame {
let function_type = self.parse_function_name(expression, span)?;
// Check the length of arguments
if function_type.inputs.len() != inputs.len() {
return Err(FrameError::num_inputs(function_type.inputs.len(), inputs.len(), span));
if function_type.num_inputs() != inputs.len() {
return Err(FrameError::num_inputs(function_type.num_inputs(), inputs.len(), span));
}
// Assert function inputs are correct types.