convert leo-inputs to span with errors. fix tests

This commit is contained in:
collin 2020-06-19 23:02:58 -07:00
parent 2743b23e1e
commit 82a0afc17e
31 changed files with 327 additions and 353 deletions

View File

@ -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<F>> {
pub struct Compiler<F: Field + PrimeField, G: GroupType<F>> {
package_name: String,
main_file_path: PathBuf,
program: Program,
program_inputs: Inputs<'ast>,
program_inputs: Inputs,
output: Option<ConstrainedValue<F, G>>,
_engine: PhantomData<F>,
}
impl<'ast, F: Field + PrimeField, G: GroupType<F>> Compiler<'ast, F, G> {
impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
pub fn new() -> Self {
Self {
package_name: "".to_string(),
@ -57,7 +57,7 @@ impl<'ast, F: Field + PrimeField, G: GroupType<F>> Compiler<'ast, F, G> {
Ok(program)
}
pub fn set_inputs(&mut self, program_inputs: Vec<Option<InputValue<'ast>>>) {
pub fn set_inputs(&mut self, program_inputs: Vec<Option<InputValue>>) {
self.program_inputs.set_inputs(program_inputs);
}
@ -105,7 +105,7 @@ impl<'ast, F: Field + PrimeField, G: GroupType<F>> 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<F>> Compiler<'ast, F, G> {
}
}
impl<'ast, F: Field + PrimeField, G: GroupType<F>> ConstraintSynthesizer<F> for Compiler<'ast, F, G> {
impl<F: Field + PrimeField, G: GroupType<F>> ConstraintSynthesizer<F> for Compiler<F, G> {
fn generate_constraints<CS: ConstraintSystem<F>>(self, cs: &mut CS) -> Result<(), SynthesisError> {
let _result =
generate_constraints::<_, G, _>(cs, self.program, self.program_inputs.get_inputs()).map_err(|e| {

View File

@ -26,12 +26,10 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
// 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::<bool>()?;
if let InputValue::Boolean(bool) = input {
Some(bool)
} else {
return Err(BooleanError::from(input));
return Err(BooleanError::SynthesisError(SynthesisError::AssignmentMissing));
}
}
None => None,

View File

@ -17,8 +17,8 @@ pub(crate) fn field_from_input<F: Field + PrimeField, G: GroupType<F>, 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()));
}

View File

@ -15,8 +15,8 @@ pub(crate) fn group_from_input<F: Field + PrimeField, G: GroupType<F>, 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()));
}

View File

@ -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<InputValue<'ast>> 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))
}
}

View File

@ -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),
}
}

View File

@ -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);
}

View File

@ -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);
// }

View File

@ -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
}
let input: bool[512] = [true; 512];
return pedersen.hash(input)
}

View File

@ -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),

View File

@ -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;

View File

@ -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<Fq, EdwardsGroupType>;
pub type EdwardsConstrainedValue = ConstrainedValue<Fq, EdwardsGroupType>;
pub(crate) fn get_output(program: EdwardsTestCompiler) -> EdwardsConstrainedValue {
@ -60,27 +54,12 @@ pub(crate) fn parse_program(bytes: &[u8]) -> Result<EdwardsTestCompiler, Compile
Ok(compiler)
}
// pub(crate) fn parse_inputs(bytes: &[u8]) -> 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<EdwardsTestCompiler, CompilerError> {
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)
}

View File

@ -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),
}
}

View File

@ -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;

View File

@ -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::<Fq>::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::<Fq>::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::<Fq>::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::<Fq>::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() {

View File

@ -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"),
}
}

View File

@ -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)
}
}

View File

@ -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<NumberValue<'ast>>,
#[pest_ast(outer())]
pub span: Span<'ast>,

View File

@ -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 {}

View File

@ -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),

View File

@ -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 {}

View File

@ -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 {}

View File

@ -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"),

View File

@ -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>),
}

View File

@ -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_,

View File

@ -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>,
}

View File

@ -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_,

View File

@ -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 {}

View File

@ -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<InputValue<'ast>>),
#[derive(Clone, PartialEq, Eq)]
pub enum InputValue {
Integer(IntegerType, u128),
Field(String),
Group(String),
Boolean(bool),
Array(Vec<InputValue>),
}
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<Self, InputParserError> {
let boolean = boolean.value.parse::<bool>()?;
Ok(InputValue::Boolean(boolean))
}
fn from_typed_integer(
integer_type: IntegerType<'ast>,
integer: IntegerValue<'ast>,
) -> Result<Self, InputParserError> {
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<Self, InputParserError> {
let integer = number.value.parse::<u128>()?;
Ok(InputValue::Integer(integer_type, integer))
}
fn from_implicit(data_type: DataType<'ast>, number: NumberImplicitValue<'ast>) -> Result<Self, InputParserError> {
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<Self, InputParserError> {
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<Self, InputParserError> {
fn from_value(data_type: DataType, value: Value) -> Result<Self, InputParserError> {
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<Self, InputParserError> {
pub(crate) fn from_expression(type_: Type, expression: Expression) -> Result<Self, InputParserError> {
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<Self, InputParserError> {
if let Some(number) = array_type.next_dimension() {
let outer_dimension = number.value.parse::<usize>()?;
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<Self, InputParserError> {
let initializer_count = initializer.count.value.parse::<usize>()?;
@ -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) => {

View File

@ -2,11 +2,11 @@ use crate::{FunctionInput, InputValue};
use leo_inputs::{files::File, InputParserError};
#[derive(Clone)]
pub struct Inputs<'ast> {
program_inputs: Vec<Option<InputValue<'ast>>>,
pub struct Inputs {
program_inputs: Vec<Option<InputValue>>,
}
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<Option<InputValue<'ast>>>) {
pub fn set_inputs(&mut self, inputs: Vec<Option<InputValue>>) {
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<FunctionInput>) -> Result<Self, InputParserError> {
pub fn from_inputs_file(file: File, expected_inputs: Vec<FunctionInput>) -> Result<Self, InputParserError> {
let mut program_inputs = vec![];
for section in file.sections.into_iter() {

View File

@ -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::<u128>()?;
Some(integer)
if let InputValue::Integer(_type_, number) = input {
Some(number)
} else {
return Err(IntegerError::InvalidInteger(input.to_string()));
}