Merge pull request #530 from AleoHQ/feature/implicit-array-index

Implement implicit u32 array indices
This commit is contained in:
Howard Wu 2021-01-07 20:37:52 -04:00 committed by GitHub
commit a59e1e3836
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 95 additions and 7 deletions

View File

@ -2,11 +2,11 @@ circuit PedersenHash {
parameters: [group; 256],
// Instantiates a Pedersen hash circuit
static function new(parameters: [group; 256]) -> Self {
function new(parameters: [group; 256]) -> Self {
return Self { parameters: parameters }
}
function hash(bits: [bool; 256]) -> group {
function hash(self, bits: [bool; 256]) -> group {
let mut digest: group = 0;
for i in 0..256 {
if bits[i] {

View File

@ -426,8 +426,8 @@ impl Frame {
let _expect_none = self.insert_variable(statement.variable.name.to_owned(), u32_type.clone(), &statement.span);
// Parse `from` and `to` expressions.
let from_type = self.parse_expression(&statement.start)?;
let to_type = self.parse_expression(&statement.stop)?;
let from_type = self.parse_index(&statement.start)?;
let to_type = self.parse_index(&statement.stop)?;
// Assert `from` and `to` types are a u32 or implicit.
self.assert_equal(u32_type.clone(), from_type, &statement.span);
@ -798,6 +798,18 @@ impl Frame {
}
}
///
/// Returns `Type::U32` if the given index has `Type::TypeVariable`.
/// Hard codes all implicitly typed indices to u32.
/// Ex: `arr[0]` => `arr[0u32]`
///
fn parse_index(&mut self, index: &Expression) -> Result<Type, FrameError> {
Ok(match self.parse_expression(index)? {
Type::TypeVariable(_) => Type::IntegerType(IntegerType::U32),
type_ => type_,
})
}
///
/// Returns the type of the accessed array element.
///
@ -809,7 +821,7 @@ impl Frame {
};
// Parse the expression type.
let type_ = self.parse_expression(index)?;
let type_ = self.parse_index(index)?;
// Assert the type is an index.
self.assert_index(&type_, span);
@ -836,14 +848,14 @@ impl Frame {
if let Some(expression) = left {
// Parse the expression type.
let type_ = self.parse_expression(expression)?;
let type_ = self.parse_index(expression)?;
self.assert_index(&type_, span);
}
if let Some(expression) = right {
// Parse the expression type.
let type_ = self.parse_expression(expression)?;
let type_ = self.parse_index(expression)?;
self.assert_index(&type_, span);
}

View File

@ -0,0 +1,5 @@
function main() {
let a = [0u32; 4];
let b = a[0]; // This should not cause a type inference error
}

View File

@ -42,3 +42,21 @@ fn test_invalid_spread() {
check.expect_error();
}
#[test]
fn test_index_implicit() {
let program_string = include_str!("index_implicit.leo");
let check = TestTypeInference::new(program_string);
check.check()
}
#[test]
fn test_slice_implicit() {
let program_string = include_str!("slice_implicit.leo");
let check = TestTypeInference::new(program_string);
check.check();
}

View File

@ -0,0 +1,5 @@
function main() {
let a = [0u32; 4];
let b = a[0..2]; // This should not cause a type inference error
}

View File

@ -17,6 +17,7 @@
pub mod arrays;
pub mod circuits;
pub mod functions;
pub mod statements;
pub mod tuples;
pub mod variables;

View File

@ -0,0 +1,7 @@
function main() {
let a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for i in 0..10 {
console.log("{}", a[i]);
}
}

View File

@ -0,0 +1,5 @@
function main() {
for i in 0..10 {
console.log("{}", i);
}
}

View File

@ -0,0 +1,35 @@
// Copyright (C) 2019-2020 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::TestTypeInference;
#[test]
fn test_loop_implicit() {
let program_string = include_str!("loop_implicit.leo");
let check = TestTypeInference::new(program_string);
check.check();
}
#[test]
fn test_array_loop_implicit() {
let program_string = include_str!("array_loop_implicit.leo");
let check = TestTypeInference::new(program_string);
check.check();
}