mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-27 17:53:58 +00:00
* 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:
@@ -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`.
|
||||
|
||||
@@ -42,3 +42,27 @@ template enableRemoteNetworking*: bool =
|
||||
## process calls, e.g. `testament all` calls itself, which in turns invokes
|
||||
## a `nim` invocation (possibly via additional intermediate processes).
|
||||
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 """
|
||||
targets: "c cpp js"
|
||||
matrix: "; --gc:arc"
|
||||
"""
|
||||
|
||||
from std/sugar import collect
|
||||
from stdtest/testutils import whenRuntimeJs, whenVMorJs
|
||||
|
||||
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
|
||||
template testMitems() =
|
||||
block:
|
||||
var a = "abc"
|
||||
var b = a.cstring
|
||||
let s = collect:
|
||||
for bi in mitems(b):
|
||||
if bi == 'b': bi = 'B'
|
||||
bi
|
||||
whenRuntimeJs:
|
||||
discard # xxx mitems should give CT error instead of @['\x00', '\x00', '\x00']
|
||||
do:
|
||||
doAssert s == @['a', 'B', 'c']
|
||||
|
||||
const str3 = "abc".cstring
|
||||
doAssert len(str3).int32 == 3
|
||||
doAssert len("abc".cstring).int16 == 3
|
||||
doAssert len("abc".cstring).float32 == 3.0
|
||||
block:
|
||||
var a = "abc\0def"
|
||||
var b = a.cstring
|
||||
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()
|
||||
|
||||
Reference in New Issue
Block a user