Skip to content

Commit

Permalink
iter: minimal bare impl
Browse files Browse the repository at this point in the history
  • Loading branch information
hackwaly committed Apr 22, 2024
1 parent 93c1ddd commit ecbf75f
Show file tree
Hide file tree
Showing 9 changed files with 324 additions and 25 deletions.
82 changes: 58 additions & 24 deletions array/array.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ test "iter" {
@assertion.assert_eq(i, 5)?
}

/// Iterates over the array with index.
/// Iterates over the array with index.
///
/// # Arguments
///
Expand Down Expand Up @@ -150,7 +150,7 @@ test "iter_rev" {
@assertion.assert_eq(i, 1)?
}

/// Iterates over the array with index in reversed turn.
/// Iterates over the array with index in reversed turn.
///
/// # Arguments
///
Expand All @@ -162,7 +162,7 @@ test "iter_rev" {
/// ```
/// [1, 2, 3, 4, 5].iter_revi(fn(index, elem){
/// print("(\(index),\(elem)) ")
/// }) //output: (4,5) (3,4) (2,3) (1,2) (0,1)
/// }) //output: (4,5) (3,4) (2,3) (1,2) (0,1)
/// ```
pub fn iter_revi[T](self : Array[T], f : (Int, T) -> Unit) -> Unit {
let len = self.length()
Expand Down Expand Up @@ -238,7 +238,7 @@ test "map" {
}

/// Maps a function over the elements of the arr with index.
///
///
/// # Example
/// ```
/// let arr = [3, 4, 5]
Expand Down Expand Up @@ -329,7 +329,7 @@ test "from_array" {
}

/// Fold out values from an array according to certain rules.
///
///
/// # Example
/// ```
/// let sum = [1, 2, 3, 4, 5].fold_left(init=0, fn { sum, elem => sum + elem })
Expand All @@ -353,7 +353,7 @@ test "fold_left" {
}

/// Fold out values from an array according to certain rules in reversed turn.
///
///
/// # Example
/// ```
/// let sum = [1, 2, 3, 4, 5].fold_right(init=0, fn { sum, elem => sum + elem })
Expand All @@ -377,7 +377,7 @@ test "fold_right" {
}

/// Fold out values from an array according to certain rules with index.
///
///
/// # Example
/// ```
/// let sum = [1, 2, 3, 4, 5].fold_lefti(init=0, fn { index, sum, elem => sum + index })
Expand Down Expand Up @@ -406,7 +406,7 @@ test "fold_lefti" {
}

/// Fold out values from an array according to certain rules in reversed turn with index.
///
///
/// # Example
/// ```
/// let sum = [1, 2, 3, 4, 5].fold_righti(init=0, fn { index, sum, elem => sum + index })
Expand Down Expand Up @@ -436,7 +436,7 @@ test "fold_righti" {
}

/// Reverses the order of elements in the slice, in place.
///
///
/// # Example
/// ```
/// let arr = [1, 2, 3, 4, 5]
Expand Down Expand Up @@ -477,9 +477,9 @@ test "reverse" {
}

/// Swap two elements in the array.
///
/// # Example
///
///
/// # Example
///
/// ```
/// let arr = [1, 2, 3, 4, 5]
/// arr.swap(0, 1)
Expand Down Expand Up @@ -512,9 +512,9 @@ test "swap" {
}

/// Check if all the elements in the array match the condition.
///
/// # Example
///
///
/// # Example
///
/// ```
/// let arr = [1, 2, 3, 4, 5]
/// arr.all(fn(ele) { ele < 6 }) // true
Expand Down Expand Up @@ -546,9 +546,9 @@ test "all" {
}

/// Check if any of the elements in the array match the condition.
///
/// # Example
///
///
/// # Example
///
/// ```
/// let arr = [1, 2, 3, 4, 5]
/// arr.any(fn(ele) { ele < 6 }) // true
Expand Down Expand Up @@ -580,7 +580,7 @@ test "any" {
}

/// Fill the array with a given value.
///
///
/// # Example
/// ```
/// [0, 0, 0, 0, 0].fill(3) // [3, 3, 3, 3, 3]
Expand Down Expand Up @@ -608,7 +608,7 @@ test "fill" {
}

/// Search the array index for a given element.
///
///
/// # Example
/// ```
/// let arr = [3, 4, 5]
Expand Down Expand Up @@ -642,7 +642,7 @@ test "search" {
}

/// Checks if the array contains an element.
///
///
/// # Example
/// ```
/// let arr = [3, 4, 5]
Expand Down Expand Up @@ -676,7 +676,7 @@ test "contains" {
}

/// Check if the array starts with a given prefix.
///
///
/// # Example
/// ```
/// let arr = [3, 4, 5]
Expand Down Expand Up @@ -719,7 +719,7 @@ test "starts_with" {
}

/// Check if the array ends with a given suffix.
///
///
/// # Example
/// ```
/// let v = [3, 4, 5]
Expand Down Expand Up @@ -768,7 +768,7 @@ test "ends_with" {
}

/// Convert array to list.
///
///
/// # Example
///
/// ```
Expand Down Expand Up @@ -894,3 +894,37 @@ test "op_add" {
content="[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]",
)?
}

/// @intrinsic %iter.from_array
pub fn to_iter[T](self : Array[T]) -> @iter.Iter[T] {
@iter.Iter::_unstable_internal_make(

Check warning on line 900 in array/array.mbt

View check run for this annotation

Codecov / codecov/patch

array/array.mbt#L900

Added line #L900 was not covered by tests
fn(yield) {
for i = 0, len = self.length(); i < len; i = i + 1 {
if yield(self[i]).not() {
break

Check warning on line 904 in array/array.mbt

View check run for this annotation

Codecov / codecov/patch

array/array.mbt#L902-L904

Added lines #L902 - L904 were not covered by tests
}
}
},
)
}

test "to_iter" {
let arr = [1, 2, 3, 4, 5]
let iter = arr.to_iter()
let exb = Buffer::make(0)
let mut i = 0
iter.iter(fn(x) {
exb.write_string(x.to_string())
exb.write_char('\n')
i = i + 1
})
@assertion.assert_eq(i, arr.length())?
exb.expect(~content=
#|1
#|2
#|3
#|4
#|5
#|
)?
}
1 change: 1 addition & 0 deletions array/array.mbti
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ fn Array::sort_by_key[T, K : @moonbitlang/core/builtin.Compare + @moonbitlang/co
fn Array::stable_sort[T : @moonbitlang/core/builtin.Compare + @moonbitlang/core/builtin.Eq](Array[T]) -> Unit
fn Array::starts_with[T : @moonbitlang/core/builtin.Eq](Array[T], Array[T]) -> Bool
fn Array::swap[T](Array[T], Int, Int) -> Unit
fn Array::to_iter[T](Array[T]) -> @moonbitlang/core/iter.Iter[T]
fn Array::to_list[T](Array[T]) -> List[T]

// Traits
Expand Down
3 changes: 2 additions & 1 deletion array/moon.pkg.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"moonbitlang/core/assertion",
"moonbitlang/core/math",
"moonbitlang/core/coverage",
"moonbitlang/core/vec"
"moonbitlang/core/vec",
"moonbitlang/core/iter"
]
}
43 changes: 43 additions & 0 deletions iter/consumers.mbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2024 International Digital Economy Academy
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/// @intrinsic %iter.iter
pub fn iter[T](self : Iter[T], f : (T) -> Unit) -> Unit {
(self.0)(

Check warning on line 17 in iter/consumers.mbt

View check run for this annotation

Codecov / codecov/patch

iter/consumers.mbt#L17

Added line #L17 was not covered by tests
fn {
yield => {
f(yield)

Check warning on line 20 in iter/consumers.mbt

View check run for this annotation

Codecov / codecov/patch

iter/consumers.mbt#L20

Added line #L20 was not covered by tests
true
}
},
)
}

/// @intrinsic %iter.reduce
pub fn fold[T, B](self : Iter[T], f : (B, T) -> B, init : B) -> B {
let mut acc = init

Check warning on line 29 in iter/consumers.mbt

View check run for this annotation

Codecov / codecov/patch

iter/consumers.mbt#L29

Added line #L29 was not covered by tests
(self.0)(
fn {
yield => {
acc = f(acc, yield)

Check warning on line 33 in iter/consumers.mbt

View check run for this annotation

Codecov / codecov/patch

iter/consumers.mbt#L33

Added line #L33 was not covered by tests
true
}
},
)
acc
}

pub fn count[T](self : Iter[T]) -> Int {
self.fold(fn { acc, _ => acc + 1 }, 0)

Check warning on line 42 in iter/consumers.mbt

View check run for this annotation

Codecov / codecov/patch

iter/consumers.mbt#L42

Added line #L42 was not covered by tests
}
27 changes: 27 additions & 0 deletions iter/iter.mbti
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package moonbitlang/core/iter

// Values

// Types and methods
type Iter
fn Iter::_unstable_internal_make[T](((T) -> Bool) -> Unit) -> Iter[T]
fn Iter::count[T](Iter[T]) -> Int
fn Iter::drop[T](Iter[T], Int) -> Iter[T]
fn Iter::drop_while[T](Iter[T], (T) -> Bool) -> Iter[T]
fn Iter::empty[T]() -> Iter[T]
fn Iter::filter[T](Iter[T], (T) -> Bool) -> Iter[T]
fn Iter::find_first[T](Iter[T], (T) -> Bool) -> Option[T]
fn Iter::flat_map[T, R](Iter[T], (T) -> Iter[R]) -> Iter[R]
fn Iter::fold[T, B](Iter[T], (B, T) -> B, B) -> B
fn Iter::iter[T](Iter[T], (T) -> Unit) -> Unit
fn Iter::map[T, R](Iter[T], (T) -> R) -> Iter[R]
fn Iter::repeat[T](T) -> Iter[T]
fn Iter::singleton[T](T) -> Iter[T]
fn Iter::take[T](Iter[T], Int) -> Iter[T]
fn Iter::take_while[T](Iter[T], (T) -> Bool) -> Iter[T]
fn Iter::tap[T](Iter[T], (T) -> Unit) -> Iter[T]

// Traits

// Extension Methods

7 changes: 7 additions & 0 deletions iter/moon.pkg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"import": [
"moonbitlang/core/builtin",
"moonbitlang/core/assertion",
"moonbitlang/core/coverage"
]
}
Loading

0 comments on commit ecbf75f

Please sign in to comment.