Add tests and fixes

This commit is contained in:
Pranav Gaddamadugu 2023-10-17 15:30:19 -04:00 committed by Pranav Gaddamadugu
parent 0dcd156513
commit b3c1723d5c
15 changed files with 207 additions and 28 deletions

View File

@ -292,13 +292,12 @@ impl<'a> CodeGenerator<'a> {
// Note that this unwrap is safe since all struct and records have been added to the composite mapping.
let (is_record, _) = self.composite_mapping.get(&identifier.name).unwrap();
match is_record {
// If the type is a record, then declare the type as is.
// If the type is a struct, then add the public modifier.
false => format!("{identifier}.public"),
false => self.visit_type_with_visibility(type_, Mode::Public),
true => unreachable!("Type checking guarantees that mappings cannot contain records."),
}
}
type_ => format!("{type_}.public"),
type_ => self.visit_type_with_visibility(type_, Mode::Public),
}
};

View File

@ -73,25 +73,26 @@ impl ExpressionReconstructor for Flattener<'_> {
match (*input.if_true, *input.if_false) {
// If both expressions are identifiers which are arrays, construct ternary expressions for each of the members and an array expression for the result.
(Expression::Identifier(first), Expression::Identifier(second)) => {
match (self.type_table.get(&first.id()), self.type_table.get(&second.id())) {
(Some(Type::Array(first_type)), Some(Type::Array(second_type))) => {
// Note that type checking guarantees that both expressions have the same same type. This is a sanity check.
assert_eq!(first_type, second_type);
self.ternary_array(&first_type, &input.condition, &first, &second)
}
(Some(Type::Identifier(first_type)), Some(Type::Identifier(second_type))) => {
let first_type = match self.type_table.get(&first.id()) {
Some(first_type) => first_type,
_ => unreachable!("Type checking guarantees that all expressions are typed."),
};
let second_type = match self.type_table.get(&second.id()) {
Some(second_type) => second_type,
_ => unreachable!("Type checking guarantees that all expressions are typed."),
};
// Note that type checking guarantees that both expressions have the same same type. This is a sanity check.
assert!(first_type.eq_flat(&second_type));
match &first_type {
Type::Array(first_type) => self.ternary_array(&first_type, &input.condition, &first, &second),
Type::Identifier(first_type) => {
// Get the struct definitions.
let first_type = self.symbol_table.lookup_struct(first_type.name).unwrap();
let second_type = self.symbol_table.lookup_struct(second_type.name).unwrap();
// Note that type checking guarantees that both expressions have the same same type. This is a sanity check.
assert_eq!(first_type, second_type);
self.ternary_struct(first_type, &input.condition, &first, &second)
}
(Some(Type::Tuple(first_type)), Some(Type::Tuple(second_type))) => {
// Note that type checking guarantees that both expressions have the same same type. This is a sanity check.
assert_eq!(first_type, second_type);
self.ternary_tuple(&first_type, &input.condition, &first, &second)
self.ternary_struct(&first_type, &input.condition, &first, &second)
}
Type::Tuple(first_type) => self.ternary_tuple(&first_type, &input.condition, &first, &second),
_ => {
// Reconstruct the true case.
let (if_true, stmts) = self.reconstruct_expression(Expression::Identifier(first));
@ -117,9 +118,7 @@ impl ExpressionReconstructor for Flattener<'_> {
}
}
}
(expr1, expr2) => {
println!("expr1: {:?}", expr1);
println!("expr2: {:?}", expr2);
_ => {
unreachable!("SSA guarantees that the subexpressions of a ternary expression are identifiers.")
}
}

View File

@ -18,6 +18,7 @@ use crate::StaticSingleAssigner;
use leo_ast::{
AccessExpression,
ArrayAccess,
ArrayExpression,
AssociatedFunction,
BinaryExpression,
@ -101,6 +102,19 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
statements,
)
}
AccessExpression::Array(input) => {
let (array, statements) = self.consume_expression(*input.array);
(
AccessExpression::Array(ArrayAccess {
array: Box::new(array),
index: input.index,
span: input.span,
id: input.id,
}),
statements,
)
}
expr => (expr, Vec::new()),
};
let (place, statement) = self.unique_simple_assign_statement(Expression::Access(expr));

View File

@ -555,7 +555,7 @@ impl<'a> ExpressionVisitor<'a> for TypeChecker<'a> {
// Assert right type is a magnitude (u8, u16, u32).
self.assert_magnitude_type(&t2, input.right.span());
return_incorrect_type(t1, t2, destination)
t1
}
}
}

View File

@ -7,10 +7,10 @@ outputs:
unrolled_symbol_table: ada5f23ac25bb1d9459045c27095fce0e36e746d84ca57cd7499c322773aa334
initial_ast: efb843c1ad9ab3c9702e6a7371a6d82ee7cee6a9373cb50f6dfc2a73e7de5336
unrolled_ast: efb843c1ad9ab3c9702e6a7371a6d82ee7cee6a9373cb50f6dfc2a73e7de5336
ssa_ast: 3ce96d3ff2764de26ca950390ed39d4ef11257f7c254ea4b9843f99f75607f6f
flattened_ast: b204db3b8936f01d4d8c157ceda34c5de887d622b5c4cce307dba772e2f9fa31
destructured_ast: b4f45fe4b1d71e31f8e2b6354a8c7239ecdb6129e40b81c634e1e75ac0cc70e3
inlined_ast: b4f45fe4b1d71e31f8e2b6354a8c7239ecdb6129e40b81c634e1e75ac0cc70e3
dce_ast: b4f45fe4b1d71e31f8e2b6354a8c7239ecdb6129e40b81c634e1e75ac0cc70e3
ssa_ast: 23b7fcac156b953db56e1c45fc27570a2156499fd9b7f6e77ceb04f33fc99fac
flattened_ast: 0be4a04e516edc0a6729fcd364cb393ccf181d9c21e24aa57c284ff87763686f
destructured_ast: 9df17c7ff4d181afd738c449f79119bcbb10519b07441fb45dcb6d0b93c8f80d
inlined_ast: 9df17c7ff4d181afd738c449f79119bcbb10519b07441fb45dcb6d0b93c8f80d
dce_ast: 9df17c7ff4d181afd738c449f79119bcbb10519b07441fb45dcb6d0b93c8f80d
bytecode: a3539a0515c22f4ec653aa601063d7a414db833dc25273cee463985b052b72bc
warnings: ""

View File

@ -0,0 +1,16 @@
---
namespace: Compile
expectation: Pass
outputs:
- - initial_symbol_table: 002a658ff3a2db38eb21e316458d2473313bbe50f2b4a7cd4aa6e04444c2ed3c
type_checked_symbol_table: e6cbe752fa16e7a820685d02f654c97c2ccf509f7bb3287ea7060017bda0a139
unrolled_symbol_table: e6cbe752fa16e7a820685d02f654c97c2ccf509f7bb3287ea7060017bda0a139
initial_ast: 6eefbb8a62e5c5b798129574876dee19ee0e3b75de9337f539a3a005b18ea1f7
unrolled_ast: 6eefbb8a62e5c5b798129574876dee19ee0e3b75de9337f539a3a005b18ea1f7
ssa_ast: 6eefbb8a62e5c5b798129574876dee19ee0e3b75de9337f539a3a005b18ea1f7
flattened_ast: 2f4a5e927ab19fb770caabe0c4a3ceda8d765d4303c59ad1a0c8350cecd8a9fd
destructured_ast: 1dc62a6fcfea66fe2a10e3a5584057ab22f8b737252efb2902778b1c651fcd8f
inlined_ast: 1dc62a6fcfea66fe2a10e3a5584057ab22f8b737252efb2902778b1c651fcd8f
dce_ast: 1dc62a6fcfea66fe2a10e3a5584057ab22f8b737252efb2902778b1c651fcd8f
bytecode: b39b7b375dab7194cd24f4f2dde6f8c4c13e6a25b9107af52fddb45df9e3435f
warnings: ""

View File

@ -0,0 +1,5 @@
---
namespace: Compile
expectation: Fail
outputs:
- "Error [ETYC0372000]: invalid assignment target\n --> compiler-test:5:9\n |\n 5 | a[0u32] = false;\n | ^^^^^^^\nError [ETYC0372000]: invalid assignment target\n --> compiler-test:6:9\n |\n 6 | a[1u32] = true;\n | ^^^^^^^\n"

View File

@ -0,0 +1,5 @@
---
namespace: Compile
expectation: Fail
outputs:
- "Error [ETYC0372007]: Expected one type from `array`, but got `u32`\n --> compiler-test:9:29\n |\n 9 | sum = sum + a[i][j];\n | ^^^^\nError [ETYC0372003]: Expected type `u32` but type `no type` was found\n --> compiler-test:9:23\n |\n 9 | sum = sum + a[i][j];\n | ^^^^^^^^^^^^^\n"

View File

@ -0,0 +1,16 @@
---
namespace: Compile
expectation: Pass
outputs:
- - initial_symbol_table: 03511070212594f877945470becbe3258d1dbc7c5673adb0d2fa56fc7b9d52ae
type_checked_symbol_table: 9a9deaa022f73e57c24c8336dffa974f8cddb35e9b81c5b383571a37d2531bf2
unrolled_symbol_table: 9a9deaa022f73e57c24c8336dffa974f8cddb35e9b81c5b383571a37d2531bf2
initial_ast: 12e8c9a76387f6e9b54a59010089629f2f3c0736c56da880208280e86611e3fb
unrolled_ast: 12e8c9a76387f6e9b54a59010089629f2f3c0736c56da880208280e86611e3fb
ssa_ast: eb96cfc44c8d578ec0cf3172f2e794e36c0052aab90eeef12f8ec7c8f8922758
flattened_ast: 9f508e380ec0e1c97854f3101a18b33de757b26cb241c07995f7ad387544ea7c
destructured_ast: 621c185f09c1cffc1ac757e55ced700b67068c08837c58dc9462dcdc5605faa7
inlined_ast: 621c185f09c1cffc1ac757e55ced700b67068c08837c58dc9462dcdc5605faa7
dce_ast: 621c185f09c1cffc1ac757e55ced700b67068c08837c58dc9462dcdc5605faa7
bytecode: 11706f359e35f6269b2f879e483f2e1dc1df99c710fc8476dfb1e3c6115d8268
warnings: ""

View File

@ -0,0 +1,16 @@
---
namespace: Compile
expectation: Pass
outputs:
- - initial_symbol_table: db965bbea0fe710347e590189a11c632e67356d6eb3dcff1ee3746f59abada67
type_checked_symbol_table: 7388f185d6d4bf6f50baf94b543d24759c53a72ebe46a730911eb7c13b429970
unrolled_symbol_table: 7388f185d6d4bf6f50baf94b543d24759c53a72ebe46a730911eb7c13b429970
initial_ast: 89e5ca97a429005c3b5c6fdd40756114ed302961d90fc8109c25218613dbe305
unrolled_ast: 89e5ca97a429005c3b5c6fdd40756114ed302961d90fc8109c25218613dbe305
ssa_ast: daa92399cb5b70a35693c15d2f3a59ae0f75a9203c7be55ddb12a083adeeb2c4
flattened_ast: cf3dd007fa44453a99893d32369678eaa8bdce11ebe676fd5383fe726f5b2f39
destructured_ast: 12970e30a633c72202544f4d9fcdd174a63d0cd52595a7cb499b92baf1da028f
inlined_ast: 12970e30a633c72202544f4d9fcdd174a63d0cd52595a7cb499b92baf1da028f
dce_ast: 12970e30a633c72202544f4d9fcdd174a63d0cd52595a7cb499b92baf1da028f
bytecode: 789b22bc0c6e954ae7fed24a064342bf0729393fab7e8d8206b0923f53240dd1
warnings: ""

View File

@ -0,0 +1,16 @@
/*
namespace: Compile
expectation: Pass
*/
program test.aleo {
mapping data: address => [bool; 8];
transition foo(a: [bool; 8]) {
return then finalize(self.caller, a);
}
finalize foo(caller: address, a: [bool; 8]) {
data.set(caller, a);
}
}

View File

@ -0,0 +1,12 @@
/*
namespace: Compile
expectation: Fail
*/
program test.aleo {
transition foo(a: [bool; 8]) -> [bool; 8] {
a[0u32] = false;
a[1u32] = true;
return a;
}
}

View File

@ -0,0 +1,16 @@
/*
namespace: Compile
expectation: Fail
*/
program test.aleo {
transition foo(a: [u32; 4]) {
let sum: u32 = 0u32;
for i: u32 in 0u32..4u32 {
for j: u32 in 0u32..4u32 {
sum = sum + a[i][j];
}
}
}
}

View File

@ -0,0 +1,28 @@
/*
namespace: Compile
expectation: Pass
*/
program test.aleo {
transition main(
a: address, b: bool, c: field, d: i8, e: i16, f: i64, g: i128, h: u8, i: u16, j: u32, k: u64, l: u128, m: scalar, n: i32
) -> (
address, bool, field, i8, i16, i64, i128, u8, u16, u32, u64, u128, scalar, i32
) {
let one: address = b ? a : a;
let two: bool = b ? b : b;
let three: field = b ? c : c;
let four: i8 = b ? d : d;
let five: i16 = b ? e : e;
let six: i64 = b ? f : f;
let seven: i128 = b ? g : g;
let eight: u8 = b ? h : h;
let nine: u16 = b ? i : i;
let ten: u32 = b ? j : j;
let eleven: u64 = b ? k : k;
let twelve: u128 = b ? l : l;
let thirteen: scalar = b ? m : m;
let fourteen: i32 = b ? n : n;
return (one, two, three, four, five, six, seven, eight, nine, ten, eleven, twelve, thirteen, fourteen);
}
}

View File

@ -0,0 +1,37 @@
/*
namespace: Compile
expectation: Pass
*/
program test.aleo {
struct Data {
data: [u8; 2],
}
function foo(a: u8, b: u8) -> [Data; 2] {
let data_1: Data = Data { data: [a, b] };
let data_2: Data = Data { data: [b, a] };
if (a == b) {
return [data_1, data_2];
}
let data_3: Data = Data { data: [2u8 * data_1.data[0u8], 4u8 * data_2.data[1u8]] };
return [data_2, data_3];
}
transition bar(flag1: bool, flag2: bool, a: u8, b: u8) -> [Data; 2] {
let start: [Data; 2] = foo(a, b);
if flag1 {
start = foo(start[0u8].data[0u8], start[1u8].data[1u8]);
} else {
if flag2 {
start = foo(start[1u8].data[0u8], start[0u8].data[1u8]);
} else {
start = foo(start[0u8].data[1u8], start[1u8].data[0u8]);
}
}
return start;
}
}