mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-30 13:42:24 +03:00
input, output and compiler tests
This commit is contained in:
parent
0ef7ca3d8e
commit
29cd920075
@ -38,7 +38,7 @@ use std::fmt;
|
||||
pub enum InputValue {
|
||||
Address(String),
|
||||
Boolean(bool),
|
||||
Char(String),
|
||||
Char(char),
|
||||
Field(String),
|
||||
Group(GroupValue),
|
||||
Integer(IntegerType, String),
|
||||
@ -63,8 +63,9 @@ impl InputValue {
|
||||
Ok(InputValue::Boolean(boolean))
|
||||
}
|
||||
|
||||
fn from_char(character: CharValue) -> Self {
|
||||
InputValue::Char(character.value)
|
||||
fn from_char(character: CharValue) -> Result<Self, InputParserError> {
|
||||
let character = character.value.inner()?;
|
||||
Ok(InputValue::Char(character))
|
||||
}
|
||||
|
||||
fn from_number(integer_type: IntegerType, number: String) -> Self {
|
||||
@ -94,7 +95,7 @@ impl InputValue {
|
||||
match (data_type, value) {
|
||||
(DataType::Address(_), Value::Address(address)) => Ok(InputValue::from_address_value(address)),
|
||||
(DataType::Boolean(_), Value::Boolean(boolean)) => InputValue::from_boolean(boolean),
|
||||
(DataType::Char(_), Value::Char(character)) => Ok(InputValue::from_char(character)),
|
||||
(DataType::Char(_), Value::Char(character)) => InputValue::from_char(character),
|
||||
(DataType::Integer(integer_type), Value::Integer(integer)) => {
|
||||
Ok(InputValue::from_number(integer_type, integer.to_string()))
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
use crate::{
|
||||
address::Address,
|
||||
errors::{CharError, FunctionError},
|
||||
errors::FunctionError,
|
||||
program::ConstrainedProgram,
|
||||
value::{
|
||||
boolean::input::bool_from_input,
|
||||
@ -83,17 +83,11 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
match (type_, input) {
|
||||
(Type::Address, InputValue::Address(addr)) => Ok(ConstrainedValue::Address(Address::constant(addr, span)?)),
|
||||
(Type::Boolean, InputValue::Boolean(value)) => Ok(ConstrainedValue::Boolean(Boolean::constant(value))),
|
||||
(Type::Char, InputValue::Char(value)) => {
|
||||
if let Some(character) = value.chars().nth(1) {
|
||||
Ok(ConstrainedValue::Char(Char::constant(
|
||||
(Type::Char, InputValue::Char(character)) => Ok(ConstrainedValue::Char(Char::constant(
|
||||
character,
|
||||
format!("{}", character as u32),
|
||||
span,
|
||||
)?))
|
||||
} else {
|
||||
Err(FunctionError::from(CharError::invalid_char(value, span)))
|
||||
}
|
||||
}
|
||||
)?)),
|
||||
(Type::Field, InputValue::Field(value)) => Ok(ConstrainedValue::Field(FieldType::constant(value, span)?)),
|
||||
(Type::Group, InputValue::Group(value)) => Ok(ConstrainedValue::Group(G::constant(&value.into(), span)?)),
|
||||
(Type::Integer(integer_type), InputValue::Integer(_, value)) => Ok(ConstrainedValue::Integer(
|
||||
|
@ -50,12 +50,8 @@ pub(crate) fn char_from_input<'a, F: PrimeField, G: GroupType<F>, CS: Constraint
|
||||
// Check that the parameter value is the correct type
|
||||
let option = match input_value {
|
||||
Some(input) => {
|
||||
if let InputValue::Char(string) = input {
|
||||
if let Some(character) = string.chars().nth(1) {
|
||||
if let InputValue::Char(character) = input {
|
||||
(character, Some((character as u32).to_string()))
|
||||
} else {
|
||||
return Err(CharError::invalid_char(string, span));
|
||||
}
|
||||
} else {
|
||||
return Err(CharError::invalid_char(input.to_string(), span));
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
circuit Foo {
|
||||
a: char;
|
||||
b: char;
|
||||
c: char;
|
||||
}
|
||||
|
||||
function main() {
|
||||
const f = Foo { a: 'a' };
|
||||
function main(a: char, b: char, c: char) {
|
||||
let f = Foo { a, b, c };
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
[main]
|
||||
a: char = '\u{2764}';
|
||||
b: char = 'a';
|
||||
a: char = 'a';
|
||||
b: char = '\'';
|
||||
c: char = '\u{2764}';
|
@ -1,2 +1,2 @@
|
||||
[registers]
|
||||
r: char = '\n';
|
||||
r: char = 'a';
|
@ -14,13 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{
|
||||
assert_satisfied,
|
||||
get_output,
|
||||
parse_program,
|
||||
parse_program_with_input,
|
||||
EdwardsTestCompiler,
|
||||
};
|
||||
use crate::{assert_satisfied, get_output, parse_program, parse_program_with_input, EdwardsTestCompiler};
|
||||
|
||||
pub fn output_char(program: EdwardsTestCompiler) {
|
||||
let expected = include_bytes!("output/output_char.out");
|
||||
@ -29,26 +23,6 @@ pub fn output_char(program: EdwardsTestCompiler) {
|
||||
assert_eq!(expected, actual.bytes().as_slice());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_pass() {
|
||||
let program_string = include_str!("input.leo");
|
||||
let input_string = include_str!("input/char.in");
|
||||
|
||||
let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn test_input_fail() {
|
||||
// let program_string = include_str!("assert_eq_input.leo");
|
||||
// let input_string = include_str!("input/true_false.in");
|
||||
|
||||
// let program = parse_program_with_input(program_string, input_string).unwrap();
|
||||
|
||||
// expect_compiler_error(program);
|
||||
// }
|
||||
|
||||
#[test]
|
||||
fn test_registers() {
|
||||
let program_string = include_str!("output_register.leo");
|
||||
@ -94,8 +68,10 @@ fn test_function() {
|
||||
|
||||
#[test]
|
||||
fn test_circuit() {
|
||||
let program_string = include_str!("function.leo");
|
||||
let program = parse_program(program_string).unwrap();
|
||||
let program_string = include_str!("circuit.leo");
|
||||
let char_input_string = include_str!("input/char.in");
|
||||
|
||||
let program = parse_program_with_input(program_string, char_input_string).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
@ -1,2 +1,2 @@
|
||||
[registers]
|
||||
r: char = '\n';
|
||||
r: char = a;
|
||||
|
@ -83,6 +83,12 @@ impl InputParserError {
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn invalid_char(character: String, span: &Span) -> Self {
|
||||
let message = format!("Expected valid character found `{}`", character);
|
||||
|
||||
Self::new_from_span(message, span)
|
||||
}
|
||||
|
||||
pub fn implicit_type(data_type: DataType, implicit: NumberValue) -> Self {
|
||||
let message = format!("expected `{}`, found `{}`", data_type, implicit);
|
||||
|
||||
|
@ -133,17 +133,19 @@ number_negative = @{ "-" ~ ASCII_DIGIT+ }
|
||||
// Declared in values/number_positive.rs
|
||||
number_positive = @{ ASCII_DIGIT+ }
|
||||
|
||||
|
||||
// Decalred in values/char_types.rs
|
||||
// ANY is equivalent to '\u{00}'..'\u{10FFFF}'
|
||||
basic_char = { ANY }
|
||||
escaped_char = @{ "\\" ~ ("\"" | "\'" | "\\" | "/" | "b" | "f" | "n" | "r" | "t") }
|
||||
hex_char = @{ "\\" ~ "u" ~ "{" ~ ASCII_HEX_DIGIT{4} ~ "}" }
|
||||
char_types = {
|
||||
escaped_char
|
||||
| hex_char
|
||||
| basic_char
|
||||
}
|
||||
|
||||
// Declared in values/char_value.rs
|
||||
// ANY is equivalent to '\u{00}'..'\u{10FFFF}'
|
||||
// TODO FIX
|
||||
// value_char = {
|
||||
// !("\'" | "\\") ~ ANY
|
||||
// | "\\" ~ ("\"" | "\'" | "\\" | "/" | "b" | "f" | "n" | "r" | "t")
|
||||
// | "\\" ~ ("u" ~ ASCII_HEX_DIGIT(4))
|
||||
// }
|
||||
value_char = { "'" ~ "\\"? ~ ANY ~ "'" }
|
||||
value_char = { "\'" ~ char_types ~ "\'" }
|
||||
|
||||
// Declared in values/integer_value.rs
|
||||
value_integer = { value_integer_signed | value_integer_unsigned}
|
||||
|
89
input/src/values/char_types.rs
Normal file
89
input/src/values/char_types.rs
Normal file
@ -0,0 +1,89 @@
|
||||
// Copyright (C) 2019-2021 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{
|
||||
ast::{span_into_string, Rule},
|
||||
errors::InputParserError,
|
||||
};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq, Eq)]
|
||||
#[pest_ast(rule(Rule::basic_char))]
|
||||
pub struct BasicChar<'ast> {
|
||||
#[pest_ast(outer(with(span_into_string)))]
|
||||
pub value: String,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq, Eq)]
|
||||
#[pest_ast(rule(Rule::escaped_char))]
|
||||
pub struct EscapedChar<'ast> {
|
||||
#[pest_ast(outer(with(span_into_string)))]
|
||||
pub value: String,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq, Eq)]
|
||||
#[pest_ast(rule(Rule::hex_char))]
|
||||
pub struct HexChar<'ast> {
|
||||
#[pest_ast(outer(with(span_into_string)))]
|
||||
pub value: String,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq, Eq)]
|
||||
#[pest_ast(rule(Rule::char_types))]
|
||||
pub enum CharTypes<'ast> {
|
||||
Basic(BasicChar<'ast>),
|
||||
Escaped(EscapedChar<'ast>),
|
||||
Hex(HexChar<'ast>),
|
||||
}
|
||||
|
||||
impl<'ast> CharTypes<'ast> {
|
||||
pub fn inner(self) -> Result<char, InputParserError> {
|
||||
match self {
|
||||
Self::Basic(character) => {
|
||||
if let Some(character) = character.value.chars().next() {
|
||||
return Ok(character);
|
||||
}
|
||||
|
||||
Err(InputParserError::invalid_char(character.value, &character.span))
|
||||
}
|
||||
Self::Escaped(character) => {
|
||||
if let Some(character) = character.value.chars().nth(1) {
|
||||
return Ok(character);
|
||||
}
|
||||
|
||||
Err(InputParserError::invalid_char(character.value, &character.span))
|
||||
}
|
||||
Self::Hex(character) => {
|
||||
let hex_string_number = character.value[3..=6].to_string();
|
||||
if let Ok(hex) = u32::from_str_radix(&hex_string_number, 16) {
|
||||
if let Some(unicode) = std::char::from_u32(hex) {
|
||||
return Ok(unicode);
|
||||
}
|
||||
}
|
||||
|
||||
Err(InputParserError::invalid_char(character.value, &character.span))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::ast::{span_into_string, Rule};
|
||||
use crate::{ast::Rule, values::CharTypes};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
@ -23,14 +23,13 @@ use std::fmt;
|
||||
#[derive(Clone, Debug, FromPest, PartialEq, Eq)]
|
||||
#[pest_ast(rule(Rule::value_char))]
|
||||
pub struct CharValue<'ast> {
|
||||
#[pest_ast(outer(with(span_into_string)))]
|
||||
pub value: String,
|
||||
pub value: CharTypes<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for CharValue<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.value)
|
||||
write!(f, "{:?}", self.value)
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,9 @@ pub use address_value::*;
|
||||
pub mod boolean_value;
|
||||
pub use boolean_value::*;
|
||||
|
||||
pub mod char_types;
|
||||
pub use char_types::*;
|
||||
|
||||
pub mod char_value;
|
||||
pub use char_value::*;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user