Hi,
i'm struggeling with the QuickJS-engine. The last thing to do is to make iteration on opaque-nim-types possible. The Iteration-API expects a C-function which delivers one element from a container per call. I need to use {.cdecl.} - so a inline-iterator won't work. I'm somewhat mentally blocked about how to achieve this ? I considered a callback, co-routine, fiber whatever works. So how can i make a nim-proc, that prbly. uses a nim-closure-iterator in the back, and delivers one item-per-call - a int from, e.g. a PackedSet[int]/IntSet ? Since i have to provide the proc to the API, everything can be constructed, designed as needed. As a last resort, i could change the quickjs-c-code, which has already been done by another user - but me and C, no,no that'll ruin it :) Every iteration must yield a result-object { done: bool, value: T }. The function is provided once and called until the result-object has done= false. So far nothing special. I spare the details how to declare/create the nim-proc, where to place JSCFunction, howto convert the types etc. - i figured all this out, already. I need to find a way to provide a {.cdecl.}-proc that uses a provided nim-iterator, 'cos afaik it's not possible to iterate a PackedSet[T] without the provided nim-iterator. greets and thx, Andreas
You could use a closure iterator that you iterate manually by "calling" it in your callback.
For example
import std/packedsets
var data = toPackedSet([1,2,3,4])
# Instantiate an anonymous iterator that captures `data`
var iterVar = iterator (): int =
for value in data:
yield value
type
IterResult[T] = object
done: bool
value: T
proc iterCallback(): IterResult[int] {.cdecl.} =
# a call to an iterator give next value
let value = iterVar()
# `finished` is a "magic" proc that is self-explanatory
return IterResult[int](done: iterVar.finished, value: value)
# Usage
while (let result = iterCallback(); not result.done ):
echo result.value
Manual: https://nim-lang.org/docs/manual.html#iterators-and-the-for-statement-firstminusclass-iterators