Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(stdlib): Vec type #1905

Merged
merged 18 commits into from
Jul 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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: [] }
}

vezenovm marked this conversation as resolved.
Show resolved Hide resolved
// 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