fix(hir_lower): generic monomorphization for cross-module generic calls
The old findGenericCalls second-pass only looked in non-generic functions and generated unresolved instances like Array_Get_T when generic funcs called other generic funcs. Removed it entirely. lowerExpr for ekCall now invokes generateMethodInstance directly for both explicit (ekGenericCall) and inferred generic calls. This ensures concrete instantiations are generated on-demand with correct typeSubst. Also added guard in resolveTypeExpr/substituteType to skip emitting C struct definitions for unresolved type parameters (e.g. Array<T> inside a generic function body before monomorphization). feat(std): add Std::Iter module - Array_Iter, Iter_Next, Iter_HasNext, Iter_Peek, Iter_Reset - Iter_Pos, Iter_Len, Iter_Count, Iter_Skip, Iter_Take docs: document Std::Iter in Stdlib.md examples: add iter.bux example tests: add _test_array regression test
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
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 };
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user