diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index d4a22e3a70..5befd5ec4c 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -19,16 +19,16 @@ use sha2::{Digest, Sha256}; use std::{fs, marker::PhantomData, path::PathBuf}; #[derive(Clone)] -pub struct Compiler<'ast, F: Field + PrimeField, G: GroupType> { +pub struct Compiler> { package_name: String, main_file_path: PathBuf, program: Program, - program_inputs: Inputs<'ast>, + program_inputs: Inputs, output: Option>, _engine: PhantomData, } -impl<'ast, F: Field + PrimeField, G: GroupType> Compiler<'ast, F, G> { +impl> Compiler { pub fn new() -> Self { Self { package_name: "".to_string(), @@ -57,7 +57,7 @@ impl<'ast, F: Field + PrimeField, G: GroupType> Compiler<'ast, F, G> { Ok(program) } - pub fn set_inputs(&mut self, program_inputs: Vec>>) { + pub fn set_inputs(&mut self, program_inputs: Vec>) { self.program_inputs.set_inputs(program_inputs); } @@ -105,7 +105,7 @@ impl<'ast, F: Field + PrimeField, G: GroupType> Compiler<'ast, F, G> { Ok(()) } - pub fn parse_inputs( + pub fn parse_inputs<'ast>( &mut self, input_file_path: &'ast PathBuf, input_file_string: &'ast str, @@ -119,7 +119,7 @@ impl<'ast, F: Field + PrimeField, G: GroupType> Compiler<'ast, F, G> { } } -impl<'ast, F: Field + PrimeField, G: GroupType> ConstraintSynthesizer for Compiler<'ast, F, G> { +impl> ConstraintSynthesizer for Compiler { fn generate_constraints>(self, cs: &mut CS) -> Result<(), SynthesisError> { let _result = generate_constraints::<_, G, _>(cs, self.program, self.program_inputs.get_inputs()).map_err(|e| { diff --git a/compiler/src/constraints/boolean.rs b/compiler/src/constraints/boolean.rs index 782e0d46f2..f041cd1671 100644 --- a/compiler/src/constraints/boolean.rs +++ b/compiler/src/constraints/boolean.rs @@ -26,12 +26,10 @@ impl> ConstrainedProgram { // Check that the input value is the correct type let bool_value = match input_value { Some(input) => { - if let InputValue::Boolean(ast) = input { - let bool = ast.value.parse::()?; - + if let InputValue::Boolean(bool) = input { Some(bool) } else { - return Err(BooleanError::from(input)); + return Err(BooleanError::SynthesisError(SynthesisError::AssignmentMissing)); } } None => None, diff --git a/compiler/src/constraints/field.rs b/compiler/src/constraints/field.rs index 70e0e85586..c1990c6c38 100644 --- a/compiler/src/constraints/field.rs +++ b/compiler/src/constraints/field.rs @@ -17,8 +17,8 @@ pub(crate) fn field_from_input, CS: Const // Check that the parameter value is the correct type let field_option = match input_value { Some(input) => { - if let InputValue::Field(ast) = input { - Some(ast.number.value) + if let InputValue::Field(string) = input { + Some(string) } else { return Err(FieldError::Invalid(input.to_string())); } diff --git a/compiler/src/constraints/group.rs b/compiler/src/constraints/group.rs index 71c676c27f..93c90d0f71 100644 --- a/compiler/src/constraints/group.rs +++ b/compiler/src/constraints/group.rs @@ -15,8 +15,8 @@ pub(crate) fn group_from_input, CS: Const // Check that the parameter value is the correct type let group_option = match input_value { Some(input) => { - if let InputValue::Group(ast) = input { - Some(ast.value.to_string()) + if let InputValue::Group(string) = input { + Some(string) } else { return Err(GroupError::Invalid(input.to_string())); } diff --git a/compiler/src/errors/constraints/boolean.rs b/compiler/src/errors/constraints/boolean.rs index 10cb726289..24e4ed0088 100644 --- a/compiler/src/errors/constraints/boolean.rs +++ b/compiler/src/errors/constraints/boolean.rs @@ -1,8 +1,5 @@ use snarkos_errors::gadgets::SynthesisError; -use leo_inputs::SyntaxError as InputSyntaxError; -use leo_types::InputValue; -use pest::error::{Error, ErrorVariant}; use std::str::ParseBoolError; #[derive(Debug, Error)] @@ -18,20 +15,4 @@ pub enum BooleanError { #[error("{}", _0)] SynthesisError(#[from] SynthesisError), - - #[error("{}", _0)] - SyntaxError(#[from] InputSyntaxError), -} - -impl<'ast> From> for BooleanError { - fn from(value: InputValue<'ast>) -> Self { - let error = Error::new_from_span( - ErrorVariant::CustomError { - message: format!("expected boolean input, actual {}", value.to_string()), - }, - value.span().to_owned(), - ); - - BooleanError::SyntaxError(InputSyntaxError::from(error)) - } } diff --git a/compiler/tests/array/mod.rs b/compiler/tests/array/mod.rs index 2df023642b..a1310e8eae 100644 --- a/compiler/tests/array/mod.rs +++ b/compiler/tests/array/mod.rs @@ -3,9 +3,9 @@ use leo_compiler::{ errors::{CompilerError, FunctionError}, ConstrainedValue, }; +use leo_inputs::types::{IntegerType, U32Type}; use leo_types::{InputValue, Integer, IntegerError}; -use leo_inputs::types::{IntegerType, U32Type}; use snarkos_models::gadgets::utilities::uint::UInt32; // [1, 1, 1] @@ -41,7 +41,7 @@ fn output_multi(program: EdwardsTestCompiler) { fn fail_array(program: EdwardsTestCompiler) { match get_error(program) { - CompilerError::FunctionError(FunctionError::InvalidArray(_string)) => {} + CompilerError::FunctionError(FunctionError::Error(_string)) => {} error => panic!("Expected invalid array error, got {}", error), } } diff --git a/compiler/tests/boolean/mod.rs b/compiler/tests/boolean/mod.rs index b42f9e3d4b..b6ae7ab741 100644 --- a/compiler/tests/boolean/mod.rs +++ b/compiler/tests/boolean/mod.rs @@ -3,24 +3,9 @@ use leo_compiler::{ errors::{BooleanError, CompilerError, ExpressionError, FunctionError, StatementError}, ConstrainedValue, }; -use leo_inputs::syntax::SyntaxError; +use leo_types::InputValue; -use crate::input_value_u32_one; use snarkos_models::gadgets::utilities::boolean::Boolean; -// use leo_types::InputValue; -// use pest::Span; -// use leo_inputs::types::BooleanType; -// use leo_inputs::values::BooleanValue; -// -// pub fn input_value_bool(bool: bool) -> InputValue<'static> { -// let input = bool.to_string(); -// let span = Span::new(&input, 0, input.len()).unwrap(); -// -// InputValue::Boolean(BooleanValue { -// value: input, -// span, -// }) -// } pub fn output_expected_boolean(program: EdwardsTestCompiler, boolean: bool) { let output = get_output(program); @@ -58,7 +43,7 @@ fn fail_enforce(program: EdwardsTestCompiler) { fn fail_boolean(program: EdwardsTestCompiler) { match get_error(program) { - CompilerError::FunctionError(FunctionError::BooleanError(BooleanError::SyntaxError(SyntaxError::Error))) => {} + CompilerError::FunctionError(FunctionError::BooleanError(BooleanError::SynthesisError(_))) => {} error => panic!("Expected invalid boolean error, got {}", error), } } @@ -91,7 +76,7 @@ fn test_input_bool_field() { let bytes = include_bytes!("input_bool.leo"); let mut program = parse_program(bytes).unwrap(); - program.set_inputs(vec![Some(input_value_u32_one())]); + program.set_inputs(vec![Some(InputValue::Field("1field".to_string()))]); fail_boolean(program); } diff --git a/compiler/tests/circuits/mod.rs b/compiler/tests/circuits/mod.rs index 9cf04659b7..f83c71f8a0 100644 --- a/compiler/tests/circuits/mod.rs +++ b/compiler/tests/circuits/mod.rs @@ -11,7 +11,7 @@ use leo_compiler::{ ConstrainedCircuitMember, ConstrainedValue, }; -use leo_types::{Expression, Function, Identifier, Integer, Statement, Type}; +use leo_types::{Expression, Function, Identifier, Integer, Span, Statement, Type}; use snarkos_models::gadgets::utilities::uint::UInt32; @@ -20,9 +20,25 @@ fn output_circuit(program: EdwardsTestCompiler) { let output = get_output(program); assert_eq!( EdwardsConstrainedValue::Return(vec![ConstrainedValue::CircuitExpression( - Identifier::new("Circ".into()), + Identifier { + name: "Circ".to_string(), + span: Span { + text: "".to_string(), + line: 0, + start: 0, + end: 0 + } + }, vec![ConstrainedCircuitMember( - Identifier::new("x".into()), + Identifier { + name: "x".to_string(), + span: Span { + text: "".to_string(), + line: 0, + start: 0, + end: 0 + } + }, ConstrainedValue::Integer(Integer::U32(UInt32::constant(1u32))) )] )]) @@ -34,7 +50,7 @@ fn output_circuit(program: EdwardsTestCompiler) { fn fail_expected_member(program: EdwardsTestCompiler) { match get_error(program) { CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError( - ExpressionError::ExpectedCircuitMember(_string), + ExpressionError::Error(_string), ))) => {} error => panic!("Expected invalid circuit member error, got {}", error), } @@ -43,7 +59,7 @@ fn fail_expected_member(program: EdwardsTestCompiler) { fn fail_undefined_member(program: EdwardsTestCompiler) { match get_error(program) { CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError( - ExpressionError::UndefinedMemberAccess(_, _), + ExpressionError::Error(_), ))) => {} error => panic!("Expected undefined circuit member error, got {}", error), } @@ -74,7 +90,7 @@ fn test_inline_undefined() { match get_error(program) { CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError( - ExpressionError::UndefinedCircuit(_), + ExpressionError::Error(_), ))) => {} error => panic!("Expected undefined circuit error, got {}", error), } @@ -121,7 +137,7 @@ fn test_member_function_invalid() { match get_error(program) { CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError( - ExpressionError::InvalidStaticAccess(_), + ExpressionError::Error(_), ))) => {} error => panic!("Expected invalid function error, got {}", error), } @@ -142,7 +158,7 @@ fn test_member_static_function_undefined() { match get_error(program) { CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError( - ExpressionError::UndefinedStaticAccess(_, _), + ExpressionError::Error(_), ))) => {} error => panic!("Expected undefined static function error, got {}", error), } @@ -155,7 +171,7 @@ fn test_member_static_function_invalid() { match get_error(program) { CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError( - ExpressionError::InvalidMemberAccess(_), + ExpressionError::Error(_), ))) => {} error => panic!("Expected invalid static function error, got {}", error), } @@ -176,19 +192,79 @@ fn test_self() { // } assert_eq!( EdwardsConstrainedValue::Return(vec![ConstrainedValue::CircuitExpression( - Identifier::new("Circ".into()), + Identifier { + name: "Circ".to_string(), + span: Span { + text: "".to_string(), + line: 0, + start: 0, + end: 0 + } + }, vec![ConstrainedCircuitMember( - Identifier::new("new".into()), + Identifier { + name: "new".to_string(), + span: Span { + text: "".to_string(), + line: 0, + start: 0, + end: 0 + } + }, ConstrainedValue::Static(Box::new(ConstrainedValue::Function( - Some(Identifier::new("Circ".into())), + Some(Identifier { + name: "new".to_string(), + span: Span { + text: "".to_string(), + line: 0, + start: 0, + end: 0 + } + }), Function { - function_name: Identifier::new("new".into()), + function_name: Identifier { + name: "new".to_string(), + span: Span { + text: "".to_string(), + line: 0, + start: 0, + end: 0 + } + }, inputs: vec![], returns: vec![Type::SelfType], - statements: vec![Statement::Return(vec![Expression::Circuit( - Identifier::new("Self".into()), - vec![] - )])] + statements: vec![Statement::Return( + vec![Expression::Circuit( + Identifier { + name: "Self".to_string(), + span: Span { + text: "".to_string(), + line: 0, + start: 0, + end: 0 + } + }, + vec![], + Span { + text: "".to_string(), + line: 0, + start: 0, + end: 0 + } + )], + Span { + text: "".to_string(), + line: 0, + start: 0, + end: 0 + } + )], + span: Span { + text: "".to_string(), + line: 0, + start: 0, + end: 0 + } } ))) )] @@ -202,6 +278,8 @@ fn test_self() { // #[test] // fn test_pedersen_mock() { -// let program = compile_program(DIRECTORY_NAME, "pedersen_mock.leo").unwrap(); +// let bytes = include_bytes!("pedersen_mock.leo"); +// let program = parse_program(bytes).unwrap(); +// // output_zero(program); // } diff --git a/compiler/tests/circuits/pedersen_mock.leo b/compiler/tests/circuits/pedersen_mock.leo index 4b8ac0053c..ce7b714716 100644 --- a/compiler/tests/circuits/pedersen_mock.leo +++ b/compiler/tests/circuits/pedersen_mock.leo @@ -1,27 +1,22 @@ circuit PedersenHash { - parameters: group[512] - - static function new(parameters: group[512]) -> Self { + parameters: u32[512] + static function new(parameters: u32[512]) -> Self { return Self { parameters: parameters } } - - function hash(bits: bool[512]) -> group { - let mut digest: group = 0; - + function hash(bits: bool[512]) -> u32 { + let mut digest: u32 = 0; for i in 0..512 { - let base = if bits[i] ? parameters[i] : 0; + let base = if bits[i] ? parameters[i] : 0u32; digest += base; } - return digest } } -function main(parameters: group[512]) -> group { +// The 'pedersen_hash' main function. +function main() -> u32 { + let parameters = [0u32; 512]; let pedersen = PedersenHash::new(parameters); - - let input: bool[512] = [true; 512]; // use mock private key until `.bits()` function is implemented - let output = pedersen.hash(input); - - return output -} \ No newline at end of file + let input: bool[512] = [true; 512]; + return pedersen.hash(input) +} diff --git a/compiler/tests/function/mod.rs b/compiler/tests/function/mod.rs index 88cf63726c..e108c9e079 100644 --- a/compiler/tests/function/mod.rs +++ b/compiler/tests/function/mod.rs @@ -34,7 +34,7 @@ pub(crate) fn output_multiple(program: EdwardsTestCompiler) { fn fail_undefined_identifier(program: EdwardsTestCompiler) { match get_error(program) { CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError( - ExpressionError::UndefinedIdentifier(_), + ExpressionError::Error(_), ))) => {} error => panic!("Expected function undefined, got {}", error), } @@ -77,8 +77,7 @@ fn test_global_scope_fail() { CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError( ExpressionError::FunctionError(value), ))) => match *value { - FunctionError::StatementError(StatementError::ExpressionError(ExpressionError::UndefinedIdentifier(_))) => { - } + FunctionError::StatementError(StatementError::ExpressionError(ExpressionError::Error(_))) => {} error => panic!("Expected function undefined, got {}", error), }, error => panic!("Expected function undefined, got {}", error), diff --git a/compiler/tests/integers/mod.rs b/compiler/tests/integers/mod.rs index 4ed91e30ad..e8e4914e42 100644 --- a/compiler/tests/integers/mod.rs +++ b/compiler/tests/integers/mod.rs @@ -61,8 +61,8 @@ pub(crate) fn fail_synthesis(program: EdwardsTestCompiler) { } // must be below macro definitions! -pub mod u128; -pub mod u16; +// pub mod u128; +// pub mod u16; pub mod u32; -pub mod u64; -pub mod u8; +// pub mod u64; +// pub mod u8; diff --git a/compiler/tests/mod.rs b/compiler/tests/mod.rs index 6877b7f736..95c15cfc01 100644 --- a/compiler/tests/mod.rs +++ b/compiler/tests/mod.rs @@ -1,13 +1,13 @@ -// pub mod array; +pub mod array; pub mod boolean; -// pub mod circuits; -// pub mod field; -// pub mod function; -// pub mod group; -// pub mod import; +pub mod circuits; +pub mod field; +pub mod function; +pub mod group; +pub mod import; pub mod inputs; -// pub mod integers; -// pub mod mutability; +pub mod integers; +pub mod mutability; pub mod statements; pub mod syntax; @@ -18,17 +18,11 @@ use leo_compiler::{ ConstrainedValue, }; -use leo_inputs::{ - types::{IntegerType, U32Type}, - values::{IntegerValue, NumberValue}, -}; -use leo_types::InputValue; -use pest::Span; use snarkos_curves::edwards_bls12::Fq; use snarkos_models::gadgets::r1cs::TestConstraintSystem; use std::path::PathBuf; -pub type EdwardsTestCompiler<'ast> = Compiler<'ast, Fq, EdwardsGroupType>; +pub type EdwardsTestCompiler = Compiler; pub type EdwardsConstrainedValue = ConstrainedValue; pub(crate) fn get_output(program: EdwardsTestCompiler) -> EdwardsConstrainedValue { @@ -60,27 +54,12 @@ pub(crate) fn parse_program(bytes: &[u8]) -> Result Result<&mut EdwardsTestCompiler, CompilerError> { -// let inputs_string = String::from_utf8_lossy(bytes); -// -// let mut compiler = EdwardsTestCompiler::new(); -// -// compiler.parse_inputs(&PathBuf::new(), &inputs_string)?; -// -// Ok(&mut compiler) -// } +pub(crate) fn parse_inputs(bytes: &[u8]) -> Result { + let inputs_string = String::from_utf8_lossy(bytes); -pub(crate) fn input_value_u32_one() -> InputValue<'static> { - let input = "1"; - let span = Span::new(input, 0, input.len()).unwrap(); - let type_ = IntegerType::U32Type(U32Type { span: span.clone() }); + let mut compiler = EdwardsTestCompiler::new(); - InputValue::Integer(IntegerValue { - number: NumberValue { - value: input.into(), - span: span.clone(), - }, - type_, - span, - }) + compiler.parse_inputs(&PathBuf::new(), &inputs_string)?; + + Ok(compiler) } diff --git a/compiler/tests/mutability/mod.rs b/compiler/tests/mutability/mod.rs index e04ca08cae..c21f47613b 100644 --- a/compiler/tests/mutability/mod.rs +++ b/compiler/tests/mutability/mod.rs @@ -1,11 +1,10 @@ -use crate::{parse_program, EdwardsConstrainedValue, EdwardsTestCompiler}; +use crate::{array::input_value_u32_one, parse_program, EdwardsConstrainedValue, EdwardsTestCompiler}; use leo_compiler::{ errors::{CompilerError, FunctionError, StatementError}, ConstrainedValue, }; use leo_types::Integer; -use crate::array::input_value_u32_one; use snarkos_curves::edwards_bls12::Fq; use snarkos_models::gadgets::{r1cs::TestConstraintSystem, utilities::uint::UInt32}; @@ -27,7 +26,7 @@ fn mut_fail(program: EdwardsTestCompiler) { // It would be ideal if assert_eq!(Error1, Error2) were possible but unfortunately it is not due to // https://github.com/rust-lang/rust/issues/34158#issuecomment-224910299 match err { - CompilerError::FunctionError(FunctionError::StatementError(StatementError::ImmutableAssign(_string))) => {} + CompilerError::FunctionError(FunctionError::StatementError(StatementError::Error(_string))) => {} err => panic!("Expected immutable assign error, got {}", err), } } diff --git a/compiler/tests/statements/conditional/mod.rs b/compiler/tests/statements/conditional/mod.rs index daedea040f..65f5ba15c6 100644 --- a/compiler/tests/statements/conditional/mod.rs +++ b/compiler/tests/statements/conditional/mod.rs @@ -1,6 +1,6 @@ use crate::{ get_output, - integers::u32::{output_one, output_zero}, + integers::u32::{output_number, output_one, output_zero}, parse_program, EdwardsConstrainedValue, EdwardsTestCompiler, @@ -8,7 +8,6 @@ use crate::{ use leo_inputs::types::{IntegerType, U32Type}; use leo_types::InputValue; -use crate::integers::u32::output_number; use snarkos_curves::edwards_bls12::Fq; use snarkos_models::gadgets::r1cs::TestConstraintSystem; diff --git a/compiler/tests/statements/mod.rs b/compiler/tests/statements/mod.rs index e58103fc9b..31dc76ca16 100644 --- a/compiler/tests/statements/mod.rs +++ b/compiler/tests/statements/mod.rs @@ -1,60 +1,64 @@ -use crate::{get_error, parse_program}; +use crate::{ + get_error, + integers::u32::{output_one, output_zero}, + parse_program, +}; use leo_types::InputValue; use snarkos_curves::edwards_bls12::Fq; use snarkos_models::gadgets::r1cs::TestConstraintSystem; -// pub mod conditional; +pub mod conditional; // Ternary if {bool}? {expression} : {expression}; -// #[test] -// fn test_ternary_basic() { -// let bytes = include_bytes!("ternary_basic.leo"); -// let mut program_input_true = parse_program(bytes).unwrap(); -// -// let mut program_input_false = program_input_true.clone(); -// -// program_input_true.set_inputs(vec![Some(input_value_bool(true))]); -// output_one(program_input_true); -// -// program_input_false.set_inputs(vec![Some(input_value_bool(false))]); -// output_zero(program_input_false); -// } -// -// // Iteration for i {start}..{stop} { statements } -// -// #[test] -// fn test_iteration_basic() { -// let bytes = include_bytes!("iteration_basic.leo"); -// let program = parse_program(bytes).unwrap(); -// -// output_one(program); -// } -// -// // Assertion -// -// #[test] -// fn test_assertion_basic() { -// let bytes = include_bytes!("assertion_basic.leo"); -// let program = parse_program(bytes).unwrap(); -// -// let mut program_input_true = program.clone(); -// let mut cs_satisfied = TestConstraintSystem::::new(); -// -// program_input_true.set_inputs(vec![Some(input_value_bool(true))]); -// let _output = program_input_true.compile_constraints(&mut cs_satisfied).unwrap(); -// -// assert!(cs_satisfied.is_satisfied()); -// -// let mut program_input_false = program.clone(); -// let mut cs_unsatisfied = TestConstraintSystem::::new(); -// -// program_input_false.set_inputs(vec![Some(input_value_bool(false))]); -// let _output = program_input_false.compile_constraints(&mut cs_unsatisfied).unwrap(); -// -// assert!(!cs_unsatisfied.is_satisfied()); -// } +#[test] +fn test_ternary_basic() { + let bytes = include_bytes!("ternary_basic.leo"); + let mut program_input_true = parse_program(bytes).unwrap(); + + let mut program_input_false = program_input_true.clone(); + + program_input_true.set_inputs(vec![Some(InputValue::Boolean(true))]); + output_one(program_input_true); + + program_input_false.set_inputs(vec![Some(InputValue::Boolean(false))]); + output_zero(program_input_false); +} + +// Iteration for i {start}..{stop} { statements } + +#[test] +fn test_iteration_basic() { + let bytes = include_bytes!("iteration_basic.leo"); + let program = parse_program(bytes).unwrap(); + + output_one(program); +} + +// Assertion + +#[test] +fn test_assertion_basic() { + let bytes = include_bytes!("assertion_basic.leo"); + let program = parse_program(bytes).unwrap(); + + let mut program_input_true = program.clone(); + let mut cs_satisfied = TestConstraintSystem::::new(); + + program_input_true.set_inputs(vec![Some(InputValue::Boolean(true))]); + let _output = program_input_true.compile_constraints(&mut cs_satisfied).unwrap(); + + assert!(cs_satisfied.is_satisfied()); + + let mut program_input_false = program.clone(); + let mut cs_unsatisfied = TestConstraintSystem::::new(); + + program_input_false.set_inputs(vec![Some(InputValue::Boolean(false))]); + let _output = program_input_false.compile_constraints(&mut cs_unsatisfied).unwrap(); + + assert!(!cs_unsatisfied.is_satisfied()); +} #[test] fn test_num_returns_fail() { diff --git a/compiler/tests/syntax/mod.rs b/compiler/tests/syntax/mod.rs index c434690bb5..994a972322 100644 --- a/compiler/tests/syntax/mod.rs +++ b/compiler/tests/syntax/mod.rs @@ -1,4 +1,4 @@ -use crate::{get_error, parse_program}; +use crate::{get_error, parse_inputs, parse_program}; use leo_ast::ParserError; use leo_compiler::errors::{CompilerError, ExpressionError, FunctionError, StatementError}; use leo_inputs::InputParserError; @@ -42,13 +42,13 @@ fn test_undefined() { } } -// #[test] -// fn inputs_syntax_error() { -// let bytes = include_bytes!("inputs_semicolon.leo"); -// let error = parse_inputs(bytes).err().unwrap(); -// -// match error { -// CompilerError::InputParserError(InputParserError::SyntaxError(_)) => {} -// _ => panic!("inputs syntax error should be a ParserError"), -// } -// } +#[test] +fn inputs_syntax_error() { + let bytes = include_bytes!("inputs_semicolon.leo"); + let error = parse_inputs(bytes).err().unwrap(); + + match error { + CompilerError::InputParserError(InputParserError::SyntaxError(_)) => {} + _ => panic!("inputs syntax error should be a ParserError"), + } +} diff --git a/leo-inputs/src/errors/parser.rs b/leo-inputs/src/errors/parser.rs index 74b8e26721..ab813980a4 100644 --- a/leo-inputs/src/errors/parser.rs +++ b/leo-inputs/src/errors/parser.rs @@ -1,10 +1,11 @@ -use crate::{ast::Rule, errors::SyntaxError as InputSyntaxError}; - use crate::{ + ast::Rule, + errors::SyntaxError as InputSyntaxError, expressions::{ArrayInitializerExpression, ArrayInlineExpression, Expression}, - types::{DataType, IntegerType, Type}, - values::{IntegerValue, NumberValue, Value}, + types::{DataType, Type}, + values::{NumberImplicitValue, NumberValue, Value}, }; + use pest::{ error::{Error, ErrorVariant}, Span, @@ -33,38 +34,44 @@ pub enum InputParserError { } impl InputParserError { - fn syntax_error_span(message: String, span: Span) -> Self { + fn new_from_span(message: String, span: Span) -> Self { let error = Error::new_from_span(ErrorVariant::CustomError { message }, span); InputParserError::SyntaxError(InputSyntaxError::from(error)) } - pub fn integer_type_mismatch<'ast>(integer_type: IntegerType<'ast>, integer_value: IntegerValue<'ast>) -> Self { - let message = format!( - "expected `{}`, found `{}`", - integer_type.to_string(), - integer_value.type_.to_string() - ); - let span = integer_value.type_.span().to_owned(); + // pub fn integer_type_mismatch(integer_type: IntegerType, integer_value: IntegerValue) -> Self { + // let message = format!( + // "expected `{}`, found `{}`", + // integer_type.to_string(), + // integer_value.type_.to_string() + // ); + // let span = integer_value.type_.span().to_owned(); + // + // InputParserError::syntax_error_span(message, span) + // } - InputParserError::syntax_error_span(message, span) + pub fn implicit_boolean(data_type: DataType, implicit: NumberImplicitValue) -> Self { + let message = format!("expected `{}`, found `{}`", data_type.to_string(), implicit.to_string()); + + Self::new_from_span(message, implicit.span) } - pub fn data_type_mismatch<'ast>(data_type: DataType<'ast>, value: Value<'ast>) -> Self { + pub fn data_type_mismatch(data_type: DataType, value: Value) -> Self { let message = format!("expected `{}`, found `{}`", data_type.to_string(), value.to_string()); let span = value.span().to_owned(); - InputParserError::syntax_error_span(message, span) + Self::new_from_span(message, span) } - pub fn expression_type_mismatch<'ast>(type_: Type<'ast>, expression: Expression<'ast>) -> Self { + pub fn expression_type_mismatch(type_: Type, expression: Expression) -> Self { let message = format!("expected `{}`, found `{}`", type_.to_string(), expression.to_string()); let span = expression.span().to_owned(); - InputParserError::syntax_error_span(message, span) + Self::new_from_span(message, span) } - pub fn array_inline_length<'ast>(number: NumberValue<'ast>, array: ArrayInlineExpression<'ast>) -> Self { + pub fn array_inline_length(number: NumberValue, array: ArrayInlineExpression) -> Self { let message = format!( "expected an array with a fixed size of {} elements, found one with {} elements", number.to_string(), @@ -72,10 +79,10 @@ impl InputParserError { ); let span = array.span.to_owned(); - InputParserError::syntax_error_span(message, span) + Self::new_from_span(message, span) } - pub fn array_init_length<'ast>(number: NumberValue<'ast>, array: ArrayInitializerExpression<'ast>) -> Self { + pub fn array_init_length(number: NumberValue, array: ArrayInitializerExpression) -> Self { let message = format!( "expected an array with a fixed size of {} elements, found one with {} elements", number.to_string(), @@ -83,7 +90,7 @@ impl InputParserError { ); let span = array.span.to_owned(); - InputParserError::syntax_error_span(message, span) + Self::new_from_span(message, span) } } diff --git a/leo-inputs/src/types/array_type.rs b/leo-inputs/src/types/array_type.rs index 76753751b1..fd1ca18dbe 100644 --- a/leo-inputs/src/types/array_type.rs +++ b/leo-inputs/src/types/array_type.rs @@ -6,7 +6,7 @@ use pest_ast::FromPest; #[derive(Clone, Debug, FromPest, PartialEq)] #[pest_ast(rule(Rule::type_array))] pub struct ArrayType<'ast> { - pub _type: DataType<'ast>, + pub _type: DataType, pub dimensions: Vec>, #[pest_ast(outer())] pub span: Span<'ast>, diff --git a/leo-inputs/src/types/boolean_type.rs b/leo-inputs/src/types/boolean_type.rs index e3f7e8c3e5..ce338e0447 100644 --- a/leo-inputs/src/types/boolean_type.rs +++ b/leo-inputs/src/types/boolean_type.rs @@ -1,11 +1,7 @@ use crate::ast::Rule; -use pest::Span; use pest_ast::FromPest; #[derive(Clone, Debug, FromPest, PartialEq, Eq)] #[pest_ast(rule(Rule::type_boolean))] -pub struct BooleanType<'ast> { - #[pest_ast(outer())] - pub span: Span<'ast>, -} +pub struct BooleanType {} diff --git a/leo-inputs/src/types/data_type.rs b/leo-inputs/src/types/data_type.rs index 1de5e40392..83199b5813 100644 --- a/leo-inputs/src/types/data_type.rs +++ b/leo-inputs/src/types/data_type.rs @@ -3,30 +3,18 @@ use crate::{ types::{BooleanType, FieldType, GroupType, IntegerType}, }; -use pest::Span; use pest_ast::FromPest; #[derive(Clone, Debug, FromPest, PartialEq, Eq)] #[pest_ast(rule(Rule::type_data))] -pub enum DataType<'ast> { - Integer(IntegerType<'ast>), - Field(FieldType<'ast>), - Group(GroupType<'ast>), - Boolean(BooleanType<'ast>), +pub enum DataType { + Integer(IntegerType), + Field(FieldType), + Group(GroupType), + Boolean(BooleanType), } -impl<'ast> DataType<'ast> { - pub fn span(&self) -> &Span<'ast> { - match self { - DataType::Boolean(type_) => &type_.span, - DataType::Integer(type_) => type_.span(), - DataType::Field(type_) => &type_.span, - DataType::Group(type_) => &type_.span, - } - } -} - -impl<'ast> std::fmt::Display for DataType<'ast> { +impl std::fmt::Display for DataType { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { DataType::Integer(ref integer) => write!(f, "{}", integer), diff --git a/leo-inputs/src/types/field_type.rs b/leo-inputs/src/types/field_type.rs index dc1515fa6c..17fc1082ff 100644 --- a/leo-inputs/src/types/field_type.rs +++ b/leo-inputs/src/types/field_type.rs @@ -1,11 +1,7 @@ use crate::ast::Rule; -use pest::Span; use pest_ast::FromPest; #[derive(Clone, Debug, FromPest, PartialEq, Eq)] #[pest_ast(rule(Rule::type_field))] -pub struct FieldType<'ast> { - #[pest_ast(outer())] - pub span: Span<'ast>, -} +pub struct FieldType {} diff --git a/leo-inputs/src/types/group_type.rs b/leo-inputs/src/types/group_type.rs index 008f945277..6ffe8956fb 100644 --- a/leo-inputs/src/types/group_type.rs +++ b/leo-inputs/src/types/group_type.rs @@ -1,11 +1,7 @@ use crate::ast::Rule; -use pest::Span; use pest_ast::FromPest; #[derive(Clone, Debug, FromPest, PartialEq, Eq)] #[pest_ast(rule(Rule::type_group))] -pub struct GroupType<'ast> { - #[pest_ast(outer())] - pub span: Span<'ast>, -} +pub struct GroupType {} diff --git a/leo-inputs/src/types/integer_type.rs b/leo-inputs/src/types/integer_type.rs index 56ac10b014..ed2b520d1c 100644 --- a/leo-inputs/src/types/integer_type.rs +++ b/leo-inputs/src/types/integer_type.rs @@ -1,66 +1,38 @@ use crate::ast::Rule; -use pest::Span; use pest_ast::FromPest; #[derive(Clone, Debug, FromPest, PartialEq, Eq)] #[pest_ast(rule(Rule::type_integer))] -pub enum IntegerType<'ast> { - U8Type(U8Type<'ast>), - U16Type(U16Type<'ast>), - U32Type(U32Type<'ast>), - U64Type(U64Type<'ast>), - U128Type(U128Type<'ast>), +pub enum IntegerType { + U8Type(U8Type), + U16Type(U16Type), + U32Type(U32Type), + U64Type(U64Type), + U128Type(U128Type), } #[derive(Clone, Debug, FromPest, PartialEq, Eq)] #[pest_ast(rule(Rule::type_u8))] -pub struct U8Type<'ast> { - #[pest_ast(outer())] - pub span: Span<'ast>, -} +pub struct U8Type {} #[derive(Clone, Debug, FromPest, PartialEq, Eq)] #[pest_ast(rule(Rule::type_u16))] -pub struct U16Type<'ast> { - #[pest_ast(outer())] - pub span: Span<'ast>, -} +pub struct U16Type {} #[derive(Clone, Debug, FromPest, PartialEq, Eq)] #[pest_ast(rule(Rule::type_u32))] -pub struct U32Type<'ast> { - #[pest_ast(outer())] - pub span: Span<'ast>, -} +pub struct U32Type {} #[derive(Clone, Debug, FromPest, PartialEq, Eq)] #[pest_ast(rule(Rule::type_u64))] -pub struct U64Type<'ast> { - #[pest_ast(outer())] - pub span: Span<'ast>, -} +pub struct U64Type {} #[derive(Clone, Debug, FromPest, PartialEq, Eq)] #[pest_ast(rule(Rule::type_u128))] -pub struct U128Type<'ast> { - #[pest_ast(outer())] - pub span: Span<'ast>, -} +pub struct U128Type {} -impl<'ast> IntegerType<'ast> { - pub fn span(&self) -> &Span<'ast> { - match self { - IntegerType::U8Type(type_) => &type_.span, - IntegerType::U16Type(type_) => &type_.span, - IntegerType::U32Type(type_) => &type_.span, - IntegerType::U64Type(type_) => &type_.span, - IntegerType::U128Type(type_) => &type_.span, - } - } -} - -impl<'ast> std::fmt::Display for IntegerType<'ast> { +impl std::fmt::Display for IntegerType { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { IntegerType::U8Type(_) => write!(f, "u8"), diff --git a/leo-inputs/src/types/type_.rs b/leo-inputs/src/types/type_.rs index 6bd33b3df1..a7a823ecab 100644 --- a/leo-inputs/src/types/type_.rs +++ b/leo-inputs/src/types/type_.rs @@ -6,7 +6,7 @@ use std::fmt; #[derive(Clone, Debug, FromPest, PartialEq)] #[pest_ast(rule(Rule::type_))] pub enum Type<'ast> { - Basic(DataType<'ast>), + Basic(DataType), Array(ArrayType<'ast>), } diff --git a/leo-inputs/src/values/field_value.rs b/leo-inputs/src/values/field_value.rs index cb88f4af66..fba97c8873 100644 --- a/leo-inputs/src/values/field_value.rs +++ b/leo-inputs/src/values/field_value.rs @@ -9,13 +9,13 @@ use std::fmt; #[pest_ast(rule(Rule::value_field))] pub struct FieldValue<'ast> { pub number: NumberValue<'ast>, - pub type_: FieldType<'ast>, + pub type_: FieldType, #[pest_ast(outer())] pub span: Span<'ast>, } impl<'ast> FieldValue<'ast> { - pub fn from_implicit(number: NumberImplicitValue<'ast>, type_: FieldType<'ast>) -> Self { + pub fn from_implicit(number: NumberImplicitValue<'ast>, type_: FieldType) -> Self { Self { number: number.number, type_, diff --git a/leo-inputs/src/values/group_value.rs b/leo-inputs/src/values/group_value.rs index 0fd6b3bfe7..da8a076576 100644 --- a/leo-inputs/src/values/group_value.rs +++ b/leo-inputs/src/values/group_value.rs @@ -8,7 +8,7 @@ use std::fmt; #[pest_ast(rule(Rule::value_group))] pub struct GroupValue<'ast> { pub value: GroupTuple<'ast>, - pub _type: GroupType<'ast>, + pub _type: GroupType, #[pest_ast(outer())] pub span: Span<'ast>, } diff --git a/leo-inputs/src/values/integer_value.rs b/leo-inputs/src/values/integer_value.rs index b04bc6274e..b627ecc05f 100644 --- a/leo-inputs/src/values/integer_value.rs +++ b/leo-inputs/src/values/integer_value.rs @@ -12,13 +12,13 @@ use std::fmt; #[pest_ast(rule(Rule::value_integer))] pub struct IntegerValue<'ast> { pub number: NumberValue<'ast>, - pub type_: IntegerType<'ast>, + pub type_: IntegerType, #[pest_ast(outer())] pub span: Span<'ast>, } impl<'ast> IntegerValue<'ast> { - pub fn from_implicit(number: NumberImplicitValue<'ast>, type_: IntegerType<'ast>) -> Self { + pub fn from_implicit(number: NumberImplicitValue<'ast>, type_: IntegerType) -> Self { Self { number: number.number, type_, diff --git a/types/src/common/identifier.rs b/types/src/common/identifier.rs index 62ece81746..4c7e0dca18 100644 --- a/types/src/common/identifier.rs +++ b/types/src/common/identifier.rs @@ -4,7 +4,7 @@ use leo_ast::common::Identifier as AstIdentifier; use std::fmt; /// An identifier in the constrained program. -#[derive(Clone, PartialEq, Eq, Hash)] +#[derive(Clone, Hash)] pub struct Identifier { pub name: String, pub span: Span, @@ -35,3 +35,11 @@ impl fmt::Debug for Identifier { write!(f, "{}", self.name) } } + +impl PartialEq for Identifier { + fn eq(&self, other: &Self) -> bool { + self.name == other.name + } +} + +impl Eq for Identifier {} diff --git a/types/src/inputs/input_value.rs b/types/src/inputs/input_value.rs index 53ad29424b..0a3521730f 100644 --- a/types/src/inputs/input_value.rs +++ b/types/src/inputs/input_value.rs @@ -2,67 +2,62 @@ use leo_inputs::{ errors::InputParserError, expressions::{ArrayInitializerExpression, ArrayInlineExpression, Expression}, types::{ArrayType, DataType, IntegerType, Type}, - values::{BooleanValue, FieldValue, GroupValue, NumberImplicitValue, Value}, + values::{BooleanValue, FieldValue, GroupValue, NumberImplicitValue, NumberValue, Value}, }; -use leo_inputs::values::IntegerValue; -use pest::Span; use std::fmt; -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum InputValue<'ast> { - Integer(IntegerValue<'ast>), - Field(FieldValue<'ast>), - Group(GroupValue<'ast>), - Boolean(BooleanValue<'ast>), - Array(Vec>), +#[derive(Clone, PartialEq, Eq)] +pub enum InputValue { + Integer(IntegerType, u128), + Field(String), + Group(String), + Boolean(bool), + Array(Vec), } -impl<'ast> InputValue<'ast> { - pub fn span(&self) -> &Span<'ast> { - match self { - InputValue::Integer(value) => &value.span, - InputValue::Field(value) => &value.span, - InputValue::Group(value) => &value.span, - InputValue::Boolean(value) => &value.span, - InputValue::Array(_) => unimplemented!(), // create new span from start and end - } +impl InputValue { + fn from_boolean(boolean: BooleanValue) -> Result { + let boolean = boolean.value.parse::()?; + Ok(InputValue::Boolean(boolean)) } - fn from_typed_integer( - integer_type: IntegerType<'ast>, - integer: IntegerValue<'ast>, - ) -> Result { - if integer_type != integer.type_ { - return Err(InputParserError::integer_type_mismatch(integer_type, integer)); - } - - Ok(InputValue::Integer(integer)) + fn from_number(integer_type: IntegerType, number: NumberValue) -> Result { + let integer = number.value.parse::()?; + Ok(InputValue::Integer(integer_type, integer)) } - fn from_implicit(data_type: DataType<'ast>, number: NumberImplicitValue<'ast>) -> Result { + fn from_group(group: GroupValue) -> Self { + InputValue::Group(group.to_string()) + } + + fn from_field(field: FieldValue) -> Self { + InputValue::Field(field.number.value) + } + + fn from_implicit(data_type: DataType, implicit: NumberImplicitValue) -> Result { match data_type { - DataType::Integer(type_) => Ok(InputValue::Integer(IntegerValue::from_implicit(number, type_))), - DataType::Field(type_) => Ok(InputValue::Field(FieldValue::from_implicit(number, type_))), - DataType::Boolean(_) => unimplemented!("cannot have an implicit boolean"), - DataType::Group(_) => unimplemented!("group inputs must be explicitly typed"), + DataType::Boolean(_) => Err(InputParserError::implicit_boolean(data_type, implicit)), + DataType::Integer(integer_type) => InputValue::from_number(integer_type, implicit.number), + DataType::Group(_) => Ok(InputValue::Group(implicit.number.value)), + DataType::Field(_) => Ok(InputValue::Field(implicit.number.value)), } } - fn from_value(data_type: DataType<'ast>, value: Value<'ast>) -> Result { + fn from_value(data_type: DataType, value: Value) -> Result { match (data_type, value) { - (DataType::Boolean(_), Value::Boolean(boolean)) => Ok(InputValue::Boolean(boolean)), + (DataType::Boolean(_), Value::Boolean(boolean)) => InputValue::from_boolean(boolean), (DataType::Integer(integer_type), Value::Integer(integer)) => { - Self::from_typed_integer(integer_type, integer) + InputValue::from_number(integer_type, integer.number) } - (DataType::Group(_), Value::Group(group)) => Ok(InputValue::Group(group)), - (DataType::Field(_), Value::Field(field)) => Ok(InputValue::Field(field)), - (data_type, Value::Implicit(number)) => InputValue::from_implicit(data_type, number), + (DataType::Group(_), Value::Group(group)) => Ok(InputValue::from_group(group)), + (DataType::Field(_), Value::Field(field)) => Ok(InputValue::from_field(field)), + (data_type, Value::Implicit(implicit)) => InputValue::from_implicit(data_type, implicit), (data_type, value) => Err(InputParserError::data_type_mismatch(data_type, value)), } } - pub(crate) fn from_expression(type_: Type<'ast>, expression: Expression<'ast>) -> Result { + pub(crate) fn from_expression(type_: Type, expression: Expression) -> Result { match (type_, expression) { (Type::Basic(data_type), Expression::Value(value)) => InputValue::from_value(data_type, value), (Type::Array(array_type), Expression::ArrayInline(inline)) => { @@ -76,15 +71,16 @@ impl<'ast> InputValue<'ast> { } pub(crate) fn from_array_inline( - mut array_type: ArrayType<'ast>, - inline: ArrayInlineExpression<'ast>, + mut array_type: ArrayType, + inline: ArrayInlineExpression, ) -> Result { if let Some(number) = array_type.next_dimension() { let outer_dimension = number.value.parse::()?; + if outer_dimension != inline.expressions.len() { return Err(InputParserError::array_inline_length(number, inline)); } - } + }; let inner_array_type = if array_type.dimensions.len() == 0 { // this is a single array @@ -104,8 +100,8 @@ impl<'ast> InputValue<'ast> { } pub(crate) fn from_array_initializer( - mut array_type: ArrayType<'ast>, - initializer: ArrayInitializerExpression<'ast>, + mut array_type: ArrayType, + initializer: ArrayInitializerExpression, ) -> Result { let initializer_count = initializer.count.value.parse::()?; @@ -135,11 +131,11 @@ impl<'ast> InputValue<'ast> { } } -impl<'ast> fmt::Display for InputValue<'ast> { +impl fmt::Display for InputValue { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { InputValue::Boolean(ref boolean) => write!(f, "{}", boolean), - InputValue::Integer(ref number) => write!(f, "{}", number), + InputValue::Integer(ref type_, ref number) => write!(f, "{}{:?}", number, type_), InputValue::Group(ref group) => write!(f, "{}", group), InputValue::Field(ref field) => write!(f, "{}", field), InputValue::Array(ref array) => { diff --git a/types/src/inputs/inputs.rs b/types/src/inputs/inputs.rs index adc00adba5..1d13e4d9ad 100644 --- a/types/src/inputs/inputs.rs +++ b/types/src/inputs/inputs.rs @@ -2,11 +2,11 @@ use crate::{FunctionInput, InputValue}; use leo_inputs::{files::File, InputParserError}; #[derive(Clone)] -pub struct Inputs<'ast> { - program_inputs: Vec>>, +pub struct Inputs { + program_inputs: Vec>, } -impl<'ast> Inputs<'ast> { +impl Inputs { pub fn new() -> Self { Self { program_inputs: vec![] } } @@ -15,7 +15,7 @@ impl<'ast> Inputs<'ast> { self.program_inputs.clone() } - pub fn set_inputs(&mut self, inputs: Vec>>) { + pub fn set_inputs(&mut self, inputs: Vec>) { self.program_inputs = inputs; } @@ -23,7 +23,7 @@ impl<'ast> Inputs<'ast> { self.program_inputs = vec![None; size]; } - pub fn from_inputs_file(file: File<'ast>, expected_inputs: Vec) -> Result { + pub fn from_inputs_file(file: File, expected_inputs: Vec) -> Result { let mut program_inputs = vec![]; for section in file.sections.into_iter() { diff --git a/types/src/integer.rs b/types/src/integer.rs index d86a78b477..4eece3ebb1 100644 --- a/types/src/integer.rs +++ b/types/src/integer.rs @@ -132,10 +132,8 @@ impl Integer { // Check that the input value is the correct type let option = match integer_value { Some(input) => { - if let InputValue::Integer(ast) = input { - let integer = ast.number.value.parse::()?; - - Some(integer) + if let InputValue::Integer(_type_, number) = input { + Some(number) } else { return Err(IntegerError::InvalidInteger(input.to_string())); }