Skip to content

Commit

Permalink
Rewrite "remove at" standard library function.
Browse files Browse the repository at this point in the history
  • Loading branch information
hdwalters committed Dec 12, 2024
1 parent 49492d6 commit 5a9cc2a
Show file tree
Hide file tree
Showing 10 changed files with 181 additions and 47 deletions.
31 changes: 24 additions & 7 deletions src/std/array.ab
Original file line number Diff line number Diff line change
Expand Up @@ -27,29 +27,46 @@ pub fun includes(array, value) {
return result >= 0
}

/// Returns the first element in the array
pub fun first(array) {
return array[0]
}

/// Returns the last element in the array
pub fun last(array) {
return array[len(array) - 1]
let index = len(array) - 1
return array[index]
}

/// Removes an element at the index from the array
pub fun remove_at(ref array: [], index: Num): Null {
trust $ unset {nameof array}[{index}] $
let offset = index + 1
let length = len(array)
array = array[0..index] + array[offset..length]
}

/// Removes an element at the index from the array, and returns it
pub fun extract_at(ref array, index) {
let elem = array[index]
remove_at(array, index)
return elem
let element = array[index]
let offset = index + 1
let length = len(array)
array = array[0..index] + array[offset..length]
return element
}

/// Removes the last element from the array, and returns it
pub fun pop(ref array) {
return extract_at(array, len(array) - 1)
let length = len(array)
let index = length - 1
let element = array[index]
array = array[0..index]
return element
}

/// Removes the first element from the array, and returns it
pub fun shift(ref array) {
return extract_at(array, 0)
let length = len(array)
let element = array[0]
array = array[1..length]
return element
}
29 changes: 21 additions & 8 deletions src/tests/stdlib/array_extract_at.ab
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
import { extract_at, array_first_index } from "std/array"
import { extract_at } from "std/array"

main {
let array = ["Failed", "Extracted", "Failed"]
// Output
// Value at -5: "" (4) [zero one two three]
// Value at -4: "zero" (4) [zero one two three]
// Value at -3: "one" (4) [zero one two three]
// Value at -2: "two" (4) [zero one two three]
// Value at -1: "three" (4) [zero one two three]
// Value at 0: "zero" (3) [one two three]
// Value at 1: "one" (3) [zero two three]
// Value at 2: "two" (3) [zero one three]
// Value at 3: "three" (3) [zero one two]
// Value at 4: "" (4) [zero one two three]

fun test_extract(data: [Text], index: Num): Null {
let value = extract_at(data, index)
echo "Value at {index}: \"{value}\" ({len(data)}) [{data}]"
}

if extract_at(array, 1) == "Extracted"
and len(array) == 2
and array_first_index(array, "Extracted") == -1
{
echo "Succeeded"
main {
let numbers = ["zero", "one", "two", "three"]
for index in -5..=4 {
test_extract(numbers, index)
}
}
17 changes: 17 additions & 0 deletions src/tests/stdlib/array_first.ab
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { first } from "std/array"

// Output
// First of numbers: "zero" (4) [zero one two three]
// First of empty: "" (0) []

fun test_first(label: Text, data: [Text]): Null {
let value = first(data)
echo "First of {label}: \"{value}\" ({len(data)}) [{data}]"
}

main {
let numbers = ["zero", "one", "two", "three"]
let empty = [Text]
test_first("numbers", numbers)
test_first("empty", empty)
}
22 changes: 18 additions & 4 deletions src/tests/stdlib/array_first_index.ab
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
import * from "std/array"
import { array_first_index } from "std/array"

// Output
// 2
// Index of "zero": 0
// Index of "one": 1
// Index of "two": 2
// Index of "three": 3
// Index of "four": -1

fun test_index(data: [Text], value: Text): Null {
let index = array_first_index(data, value)
echo "Index of \"{value}\": {index}"
}

main {
echo array_first_index([1, 2, 3, 4], 3)
}
let numbers = ["zero", "one", "two", "three", "two", "one", "zero"]
test_index(numbers, "zero")
test_index(numbers, "one")
test_index(numbers, "two")
test_index(numbers, "three")
test_index(numbers, "four")
}
15 changes: 13 additions & 2 deletions src/tests/stdlib/array_last.ab
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
import { last } from "std/array"

// Output
// Last of numbers: "three" (4) [zero one two three]
// Last of empty: "" (0) []

fun test_last(label: Text, data: [Text]): Null {
let value = last(data)
echo "Last of {label}: \"{value}\" ({len(data)}) [{data}]"
}

main {
let array = ["Failed", "Not", "Succeeded"]
echo last(array)
let numbers = ["zero", "one", "two", "three"]
let empty = [Text]
test_last("numbers", numbers)
test_last("empty", empty)
}
22 changes: 14 additions & 8 deletions src/tests/stdlib/array_pop.ab
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import { pop, array_first_index } from "std/array"
import { pop } from "std/array"

// Output
// Popped from numbers: "three" (3) [zero one two]
// Popped from empty: "" (0) []

fun test_pop(label: Text, data: [Text]): Null {
let value = pop(data)
echo "Popped from {label}: \"{value}\" ({len(data)}) [{data}]"
}

main {
let array = ["Failed", "Failed", "Popped"]
if pop(array) == "Popped"
and len(array) == 2
and array_first_index(array, "Popped") == -1
{
echo "Succeeded"
}
let numbers = ["zero", "one", "two", "three"]
let empty = [Text]
test_pop("numbers", numbers)
test_pop("empty", empty)
}
26 changes: 21 additions & 5 deletions src/tests/stdlib/array_remove_at.ab
Original file line number Diff line number Diff line change
@@ -1,9 +1,25 @@
import { remove_at, array_first_index } from "std/array"
import { remove_at } from "std/array"

// Output
// Array after -5: (4) [zero one two three]
// Array after -4: (4) [zero one two three]
// Array after -3: (4) [zero one two three]
// Array after -2: (4) [zero one two three]
// Array after -1: (4) [zero one two three]
// Array after 0: (3) [one two three]
// Array after 1: (3) [zero two three]
// Array after 2: (3) [zero one three]
// Array after 3: (3) [zero one two]
// Array after 4: (4) [zero one two three]

fun test_remove(data: [Text], index: Num): Null {
remove_at(data, index)
echo "Array after {index}: ({len(data)}) [{data}]"
}

main {
let array = ["Failed", "Removed", "Failed"]
remove_at(array, 1)
if len(array) == 2 and array_first_index(array, "Removed") == -1 {
echo "Succeeded"
let numbers = ["zero", "one", "two", "three"]
for index in -5..=4 {
test_remove(numbers, index)
}
}
21 changes: 21 additions & 0 deletions src/tests/stdlib/array_remove_each.ab
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { remove_at } from "std/array"

// Output
// Array before 1: (4) [zero one two three]
// Array after 1: (3) [zero two three]
// Array after 2: (2) [zero three]
// Array after 3: (1) [zero]
// Array after 4: (1) [zero]

main {
let numbers = ["zero", "one", "two", "three"]
echo "Array before 1: ({len(numbers)}) [{numbers}]"
remove_at(numbers, 1)
echo "Array after 1: ({len(numbers)}) [{numbers}]"
remove_at(numbers, 1)
echo "Array after 2: ({len(numbers)}) [{numbers}]"
remove_at(numbers, 1)
echo "Array after 3: ({len(numbers)}) [{numbers}]"
remove_at(numbers, 1)
echo "Array after 4: ({len(numbers)}) [{numbers}]"
}
23 changes: 18 additions & 5 deletions src/tests/stdlib/array_search.ab
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
import * from "std/array"
import { array_search } from "std/array"

// Output
// 6
// Indices of "zero": [0 6]
// Indices of "one": [1 5]
// Indices of "two": [2 4]
// Indices of "three": [3]
// Indices of "four": []

fun test_search(data: [Text], value: Text): Null {
let indices = array_search(data, value)
echo "Indices of \"{value}\": [{indices}]"
}

main {
let result = array_search([1, 2, 3, 4, 3], 3)
echo result[0]+result[1]
}
let numbers = ["zero", "one", "two", "three", "two", "one", "zero"]
test_search(numbers, "zero")
test_search(numbers, "one")
test_search(numbers, "two")
test_search(numbers, "three")
test_search(numbers, "four")
}
22 changes: 14 additions & 8 deletions src/tests/stdlib/array_shift.ab
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import { shift, array_first_index } from "std/array"
import { shift } from "std/array"

// Output
// Shifted from numbers: "zero" (3) [one two three]
// Shifted from empty: "" (0) []

fun test_shift(label: Text, data: [Text]): Null {
let value = shift(data)
echo "Shifted from {label}: \"{value}\" ({len(data)}) [{data}]"
}

main {
let array = ["Shifted", "Failed", "Failed"]
if shift(array) == "Shifted"
and len(array) == 2
and array_first_index(array, "Shifted") == -1
{
echo "Succeeded"
}
let numbers = ["zero", "one", "two", "three"]
let empty = [Text]
test_shift("numbers", numbers)
test_shift("empty", empty)
}

0 comments on commit 5a9cc2a

Please sign in to comment.