Skip to content

Commit

Permalink
Implement the Array store and delete functions and the Buffer
Browse files Browse the repository at this point in the history
… `store` function (#825)
  • Loading branch information
dfellis authored Jul 31, 2024
1 parent e45dceb commit 6801f46
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 0 deletions.
20 changes: 20 additions & 0 deletions src/compile/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1918,6 +1918,17 @@ concat test
1, 1, 2, 3, 5, 8, 4, 5, 6
"#;
);
test!(array_store_and_delete => r#"
export fn main {
const test = [ 1, 2, 5 ];
test.store(2, 3);
test.store(3, 4);
test.print;
test.delete(4).print;
test.print;
}"#;
stdout "[1, 2, 3, 4, 5]\n5\n[1, 2, 3, 4]\n";
);
test!(array_custom_types => r#"
type Foo =
foo: string,
Expand Down Expand Up @@ -2004,6 +2015,15 @@ test!(buffer_repeat => r#"
}"#;
stdout "1, 2, 3, 1, 2, 3, 1, 2, 3\n";
);
test!(buffer_store => r#"
export fn main {
let buf = {i64[3]}(1, 2, 5);
print(buf);
buf.store(2, 3).print;
print(buf);
}"#;
stdout "[1, 2, 5]\n5\n[1, 2, 3]\n";
);

// Hashing
test!(hash => r#"
Expand Down
3 changes: 3 additions & 0 deletions src/std/root.ln
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,8 @@ export fn has{T}(a: Array{T}, f: (T) -> bool) -> bool binds hasfnarray;
export fn find{T}(a: Array{T}, f: (T) -> bool) -> Maybe{T} binds findarray;
export fn every{T}(a: Array{T}, f: (T) -> bool) -> bool binds everyarray;
export fn repeat{T}(a: Array{T}, c: i64) -> Array{T} binds repeatarray;
export fn store{T}(a: Array{T}, i: i64, v: T) -> Fallible{void} binds storearray;
export fn delete{T}(a: Array{T}, i: i64) -> Fallible{T} binds deletearray;

/// Buffer related bindings
export fn get{T, S}(b: T[S], i: i64) -> Maybe{T} binds getbuffer;
Expand All @@ -608,6 +610,7 @@ export fn concat{T, S, N}(a: Buffer{T, S}, b: Buffer{T, N}) -> Buffer{T, S + N}
// TODO: Be able to resolve explicit integer constant values as the integer type so it can be
// grabbed by the type inference system. For now, repeat for buffers outputs an array, instead.
export fn repeat{T, S}(b: Buffer{T, S}, c: i64) -> Array{T} binds repeatbuffertoarray;
export fn store{T, S}(b: Buffer{T, S}, i: i64, v: T) -> Fallible{T} binds storebuffer;

/// Dictionary-related bindings
export fn Dict{K, V}() -> Dict{K, V} binds newdict;
Expand Down
50 changes: 50 additions & 0 deletions src/std/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2870,6 +2870,38 @@ fn repeatarray<T: std::clone::Clone>(a: &Vec<T>, c: &i64) -> Vec<T> {
out
}

/// `storearray` inserts a new value at the specified index, but fails if the index is greater than
/// the length of the length of the array (so there would be at least one "gap" in the array in
/// that situation)
#[inline(always)]
fn storearray<T: std::clone::Clone>(a: &mut Vec<T>, i: &i64, v: &T) -> Result<(), AlanError> {
match (*i as usize) > a.len() {
true => Err(format!(
"Provided array index {} is greater than the length of the array",
i
)
.into()),
false => {
a.insert(*i as usize, v.clone());
Ok(())
}
}
}

/// `deletearray` deletes a value at the specified index, but fails if the index is out-of-bounds.
/// If it succeeds, it returns the value wrapped in a Fallible.
#[inline(always)]
fn deletearray<T: std::clone::Clone>(a: &mut Vec<T>, i: &i64) -> Result<T, AlanError> {
match (*i as usize) >= a.len() {
true => Err(format!(
"Provided array index {} is beyond the bounds of the array",
i
)
.into()),
false => Ok(a.remove(*i as usize).clone()),
}
}

/// Buffer-related functions
/// `getbuffer` returns the value at the given index presuming it exists
Expand Down Expand Up @@ -3007,6 +3039,24 @@ fn repeatbuffertoarray<T: std::clone::Clone, const S: usize>(a: &[T; S], c: &i64
out
}

/// `storebuffer` stores the provided value in the specified index. If the index is out-of-bounds
/// for the buffer it fails, otherwise it returns the old value.
#[inline(always)]
fn storebuffer<T: std::clone::Clone, const S: usize>(
a: &mut [T; S],
i: &i64,
v: &T,
) -> Result<T, AlanError> {
match (*i as usize) < a.len() {
false => Err(format!(
"The provided index {} is out-of-bounds for the specified buffer",
i
)
.into()),
true => Ok(std::mem::replace(a.each_mut()[*i as usize], v.clone())),
}
}

/// Dictionary-related bindings
/// `newdict` creates a new dictionary
Expand Down

0 comments on commit 6801f46

Please sign in to comment.