mirror of
https://github.com/AleoHQ/leo.git
synced 2024-12-25 02:22:44 +03:00
support all combinations of nested and tuple array syntax. Test small and large arrays
This commit is contained in:
parent
b6dc77e112
commit
4932eb688e
@ -0,0 +1,2 @@
|
||||
[main]
|
||||
a: [[u8; 2]; 3] = [[0; 2]; 3];
|
@ -0,0 +1,2 @@
|
||||
[main]
|
||||
a: [[u8; 2]; 3] = [[0; 3]; 2]; // See `type_nested_value_nested_3x2.in` for correct dimensions
|
@ -0,0 +1,2 @@
|
||||
[main]
|
||||
a: [[[u8; 2]; 3]; 4] = [[[0; 2]; 3]; 4];
|
@ -0,0 +1,2 @@
|
||||
[main]
|
||||
a: [[[u8; 2]; 3]; 4] = [[[0; 4]; 3]; 2]; // See `type_nested_value_nested_4x3x2.in` for correct dimensions
|
@ -0,0 +1,2 @@
|
||||
[main]
|
||||
a: [[u8; 2]; 3] = [0; (3, 2)];
|
@ -0,0 +1,2 @@
|
||||
[main]
|
||||
a: [[u8; 2]; 3] = [0; (2, 3)]; // See `type_nested_value_tuple_3x2.in` for correct dimensions
|
@ -0,0 +1,2 @@
|
||||
[main]
|
||||
a: [[[u8; 2]; 3]; 4] = [0; (4, 3, 2)];
|
@ -0,0 +1,2 @@
|
||||
[main]
|
||||
a: [[[u8; 2]; 3]; 4] = [0; (2, 3, 4)]; // See `type_nested_value_tuple_4x3x2.in` for correct dimensions
|
@ -0,0 +1,2 @@
|
||||
[main]
|
||||
a: [u8; (3, 2)] = [[0; 2]; 3];
|
@ -0,0 +1,2 @@
|
||||
[main]
|
||||
a: [u8; (3, 2)] = [[0; 3]; 2]; // See `type_tuple_value_nested_3x2.in` for correct dimensions
|
@ -0,0 +1,2 @@
|
||||
[main]
|
||||
a: [u8; (4, 3, 2)] = [[[0; 2]; 3]; 4];
|
@ -0,0 +1,2 @@
|
||||
[main]
|
||||
a: [u8; (4, 3, 2)] = [[[0; 4]; 3]; 2]; // See `type_tuple_value_nested_4x3x2.in` for correct dimensions
|
2
compiler/tests/array/input/type_tuple_value_tuple_3x2.in
Normal file
2
compiler/tests/array/input/type_tuple_value_tuple_3x2.in
Normal file
@ -0,0 +1,2 @@
|
||||
[main]
|
||||
a: [u8; (3, 2)] = [0; (3, 2)];
|
@ -0,0 +1,2 @@
|
||||
[main]
|
||||
a: [u8; (3, 2)] = [0; (2, 3)]; // See `type_tuple_value_tuple_3x2.in` for correct dimensions
|
@ -0,0 +1,2 @@
|
||||
[main]
|
||||
a: [u8; (4, 3, 2)] = [0; (4, 3, 2)];
|
@ -0,0 +1,2 @@
|
||||
[main]
|
||||
a: [u8; (4, 3, 2)] = [0; (2, 3, 4)]; // See `type_tuple_value_tuple_4x3x2.in` for correct dimensions
|
@ -58,39 +58,6 @@ fn test_registers() {
|
||||
|
||||
// Expressions
|
||||
|
||||
#[test]
|
||||
fn test_type_fail() {
|
||||
let program_bytes = include_bytes!("type_fail.leo");
|
||||
let syntax_error = parse_program(program_bytes).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_type_tuple() {
|
||||
let program_bytes = include_bytes!("type_tuple.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn test_type_tuple_input() {
|
||||
// let program_bytes = include_bytes!("type_tuple_input.leo");
|
||||
// let input_bytes = include_bytes!("input/input_nested_3x2.in");
|
||||
// let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
//
|
||||
// assert_satisfied(program);
|
||||
// }
|
||||
|
||||
#[test]
|
||||
fn test_type_nested() {
|
||||
let program_bytes = include_bytes!("type_nested.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inline() {
|
||||
let program_bytes = include_bytes!("inline.leo");
|
||||
@ -261,3 +228,177 @@ fn test_slice() {
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
// Array type tests
|
||||
|
||||
#[test]
|
||||
fn test_type_fail() {
|
||||
let program_bytes = include_bytes!("type_fail.leo");
|
||||
let syntax_error = parse_program(program_bytes).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_type_tuple() {
|
||||
let program_bytes = include_bytes!("type_tuple.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_type_nested() {
|
||||
let program_bytes = include_bytes!("type_nested.leo");
|
||||
let program = parse_program(program_bytes).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
// Tests for nested multi-dimensional arrays as input to the program
|
||||
|
||||
#[test]
|
||||
fn test_input_type_nested_value_nested_3x2() {
|
||||
let program_bytes = include_bytes!("type_input_3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_nested_value_nested_3x2.in");
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_type_nested_value_nested_3x2_fail() {
|
||||
let program_bytes = include_bytes!("type_input_3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_nested_value_nested_3x2_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_bytes, input_bytes).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_type_nested_value_nested_4x3x2() {
|
||||
let program_bytes = include_bytes!("type_input_4x3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_nested_value_nested_4x3x2.in");
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_type_nested_value_nested_4x3x2_fail() {
|
||||
let program_bytes = include_bytes!("type_input_4x3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_nested_value_nested_4x3x2_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_bytes, input_bytes).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_type_nested_value_tuple_3x2() {
|
||||
let program_bytes = include_bytes!("type_input_3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_nested_value_tuple_3x2.in");
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_type_nested_value_tuple_3x2_fail() {
|
||||
let program_bytes = include_bytes!("type_input_3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_nested_value_tuple_3x2_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_bytes, input_bytes).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_type_nested_value_tuple_4x3x2() {
|
||||
let program_bytes = include_bytes!("type_input_4x3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_nested_value_tuple_4x3x2.in");
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
|
||||
assert_satisfied(program)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_type_nested_value_tuple_4x3x2_fail() {
|
||||
let program_bytes = include_bytes!("type_input_4x3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_nested_value_tuple_4x3x2_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_bytes, input_bytes).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
// Tests for multi-dimensional arrays using tuple syntax as input to the program
|
||||
|
||||
#[test]
|
||||
fn test_input_type_tuple_value_nested_3x2() {
|
||||
let program_bytes = include_bytes!("type_input_3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_tuple_value_nested_3x2.in");
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_type_tuple_value_nested_3x2_fail() {
|
||||
let program_bytes = include_bytes!("type_input_3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_tuple_value_nested_3x2_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_bytes, input_bytes).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_type_tuple_value_nested_4x3x2() {
|
||||
let program_bytes = include_bytes!("type_input_4x3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_tuple_value_nested_4x3x2.in");
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_type_tuple_value_nested_4x3x2_fail() {
|
||||
let program_bytes = include_bytes!("type_input_4x3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_tuple_value_nested_4x3x2_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_bytes, input_bytes).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_type_tuple_value_tuple_3x2() {
|
||||
let program_bytes = include_bytes!("type_input_3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_tuple_value_tuple_3x2.in");
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_type_tuple_value_tuple_3x2_fail() {
|
||||
let program_bytes = include_bytes!("type_input_3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_tuple_value_tuple_3x2_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_bytes, input_bytes).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_type_tuple_value_tuple_4x3x2() {
|
||||
let program_bytes = include_bytes!("type_input_4x3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_tuple_value_tuple_4x3x2.in");
|
||||
let program = parse_program_with_input(program_bytes, input_bytes).unwrap();
|
||||
|
||||
assert_satisfied(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_type_tuple_value_tuple_4x3x2_fail() {
|
||||
let program_bytes = include_bytes!("type_input_4x3x2.leo");
|
||||
let input_bytes = include_bytes!("input/type_tuple_value_tuple_4x3x2_fail.in");
|
||||
let syntax_error = parse_program_with_input(program_bytes, input_bytes).is_err();
|
||||
|
||||
assert!(syntax_error);
|
||||
}
|
||||
|
5
compiler/tests/array/type_input_3x2.leo
Normal file
5
compiler/tests/array/type_input_3x2.leo
Normal file
@ -0,0 +1,5 @@
|
||||
function main(a: [[u8; 2]; 3]) {
|
||||
const b = [[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]]; // inline
|
||||
|
||||
console.assert(a == b);
|
||||
}
|
8
compiler/tests/array/type_input_4x3x2.leo
Normal file
8
compiler/tests/array/type_input_4x3x2.leo
Normal file
@ -0,0 +1,8 @@
|
||||
function main(a: [[[u8; 2]; 3]; 4]) {
|
||||
const b = [[[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]],
|
||||
[[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]],
|
||||
[[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]],
|
||||
[[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]]]; // inline
|
||||
|
||||
console.assert(a == b);
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
function main(a: [u8; (2, 3)) {
|
||||
let b: [u8; (2, 3)] = [[0; 3]; 2];
|
||||
|
||||
console.assert(a == b);
|
||||
}
|
@ -59,6 +59,13 @@ impl<'ast> ArrayDimensions<'ast> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
match self {
|
||||
ArrayDimensions::Single(_) => false,
|
||||
ArrayDimensions::Multiple(multiple) => multiple.numbers.is_empty(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> std::fmt::Display for ArrayDimensions<'ast> {
|
||||
|
@ -137,27 +137,38 @@ impl InputValue {
|
||||
array_type: ArrayType,
|
||||
initializer: ArrayInitializerExpression,
|
||||
) -> Result<Self, InputParserError> {
|
||||
let array_dimensions = TypedExpression::get_input_array_dimensions(array_type.dimensions.clone());
|
||||
let initializer_dimensions = TypedExpression::get_input_array_dimensions(initializer.dimensions.clone());
|
||||
|
||||
if array_dimensions.eq(&initializer_dimensions) {
|
||||
if initializer_dimensions.len() > 1 {
|
||||
// The expression is an array initializer with tuple syntax
|
||||
Self::from_array_initializer_tuple(array_type, initializer, initializer_dimensions)
|
||||
} else {
|
||||
// The expression is an array initializer with nested syntax
|
||||
Self::from_array_initializer_nested(array_type, initializer, array_dimensions, initializer_dimensions)
|
||||
Self::from_array_initializer_nested(array_type, initializer, initializer_dimensions)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn from_array_initializer_tuple(
|
||||
array_type: ArrayType,
|
||||
initializer: ArrayInitializerExpression,
|
||||
dimensions: Vec<usize>,
|
||||
initializer_dimensions: Vec<usize>,
|
||||
) -> Result<Self, InputParserError> {
|
||||
let value = InputValue::from_expression(*array_type.type_, *initializer.expression.clone())?;
|
||||
let (array_dimensions, array_element_type) = fetch_nested_array_type_dimensions(array_type.clone(), vec![]);
|
||||
|
||||
// Return an error if the dimensions of the array are incorrect.
|
||||
if array_dimensions.ne(&initializer_dimensions) {
|
||||
return Err(InputParserError::array_init_length(
|
||||
array_dimensions,
|
||||
initializer_dimensions,
|
||||
initializer.span,
|
||||
));
|
||||
}
|
||||
|
||||
let value = InputValue::from_expression(array_element_type, *initializer.expression.clone())?;
|
||||
let mut elements = vec![];
|
||||
|
||||
for (i, dimension) in dimensions.into_iter().enumerate() {
|
||||
// Build the elements of the array using the `vec!` macro
|
||||
for (i, dimension) in initializer_dimensions.into_iter().enumerate() {
|
||||
if i == 0 {
|
||||
elements = vec![value.clone(); dimension];
|
||||
} else {
|
||||
@ -173,9 +184,10 @@ impl InputValue {
|
||||
pub(crate) fn from_array_initializer_nested(
|
||||
mut array_type: ArrayType,
|
||||
initializer: ArrayInitializerExpression,
|
||||
array_dimensions: Vec<usize>,
|
||||
initializer_dimensions: Vec<usize>,
|
||||
) -> Result<Self, InputParserError> {
|
||||
let array_dimensions = TypedExpression::get_input_array_dimensions(array_type.dimensions.clone());
|
||||
|
||||
let current_array_dimension = array_dimensions[0];
|
||||
let current_initializer_dimension = initializer_dimensions[0];
|
||||
|
||||
@ -228,6 +240,17 @@ impl InputValue {
|
||||
}
|
||||
}
|
||||
|
||||
// Recursively fetch all dimensions from the array type
|
||||
fn fetch_nested_array_type_dimensions(array_type: ArrayType, mut array_dimensions: Vec<usize>) -> (Vec<usize>, Type) {
|
||||
let mut current_dimension = TypedExpression::get_input_array_dimensions(array_type.dimensions);
|
||||
array_dimensions.append(&mut current_dimension);
|
||||
|
||||
match *array_type.type_ {
|
||||
Type::Array(next_array_type) => fetch_nested_array_type_dimensions(next_array_type, array_dimensions),
|
||||
type_ => (array_dimensions, type_),
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for InputValue {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
|
Loading…
Reference in New Issue
Block a user