fix #17159 items(cstring) works in VM (#17160)

* fix #17159 items(cstring) works in VM

* improve test coverage tests/stdlib/tcstring.nim; add helpers: whenRuntimeJs, whenVMorJs

* document items(cstring)

* address comments
This commit is contained in:
Timothee Cour 2021-02-24 05:01:06 -08:00 • committed by GitHub
commit 11a7fa68f6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 155 additions and 43 deletions

View file

@ -56,31 +56,62 @@ iterator items*[T](a: set[T]): T {.inline.} =
iterator items*(a: cstring): char {.inline.} =
## Iterates over each item of `a`.
when defined(js):
runnableExamples:
from std/sequtils import toSeq
assert toSeq("abc\0def".cstring) == @['a', 'b', 'c']
assert toSeq("abc".cstring) == @['a', 'b', 'c']
#[
assert toSeq(nil.cstring) == @[] # xxx fails with SIGSEGV
this fails with SIGSEGV; unclear whether we want to instead yield nothing
or pay a small price to check for `nil`, a benchmark is needed. Note that
other procs support `nil`.
]#
template impl() =
var i = 0
var L = len(a)
while i < L:
let n = len(a)
while i < n:
yield a[i]
inc(i)
when defined(js): impl()
else:
var i = 0
while a[i] != '\0':
yield a[i]
inc(i)
when nimvm:
# xxx `cstring` should behave like c backend instead.
impl()
else:
var i = 0
while a[i] != '\0':
yield a[i]
inc(i)
iterator mitems*(a: var cstring): var char {.inline.} =
## Iterates over each item of `a` so that you can modify the yielded value.
when defined(js):
# xxx this should give CT error in js RT.
runnableExamples:
from std/sugar import collect
var a = "abc\0def"
var b = a.cstring
let s = collect:
for bi in mitems(b):
if bi == 'b': bi = 'B'
bi
assert s == @['a', 'B', 'c']
assert b == "aBc"
assert a == "aBc\0def"
template impl() =
var i = 0
var L = len(a)
while i < L:
let n = len(a)
while i < n:
yield a[i]
inc(i)
when defined(js): impl()
else:
var i = 0
while a[i] != '\0':
yield a[i]
inc(i)
when nimvm: impl()
else:
var i = 0
while a[i] != '\0':
yield a[i]
inc(i)
iterator items*[T: enum and Ordinal](E: typedesc[T]): T =
## Iterates over the values of `E`.