Skip to content

Commit

Permalink
feat(stdlib): Vec type (#1905)
Browse files Browse the repository at this point in the history
* add multiple slice builtin funcs

* initial new stdlib Vec method that uses slices

* a couple more methods and starting to test

* remove Vec keyword from lexer and finish Vec test

* enable array index panic in acir gen when enable_side_effects_var is None

* Update crates/nargo_cli/tests/test_data_ssa_refactor/vectors/src/main.nr

* Update crates/nargo_cli/tests/test_data_ssa_refactor/slices/src/main.nr

* when slices are not enabled do not include collections module in stdlib

* fix in collect_defs

* remove append builtin for now

* Update noir_stdlib/src/collections/vec.nr

Co-authored-by: jfecher <jake@aztecprotocol.com>

* Update noir_stdlib/src/collections/vec.nr

Co-authored-by: jfecher <jake@aztecprotocol.com>

* revert check on option and merge in pr #1906

* use from_slice in test

* switch retain for collections and slice modules to &&

---------

Co-authored-by: jfecher <jake@aztecprotocol.com>
  • Loading branch information
vezenovm and jfecher authored Jul 10, 2023
1 parent 0628c3c commit 3734e25
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ fn main(x : Field, y : pub Field) {
/// is not yet supported
let mut slice: [Field] = [0; 2];

assert(slice[0] == 0);
assert(slice[0] != 1);
slice[0] = x;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[package]
authors = [""]
compiler_version = "0.7.1"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
x = "5"
y = "10"
32 changes: 32 additions & 0 deletions crates/nargo_cli/tests/test_data_ssa_refactor/vectors/src/main.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use dep::std::collections::vec::Vec;

fn main(x: Field, y: pub Field) {
let mut vector = Vec::new();

assert(vector.len() == 0);
for i in 0..5 {
vector.push(i);
}
assert(vector.len() == 5);
for i in 0..5 {
assert(i == vector.get(i));
}

let last_elem = vector.pop();
assert(last_elem == 4);
assert(vector.len() == 4);

vector.insert(2, 100);
assert(vector.get(2) == 100);
assert(vector.get(4) == 3);
assert(vector.len() == 5);

let removed_elem = vector.remove(3);
assert(removed_elem == 2);
assert(vector.get(3) == 3);
assert(vector.len() == 4);

let mut inputs_vector = Vec::from_slice([x, y]);
assert(inputs_vector.get(0) == x);
assert(inputs_vector.get(1) == y);
}
1 change: 0 additions & 1 deletion crates/noirc_evaluator/src/ssa_refactor/ir/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,6 @@ impl Instruction {
if let (Some((array, _)), Some(index)) = (array, index) {
let index =
index.try_to_u64().expect("Expected array index to fit in u64") as usize;

if index < array.len() {
return SimplifiedTo(array[index]);
}
Expand Down
3 changes: 2 additions & 1 deletion crates/noirc_frontend/src/hir/def_map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ impl CrateDefMap {
.to_str()
.expect("expected std path to be convertible to str");
assert_eq!(path_as_str, "std/lib");
ast.module_decls.retain(|ident| ident.0.contents != "slice");
ast.module_decls
.retain(|ident| ident.0.contents != "slice" && ident.0.contents != "collections");
}

// Allocate a default Module for the root, giving it a ModuleId
Expand Down
3 changes: 0 additions & 3 deletions crates/noirc_frontend/src/lexer/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,6 @@ pub enum Keyword {
Struct,
Unconstrained,
Use,
Vec,
While,
}

Expand Down Expand Up @@ -478,7 +477,6 @@ impl fmt::Display for Keyword {
Keyword::Struct => write!(f, "struct"),
Keyword::Unconstrained => write!(f, "unconstrained"),
Keyword::Use => write!(f, "use"),
Keyword::Vec => write!(f, "Vec"),
Keyword::While => write!(f, "while"),
}
}
Expand Down Expand Up @@ -517,7 +515,6 @@ impl Keyword {
"struct" => Keyword::Struct,
"unconstrained" => Keyword::Unconstrained,
"use" => Keyword::Use,
"Vec" => Keyword::Vec,
"while" => Keyword::While,

"true" => return Some(Token::Bool(true)),
Expand Down
60 changes: 60 additions & 0 deletions noir_stdlib/src/collections/vec.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
struct Vec<T> {
slice: [T]
}

// A mutable vector type implemented as a wrapper around immutable slices.
// A separate type is technically not needed but helps differentiate which operations are mutable.
impl<T> Vec<T> {
fn new() -> Self {
Self { slice: [] }
}

// Create a Vec containing each element from the given slice.
// Mutations to the resulting Vec will not affect the original slice.
fn from_slice(slice: [T]) -> Self {
Self { slice }
}

/// Get an element from the vector at the given index.
/// Panics if the given index
/// points beyond the end of the vector.
fn get(&mut self, index: Field) -> T {
self.slice[index]
}

/// Push a new element to the end of the vector, returning a
/// new vector with a length one greater than the
/// original unmodified vector.
fn push(&mut self, elem: T) {
self.slice = self.slice.push_back(elem);
}

/// Pop an element from the end of the given vector, returning
/// a new vector with a length of one less than the given vector,
/// as well as the popped element.
/// Panics if the given vector's length is zero.
fn pop(&mut self) -> T {
let (popped_slice, last_elem) = self.slice.pop_back();
self.slice = popped_slice;
last_elem
}

/// Insert an element at a specified index, shifting all elements
/// after it to the right
fn insert(&mut self, index: Field, elem: T) {
self.slice = self.slice.insert(index, elem);
}

/// Remove an element at a specified index, shifting all elements
/// after it to the left, returning the removed element
fn remove(&mut self, index: Field) -> T {
let (new_slice, elem) = self.slice.remove(index);
self.slice = new_slice;
elem
}

/// Returns the number of elements in the vector
fn len(self: Self) -> Field {
self.slice.len()
}
}
1 change: 1 addition & 0 deletions noir_stdlib/src/lib.nr
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ mod sha512;
mod field;
mod ec;
mod unsafe;
mod collections;
mod compat;

#[builtin(println)]
Expand Down

0 comments on commit 3734e25

Please sign in to comment.