61ac06ab5f
Introduce fat function pointers (BuxFn {code, env}) so capturing closures
are heap-allocated per value in both bootstrap and selfhost. Expand
Array/Map/Set/String/Test/Result APIs, add proper tuple codegen and
error snippets with multi-char underlines, golden diagnostic tests, and
LSP diagnostics via buxc check.
111 lines
2.4 KiB
Plaintext
111 lines
2.4 KiB
Plaintext
module Std::Iter {
|
|
|
|
import Std::Array::*;
|
|
|
|
struct Iter<T> {
|
|
data: *T,
|
|
len: uint,
|
|
pos: uint,
|
|
}
|
|
|
|
/* Create an iterator from an Array */
|
|
func Array_Iter<T>(arr: *Array<T>) -> Iter<T> {
|
|
return Iter<T> { data: arr.data, len: arr.len, pos: 0 };
|
|
}
|
|
|
|
/* Check if there are more elements */
|
|
func Iter_HasNext<T>(it: *Iter<T>) -> bool {
|
|
return it.pos < it.len;
|
|
}
|
|
|
|
/* Get the next element and advance (undefined if HasNext is false) */
|
|
func Iter_Next<T>(it: *Iter<T>) -> T {
|
|
let val: T = it.data[it.pos];
|
|
it.pos = it.pos + 1;
|
|
return val;
|
|
}
|
|
|
|
/* Peek current element without advancing (undefined if HasNext is false) */
|
|
func Iter_Peek<T>(it: *Iter<T>) -> T {
|
|
return it.data[it.pos];
|
|
}
|
|
|
|
/* Reset iterator to the beginning */
|
|
func Iter_Reset<T>(it: *Iter<T>) {
|
|
it.pos = 0;
|
|
}
|
|
|
|
/* Current position */
|
|
func Iter_Pos<T>(it: *Iter<T>) -> uint {
|
|
return it.pos;
|
|
}
|
|
|
|
/* Remaining length */
|
|
func Iter_Len<T>(it: *Iter<T>) -> uint {
|
|
return it.len;
|
|
}
|
|
|
|
/* Count remaining elements */
|
|
func Iter_Count<T>(it: *Iter<T>) -> uint {
|
|
return it.len - it.pos;
|
|
}
|
|
|
|
/* Skip N elements */
|
|
func Iter_Skip<T>(it: *Iter<T>, n: uint) {
|
|
it.pos = it.pos + n;
|
|
if it.pos > it.len {
|
|
it.pos = it.len;
|
|
}
|
|
}
|
|
|
|
/* Take first N elements (by limiting len) */
|
|
func Iter_Take<T>(it: *Iter<T>, n: uint) -> Iter<T> {
|
|
var endPos: uint = it.pos + n;
|
|
if endPos > it.len {
|
|
endPos = it.len;
|
|
}
|
|
return Iter<T> { data: it.data, len: endPos, pos: it.pos };
|
|
}
|
|
|
|
/* True if any remaining element equals value */
|
|
func Iter_AnyEq<T>(it: *Iter<T>, value: T) -> bool {
|
|
var i: uint = it.pos;
|
|
while i < it.len {
|
|
if it.data[i] == value {
|
|
return true;
|
|
}
|
|
i = i + 1;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/* True if every remaining element equals value (true if empty) */
|
|
func Iter_AllEq<T>(it: *Iter<T>, value: T) -> bool {
|
|
var i: uint = it.pos;
|
|
while i < it.len {
|
|
if it.data[i] != value {
|
|
return false;
|
|
}
|
|
i = i + 1;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/* Collect remaining elements into a new Array */
|
|
func Iter_Collect<T>(it: *Iter<T>) -> Array<T> {
|
|
let remaining: uint = it.len - it.pos;
|
|
var cap: uint = remaining;
|
|
if cap == 0 {
|
|
cap = 1;
|
|
}
|
|
var arr: Array<T> = Array_New<T>(cap);
|
|
var i: uint = it.pos;
|
|
while i < it.len {
|
|
Array_Push<T>(&arr, it.data[i]);
|
|
i = i + 1;
|
|
}
|
|
return arr;
|
|
}
|
|
|
|
}
|