* 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:
parent
3021252ad4
commit
11a7fa68f6
4 changed files with 155 additions and 43 deletions
|
|
@ -56,31 +56,62 @@ iterator items*[T](a: set[T]): T {.inline.} =
|
||||||
|
|
||||||
iterator items*(a: cstring): char {.inline.} =
|
iterator items*(a: cstring): char {.inline.} =
|
||||||
## Iterates over each item of `a`.
|
## 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 i = 0
|
||||||
var L = len(a)
|
let n = len(a)
|
||||||
while i < L:
|
while i < n:
|
||||||
yield a[i]
|
yield a[i]
|
||||||
inc(i)
|
inc(i)
|
||||||
|
when defined(js): impl()
|
||||||
else:
|
else:
|
||||||
var i = 0
|
when nimvm:
|
||||||
while a[i] != '\0':
|
# xxx `cstring` should behave like c backend instead.
|
||||||
yield a[i]
|
impl()
|
||||||
inc(i)
|
else:
|
||||||
|
var i = 0
|
||||||
|
while a[i] != '\0':
|
||||||
|
yield a[i]
|
||||||
|
inc(i)
|
||||||
|
|
||||||
iterator mitems*(a: var cstring): var char {.inline.} =
|
iterator mitems*(a: var cstring): var char {.inline.} =
|
||||||
## Iterates over each item of `a` so that you can modify the yielded value.
|
## 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 i = 0
|
||||||
var L = len(a)
|
let n = len(a)
|
||||||
while i < L:
|
while i < n:
|
||||||
yield a[i]
|
yield a[i]
|
||||||
inc(i)
|
inc(i)
|
||||||
|
when defined(js): impl()
|
||||||
else:
|
else:
|
||||||
var i = 0
|
when nimvm: impl()
|
||||||
while a[i] != '\0':
|
else:
|
||||||
yield a[i]
|
var i = 0
|
||||||
inc(i)
|
while a[i] != '\0':
|
||||||
|
yield a[i]
|
||||||
|
inc(i)
|
||||||
|
|
||||||
iterator items*[T: enum and Ordinal](E: typedesc[T]): T =
|
iterator items*[T: enum and Ordinal](E: typedesc[T]): T =
|
||||||
## Iterates over the values of `E`.
|
## Iterates over the values of `E`.
|
||||||
|
|
|
||||||
|
|
@ -42,3 +42,27 @@ template enableRemoteNetworking*: bool =
|
||||||
## process calls, e.g. `testament all` calls itself, which in turns invokes
|
## process calls, e.g. `testament all` calls itself, which in turns invokes
|
||||||
## a `nim` invocation (possibly via additional intermediate processes).
|
## a `nim` invocation (possibly via additional intermediate processes).
|
||||||
getEnv("NIM_TESTAMENT_REMOTE_NETWORKING") == "1"
|
getEnv("NIM_TESTAMENT_REMOTE_NETWORKING") == "1"
|
||||||
|
|
||||||
|
template whenRuntimeJs*(bodyIf, bodyElse) =
|
||||||
|
##[
|
||||||
|
Behaves as `when defined(js) and not nimvm` (which isn't legal yet).
|
||||||
|
pending improvements to `nimvm`, this sugar helps; use as follows:
|
||||||
|
|
||||||
|
whenRuntimeJs:
|
||||||
|
doAssert defined(js)
|
||||||
|
when nimvm: doAssert false
|
||||||
|
else: discard
|
||||||
|
do:
|
||||||
|
discard
|
||||||
|
]##
|
||||||
|
when nimvm: bodyElse
|
||||||
|
else:
|
||||||
|
when defined(js): bodyIf
|
||||||
|
else: bodyElse
|
||||||
|
|
||||||
|
template whenVMorJs*(bodyIf, bodyElse) =
|
||||||
|
## Behaves as: `when defined(js) or nimvm`
|
||||||
|
when nimvm: bodyIf
|
||||||
|
else:
|
||||||
|
when defined(js): bodyIf
|
||||||
|
else: bodyElse
|
||||||
|
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
discard """
|
|
||||||
cmd: "nim c --gc:arc -r $file"
|
|
||||||
nimout: '''hello
|
|
||||||
h
|
|
||||||
o
|
|
||||||
'''
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Issue #13321: [codegen] --gc:arc does not properly emit cstring, results in SIGSEGV
|
|
||||||
|
|
||||||
let a = "hello".cstring
|
|
||||||
echo a
|
|
||||||
echo a[0]
|
|
||||||
echo a[4]
|
|
||||||
doAssert a[a.len] == '\0'
|
|
||||||
|
|
||||||
|
|
@ -1,19 +1,92 @@
|
||||||
discard """
|
discard """
|
||||||
targets: "c cpp js"
|
targets: "c cpp js"
|
||||||
|
matrix: "; --gc:arc"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from std/sugar import collect
|
||||||
|
from stdtest/testutils import whenRuntimeJs, whenVMorJs
|
||||||
|
|
||||||
block: # bug #13859
|
template testMitems() =
|
||||||
let str = "abc".cstring
|
block:
|
||||||
doAssert len(str).int8 == 3
|
var a = "abc"
|
||||||
doAssert len(str).int16 == 3
|
var b = a.cstring
|
||||||
doAssert len(str).int32 == 3
|
let s = collect:
|
||||||
var str2 = "cde".cstring
|
for bi in mitems(b):
|
||||||
doAssert len(str2).int8 == 3
|
if bi == 'b': bi = 'B'
|
||||||
doAssert len(str2).int16 == 3
|
bi
|
||||||
doAssert len(str2).int32 == 3
|
whenRuntimeJs:
|
||||||
|
discard # xxx mitems should give CT error instead of @['\x00', '\x00', '\x00']
|
||||||
|
do:
|
||||||
|
doAssert s == @['a', 'B', 'c']
|
||||||
|
|
||||||
const str3 = "abc".cstring
|
block:
|
||||||
doAssert len(str3).int32 == 3
|
var a = "abc\0def"
|
||||||
doAssert len("abc".cstring).int16 == 3
|
var b = a.cstring
|
||||||
doAssert len("abc".cstring).float32 == 3.0
|
let s = collect:
|
||||||
|
for bi in mitems(b):
|
||||||
|
if bi == 'b': bi = 'B'
|
||||||
|
bi
|
||||||
|
whenRuntimeJs:
|
||||||
|
discard # ditto
|
||||||
|
do:
|
||||||
|
doAssert s == @['a', 'B', 'c']
|
||||||
|
|
||||||
|
proc mainProc() =
|
||||||
|
testMitems()
|
||||||
|
|
||||||
|
template main() =
|
||||||
|
block: # bug #13859
|
||||||
|
let str = "abc".cstring
|
||||||
|
doAssert len(str).int8 == 3
|
||||||
|
doAssert len(str).int16 == 3
|
||||||
|
doAssert len(str).int32 == 3
|
||||||
|
var str2 = "cde".cstring
|
||||||
|
doAssert len(str2).int8 == 3
|
||||||
|
doAssert len(str2).int16 == 3
|
||||||
|
doAssert len(str2).int32 == 3
|
||||||
|
|
||||||
|
const str3 = "abc".cstring
|
||||||
|
doAssert len(str3).int32 == 3
|
||||||
|
doAssert len("abc".cstring).int16 == 3
|
||||||
|
doAssert len("abc".cstring).float32 == 3.0
|
||||||
|
|
||||||
|
block: # bug #17159
|
||||||
|
block:
|
||||||
|
var a = "abc"
|
||||||
|
var b = a.cstring
|
||||||
|
doAssert $(b, ) == """("abc",)"""
|
||||||
|
let s = collect:
|
||||||
|
for bi in b: bi
|
||||||
|
doAssert s == @['a', 'b', 'c']
|
||||||
|
|
||||||
|
block:
|
||||||
|
var a = "abc\0def"
|
||||||
|
var b = a.cstring
|
||||||
|
let s = collect:
|
||||||
|
for bi in b: bi
|
||||||
|
whenRuntimeJs:
|
||||||
|
doAssert $(b, ) == """("abc\x00def",)"""
|
||||||
|
doAssert s == @['a', 'b', 'c', '\x00', 'd', 'e', 'f']
|
||||||
|
do:
|
||||||
|
doAssert $(b, ) == """("abc",)"""
|
||||||
|
doAssert s == @['a', 'b', 'c']
|
||||||
|
|
||||||
|
block:
|
||||||
|
when defined(gcArc): # xxx SIGBUS
|
||||||
|
discard
|
||||||
|
else:
|
||||||
|
mainProc()
|
||||||
|
when false: # xxx bug vm: Error: unhandled exception: 'node' is not accessible using discriminant 'kind' of type 'TFullReg' [FieldDefect]
|
||||||
|
testMitems()
|
||||||
|
|
||||||
|
block: # bug #13321: [codegen] --gc:arc does not properly emit cstring, results in SIGSEGV
|
||||||
|
let a = "hello".cstring
|
||||||
|
doAssert $a == "hello"
|
||||||
|
doAssert $a[0] == "h"
|
||||||
|
doAssert $a[4] == "o"
|
||||||
|
whenVMorJs: discard # xxx this should work in vm, refs https://github.com/timotheecour/Nim/issues/619
|
||||||
|
do:
|
||||||
|
doAssert a[a.len] == '\0'
|
||||||
|
|
||||||
|
static: main()
|
||||||
|
main()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue