Skip to content

Commit 3734e25

Browse files
vezenovmjfecher
andauthoredJul 10, 2023
feat(stdlib): Vec type (#1905)
* 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>
1 parent 0628c3c commit 3734e25

File tree

9 files changed

+102
-6
lines changed

9 files changed

+102
-6
lines changed
 

‎crates/nargo_cli/tests/test_data_ssa_refactor/slices/src/main.nr

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ fn main(x : Field, y : pub Field) {
55
/// is not yet supported
66

77
let mut slice: [Field] = [0; 2];
8-
98
assert(slice[0] == 0);
109
assert(slice[0] != 1);
1110
slice[0] = x;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[package]
2+
authors = [""]
3+
compiler_version = "0.7.1"
4+
5+
[dependencies]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
x = "5"
2+
y = "10"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use dep::std::collections::vec::Vec;
2+
3+
fn main(x: Field, y: pub Field) {
4+
let mut vector = Vec::new();
5+
6+
assert(vector.len() == 0);
7+
for i in 0..5 {
8+
vector.push(i);
9+
}
10+
assert(vector.len() == 5);
11+
for i in 0..5 {
12+
assert(i == vector.get(i));
13+
}
14+
15+
let last_elem = vector.pop();
16+
assert(last_elem == 4);
17+
assert(vector.len() == 4);
18+
19+
vector.insert(2, 100);
20+
assert(vector.get(2) == 100);
21+
assert(vector.get(4) == 3);
22+
assert(vector.len() == 5);
23+
24+
let removed_elem = vector.remove(3);
25+
assert(removed_elem == 2);
26+
assert(vector.get(3) == 3);
27+
assert(vector.len() == 4);
28+
29+
let mut inputs_vector = Vec::from_slice([x, y]);
30+
assert(inputs_vector.get(0) == x);
31+
assert(inputs_vector.get(1) == y);
32+
}

‎crates/noirc_evaluator/src/ssa_refactor/ir/instruction.rs

-1
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,6 @@ impl Instruction {
300300
if let (Some((array, _)), Some(index)) = (array, index) {
301301
let index =
302302
index.try_to_u64().expect("Expected array index to fit in u64") as usize;
303-
304303
if index < array.len() {
305304
return SimplifiedTo(array[index]);
306305
}

‎crates/noirc_frontend/src/hir/def_map/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ impl CrateDefMap {
9393
.to_str()
9494
.expect("expected std path to be convertible to str");
9595
assert_eq!(path_as_str, "std/lib");
96-
ast.module_decls.retain(|ident| ident.0.contents != "slice");
96+
ast.module_decls
97+
.retain(|ident| ident.0.contents != "slice" && ident.0.contents != "collections");
9798
}
9899

99100
// Allocate a default Module for the root, giving it a ModuleId

‎crates/noirc_frontend/src/lexer/token.rs

-3
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,6 @@ pub enum Keyword {
442442
Struct,
443443
Unconstrained,
444444
Use,
445-
Vec,
446445
While,
447446
}
448447

@@ -478,7 +477,6 @@ impl fmt::Display for Keyword {
478477
Keyword::Struct => write!(f, "struct"),
479478
Keyword::Unconstrained => write!(f, "unconstrained"),
480479
Keyword::Use => write!(f, "use"),
481-
Keyword::Vec => write!(f, "Vec"),
482480
Keyword::While => write!(f, "while"),
483481
}
484482
}
@@ -517,7 +515,6 @@ impl Keyword {
517515
"struct" => Keyword::Struct,
518516
"unconstrained" => Keyword::Unconstrained,
519517
"use" => Keyword::Use,
520-
"Vec" => Keyword::Vec,
521518
"while" => Keyword::While,
522519

523520
"true" => return Some(Token::Bool(true)),

‎noir_stdlib/src/collections/vec.nr

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
struct Vec<T> {
2+
slice: [T]
3+
}
4+
5+
// A mutable vector type implemented as a wrapper around immutable slices.
6+
// A separate type is technically not needed but helps differentiate which operations are mutable.
7+
impl<T> Vec<T> {
8+
fn new() -> Self {
9+
Self { slice: [] }
10+
}
11+
12+
// Create a Vec containing each element from the given slice.
13+
// Mutations to the resulting Vec will not affect the original slice.
14+
fn from_slice(slice: [T]) -> Self {
15+
Self { slice }
16+
}
17+
18+
/// Get an element from the vector at the given index.
19+
/// Panics if the given index
20+
/// points beyond the end of the vector.
21+
fn get(&mut self, index: Field) -> T {
22+
self.slice[index]
23+
}
24+
25+
/// Push a new element to the end of the vector, returning a
26+
/// new vector with a length one greater than the
27+
/// original unmodified vector.
28+
fn push(&mut self, elem: T) {
29+
self.slice = self.slice.push_back(elem);
30+
}
31+
32+
/// Pop an element from the end of the given vector, returning
33+
/// a new vector with a length of one less than the given vector,
34+
/// as well as the popped element.
35+
/// Panics if the given vector's length is zero.
36+
fn pop(&mut self) -> T {
37+
let (popped_slice, last_elem) = self.slice.pop_back();
38+
self.slice = popped_slice;
39+
last_elem
40+
}
41+
42+
/// Insert an element at a specified index, shifting all elements
43+
/// after it to the right
44+
fn insert(&mut self, index: Field, elem: T) {
45+
self.slice = self.slice.insert(index, elem);
46+
}
47+
48+
/// Remove an element at a specified index, shifting all elements
49+
/// after it to the left, returning the removed element
50+
fn remove(&mut self, index: Field) -> T {
51+
let (new_slice, elem) = self.slice.remove(index);
52+
self.slice = new_slice;
53+
elem
54+
}
55+
56+
/// Returns the number of elements in the vector
57+
fn len(self: Self) -> Field {
58+
self.slice.len()
59+
}
60+
}

‎noir_stdlib/src/lib.nr

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ mod sha512;
1212
mod field;
1313
mod ec;
1414
mod unsafe;
15+
mod collections;
1516
mod compat;
1617

1718
#[builtin(println)]

0 commit comments

Comments
 (0)
Please sign in to comment.