feat: make String iterable over code points with iterate/iteratorValue primitives

Add String as a subclass of Sequence in core.wren and implement the iterator protocol for strings in wren_core.c. The string_iterate native advances through UTF-8 code point boundaries, while string_iteratorValue extracts the full code point at a given byte index. Includes comprehensive test coverage for iteration, edge cases (empty strings, mid-sequence positions), and error handling for invalid iterator types and out-of-bounds indices. Also updates documentation for String, List, and Sequence classes with iterator protocol details and usage examples.
This commit is contained in:
Bob Nystrom
2015-01-23 04:58:22 +00:00
parent 7e52e36a1c
commit 488fb27b91
14 changed files with 141 additions and 21 deletions
+34 -2
View File
@@ -1,11 +1,33 @@
^title Sequence Class
^category core
An abstract base class for any iterable object. It provides a number of methods for working with sequences based on the core [iterator protocol](../control-flow.html#the-iterator-protocol).
An abstract base class for any iterable object. Any class that implements the
core [iterator protocol][] can extend this to get a number of helpful methods.
[iterator protocol]: ../control-flow.html#the-iterator-protocol
### **all**(predicate)
Tests whether all the elements in the list pass the `predicate`.
Tests whether all the elements in the sequence pass the `predicate`.
Iterates over the sequence, passing each element to the function `predicate`.
If it returns `false`, stops iterating and returns `false`. Otherwise, returns
`true`.
:::dart
[1, 2, 3].all {|n| n > 2} // False.
[1, 2, 3].all {|n| n < 4} // True.
### **map**(transformation)
Creates a new list by applying `transformation` to each element in the
sequence.
Iterates over the sequence, passing each element to the function
`transformation`. Generates a new list from the result of each of those calls.
:::dart
[1, 2, 3].map {|n| n * 2} // [2, 4, 6].
### **reduce**(function)
@@ -16,3 +38,13 @@ It is a runtime error to call this on an empty sequence.
### **reduce**(seed, function)
Similar to above, but uses `seed` for the initial value of the accumulator. If the sequence is empty, returns `seed`.
### **where**(predicate)
Produces a new list containing only the elements in the sequence that pass the
`predicate`.
Iterates over the sequence, passing each element to the function `predicate`.
If it returns `true`, adds the element to the result list.
(1..10).where {|n| n % 2 == 1} // [1, 3, 5, 7, 9].