Merge branch 'devel' of github.com:nim-lang/Nim into devel
This commit is contained in:
commit
49a00fe6ff
15 changed files with 223 additions and 35 deletions
|
|
@ -253,7 +253,7 @@ compiler tcc:
|
||||||
compilerExe: "tcc",
|
compilerExe: "tcc",
|
||||||
cppCompiler: "",
|
cppCompiler: "",
|
||||||
compileTmpl: "-c $options $include -o $objfile $file",
|
compileTmpl: "-c $options $include -o $objfile $file",
|
||||||
buildGui: "UNAVAILABLE!",
|
buildGui: "-Wl,-subsystem=gui",
|
||||||
buildDll: " -shared",
|
buildDll: " -shared",
|
||||||
buildLib: "", # XXX: not supported yet
|
buildLib: "", # XXX: not supported yet
|
||||||
linkerExe: "tcc",
|
linkerExe: "tcc",
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
import
|
import
|
||||||
strutils, ast, astalgo, types, msgs, renderer, vmdef,
|
strutils, ast, astalgo, types, msgs, renderer, vmdef,
|
||||||
trees, intsets, rodread, magicsys, options, lowerings
|
trees, intsets, rodread, magicsys, options, lowerings
|
||||||
|
import platform
|
||||||
from os import splitFile
|
from os import splitFile
|
||||||
|
|
||||||
when hasFFI:
|
when hasFFI:
|
||||||
|
|
@ -761,6 +761,49 @@ proc genCard(c: PCtx; n: PNode; dest: var TDest) =
|
||||||
c.gABC(n, opcCard, dest, tmp)
|
c.gABC(n, opcCard, dest, tmp)
|
||||||
c.freeTemp(tmp)
|
c.freeTemp(tmp)
|
||||||
|
|
||||||
|
proc genIntCast(c: PCtx; n: PNode; dest: var TDest) =
|
||||||
|
const allowedIntegers = {tyInt..tyInt64, tyUInt..tyUInt64, tyChar}
|
||||||
|
var signedIntegers = {tyInt8..tyInt32}
|
||||||
|
var unsignedIntegers = {tyUInt8..tyUInt32, tyChar}
|
||||||
|
let src = n.sons[1].typ.skipTypes(abstractRange)#.kind
|
||||||
|
let dst = n.sons[0].typ.skipTypes(abstractRange)#.kind
|
||||||
|
let src_size = src.getSize
|
||||||
|
|
||||||
|
if platform.intSize < 8:
|
||||||
|
signedIntegers.incl(tyInt)
|
||||||
|
unsignedIntegers.incl(tyUInt)
|
||||||
|
if src_size == dst.getSize and src.kind in allowedIntegers and
|
||||||
|
dst.kind in allowedIntegers:
|
||||||
|
let tmp = c.genx(n.sons[1])
|
||||||
|
var tmp2 = c.getTemp(n.sons[1].typ)
|
||||||
|
let tmp3 = c.getTemp(n.sons[1].typ)
|
||||||
|
if dest < 0: dest = c.getTemp(n[0].typ)
|
||||||
|
proc mkIntLit(ival: int): int =
|
||||||
|
result = genLiteral(c, newIntTypeNode(nkIntLit, ival, getSysType(tyInt)))
|
||||||
|
if src.kind in unsignedIntegers and dst.kind in signedIntegers:
|
||||||
|
# cast unsigned to signed integer of same size
|
||||||
|
# signedVal = (unsignedVal xor offset) -% offset
|
||||||
|
let offset = 1 shl (src_size * 8 - 1)
|
||||||
|
c.gABx(n, opcLdConst, tmp2, mkIntLit(offset))
|
||||||
|
c.gABC(n, opcBitxorInt, tmp3, tmp, tmp2)
|
||||||
|
c.gABC(n, opcSubInt, dest, tmp3, tmp2)
|
||||||
|
elif src.kind in signedIntegers and dst.kind in unsignedIntegers:
|
||||||
|
# cast signed to unsigned integer of same size
|
||||||
|
# unsignedVal = (offset +% signedVal +% 1) and offset
|
||||||
|
let offset = (1 shl (src_size * 8)) - 1
|
||||||
|
c.gABx(n, opcLdConst, tmp2, mkIntLit(offset))
|
||||||
|
c.gABx(n, opcLdConst, dest, mkIntLit(offset+1))
|
||||||
|
c.gABC(n, opcAddu, tmp3, tmp, dest)
|
||||||
|
c.gABC(n, opcNarrowU, tmp3, TRegister(src_size*8))
|
||||||
|
c.gABC(n, opcBitandInt, dest, tmp3, tmp2)
|
||||||
|
else:
|
||||||
|
c.gABC(n, opcAsgnInt, dest, tmp)
|
||||||
|
c.freeTemp(tmp)
|
||||||
|
c.freeTemp(tmp2)
|
||||||
|
c.freeTemp(tmp3)
|
||||||
|
else:
|
||||||
|
globalError(n.info, errGenerated, "VM is only allowed to 'cast' between integers of same size")
|
||||||
|
|
||||||
proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
|
proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
|
||||||
case m
|
case m
|
||||||
of mAnd: c.genAndOr(n, opcFJmp, dest)
|
of mAnd: c.genAndOr(n, opcFJmp, dest)
|
||||||
|
|
@ -1844,7 +1887,7 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
|
||||||
if allowCast in c.features:
|
if allowCast in c.features:
|
||||||
genConv(c, n, n.sons[1], dest, opcCast)
|
genConv(c, n, n.sons[1], dest, opcCast)
|
||||||
else:
|
else:
|
||||||
globalError(n.info, errGenerated, "VM is not allowed to 'cast'")
|
genIntCast(c, n, dest)
|
||||||
of nkTypeOfExpr:
|
of nkTypeOfExpr:
|
||||||
genTypeLit(c, n.typ, dest)
|
genTypeLit(c, n.typ, dest)
|
||||||
of nkComesFrom:
|
of nkComesFrom:
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,10 @@ Collections and algorithms
|
||||||
* `sequtils <sequtils.html>`_
|
* `sequtils <sequtils.html>`_
|
||||||
This module implements operations for the built-in seq type
|
This module implements operations for the built-in seq type
|
||||||
which were inspired by functional programming languages.
|
which were inspired by functional programming languages.
|
||||||
|
* `sharedtables <sharedtables.html>`_
|
||||||
|
Nim shared hash table support. Contains shared tables.
|
||||||
|
* `sharedlist <sharedlist.html>`_
|
||||||
|
Nim shared linked list support. Contains shared singly linked list.
|
||||||
|
|
||||||
|
|
||||||
String handling
|
String handling
|
||||||
|
|
|
||||||
|
|
@ -296,6 +296,10 @@ empty ``discard`` statement should be used.
|
||||||
For non ordinal types it is not possible to list every possible value and so
|
For non ordinal types it is not possible to list every possible value and so
|
||||||
these always require an ``else`` part.
|
these always require an ``else`` part.
|
||||||
|
|
||||||
|
As case statements perform compile-time exhaustiveness checks, the value in
|
||||||
|
every ``of`` branch must be known at compile time. This fact is also exploited
|
||||||
|
to generate more performant code.
|
||||||
|
|
||||||
As a special semantic extension, an expression in an ``of`` branch of a case
|
As a special semantic extension, an expression in an ``of`` branch of a case
|
||||||
statement may evaluate to a set or array constructor; the set or array is then
|
statement may evaluate to a set or array constructor; the set or array is then
|
||||||
expanded into a list of its elements:
|
expanded into a list of its elements:
|
||||||
|
|
|
||||||
|
|
@ -1487,7 +1487,7 @@ proc drain*(timeout = 500) =
|
||||||
## if there are no pending operations. In contrast to ``poll`` this
|
## if there are no pending operations. In contrast to ``poll`` this
|
||||||
## processes as many events as are available.
|
## processes as many events as are available.
|
||||||
if runOnce(timeout):
|
if runOnce(timeout):
|
||||||
while runOnce(0): discard
|
while hasPendingOperations() and runOnce(0): discard
|
||||||
|
|
||||||
proc poll*(timeout = 500) =
|
proc poll*(timeout = 500) =
|
||||||
## Waits for completion events and processes them. Raises ``ValueError``
|
## Waits for completion events and processes them. Raises ``ValueError``
|
||||||
|
|
|
||||||
|
|
@ -73,10 +73,10 @@ proc add*[A](x: var SharedList[A]; y: A) =
|
||||||
node.d[node.dataLen] = y
|
node.d[node.dataLen] = y
|
||||||
inc(node.dataLen)
|
inc(node.dataLen)
|
||||||
|
|
||||||
proc initSharedList*[A](): SharedList[A] =
|
proc init*[A](t: var SharedList[A]) =
|
||||||
initLock result.lock
|
initLock t.lock
|
||||||
result.head = nil
|
t.head = nil
|
||||||
result.tail = nil
|
t.tail = nil
|
||||||
|
|
||||||
proc clear*[A](t: var SharedList[A]) =
|
proc clear*[A](t: var SharedList[A]) =
|
||||||
withLock(t):
|
withLock(t):
|
||||||
|
|
@ -92,4 +92,11 @@ proc deinitSharedList*[A](t: var SharedList[A]) =
|
||||||
clear(t)
|
clear(t)
|
||||||
deinitLock t.lock
|
deinitLock t.lock
|
||||||
|
|
||||||
|
proc initSharedList*[A](): SharedList[A] {.deprecated.} =
|
||||||
|
## Deprecated. Use `init` instead.
|
||||||
|
## This is not posix compliant, may introduce undefined behavior.
|
||||||
|
initLock result.lock
|
||||||
|
result.head = nil
|
||||||
|
result.tail = nil
|
||||||
|
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
|
||||||
|
|
@ -192,19 +192,29 @@ proc del*[A, B](t: var SharedTable[A, B], key: A) =
|
||||||
withLock t:
|
withLock t:
|
||||||
delImpl()
|
delImpl()
|
||||||
|
|
||||||
proc initSharedTable*[A, B](initialSize=64): SharedTable[A, B] =
|
proc init*[A, B](t: var SharedTable[A, B], initialSize=64) =
|
||||||
## creates a new hash table that is empty.
|
## creates a new hash table that is empty.
|
||||||
##
|
##
|
||||||
## `initialSize` needs to be a power of two. If you need to accept runtime
|
## `initialSize` needs to be a power of two. If you need to accept runtime
|
||||||
## values for this you could use the ``nextPowerOfTwo`` proc from the
|
## values for this you could use the ``nextPowerOfTwo`` proc from the
|
||||||
## `math <math.html>`_ module or the ``rightSize`` proc from this module.
|
## `math <math.html>`_ module or the ``rightSize`` proc from this module.
|
||||||
assert isPowerOfTwo(initialSize)
|
assert isPowerOfTwo(initialSize)
|
||||||
|
t.counter = 0
|
||||||
|
t.dataLen = initialSize
|
||||||
|
t.data = cast[KeyValuePairSeq[A, B]](allocShared0(
|
||||||
|
sizeof(KeyValuePair[A, B]) * initialSize))
|
||||||
|
initLock t.lock
|
||||||
|
|
||||||
|
proc deinitSharedTable*[A, B](t: var SharedTable[A, B]) =
|
||||||
|
deallocShared(t.data)
|
||||||
|
deinitLock t.lock
|
||||||
|
|
||||||
|
proc initSharedTable*[A, B](initialSize=64): SharedTable[A, B] {.deprecated.} =
|
||||||
|
## Deprecated. Use `init` instead.
|
||||||
|
## This is not posix compliant, may introduce undefined behavior.
|
||||||
|
assert isPowerOfTwo(initialSize)
|
||||||
result.counter = 0
|
result.counter = 0
|
||||||
result.dataLen = initialSize
|
result.dataLen = initialSize
|
||||||
result.data = cast[KeyValuePairSeq[A, B]](allocShared0(
|
result.data = cast[KeyValuePairSeq[A, B]](allocShared0(
|
||||||
sizeof(KeyValuePair[A, B]) * initialSize))
|
sizeof(KeyValuePair[A, B]) * initialSize))
|
||||||
initLock result.lock
|
initLock result.lock
|
||||||
|
|
||||||
proc deinitSharedTable*[A, B](t: var SharedTable[A, B]) =
|
|
||||||
deallocShared(t.data)
|
|
||||||
deinitLock t.lock
|
|
||||||
|
|
|
||||||
|
|
@ -1352,29 +1352,42 @@ else:
|
||||||
proc fromSeconds*(since1970: float): Time {.tags: [], raises: [], benign, deprecated.} =
|
proc fromSeconds*(since1970: float): Time {.tags: [], raises: [], benign, deprecated.} =
|
||||||
## Takes a float which contains the number of seconds since the unix epoch and
|
## Takes a float which contains the number of seconds since the unix epoch and
|
||||||
## returns a time object.
|
## returns a time object.
|
||||||
|
##
|
||||||
|
## **Deprecated since v0.18.0:** use ``fromUnix`` instead
|
||||||
Time(since1970)
|
Time(since1970)
|
||||||
|
|
||||||
proc fromSeconds*(since1970: int64): Time {.tags: [], raises: [], benign, deprecated.} =
|
proc fromSeconds*(since1970: int64): Time {.tags: [], raises: [], benign, deprecated.} =
|
||||||
## Takes an int which contains the number of seconds since the unix epoch and
|
## Takes an int which contains the number of seconds since the unix epoch and
|
||||||
## returns a time object.
|
## returns a time object.
|
||||||
|
##
|
||||||
|
## **Deprecated since v0.18.0:** use ``fromUnix`` instead
|
||||||
Time(since1970)
|
Time(since1970)
|
||||||
|
|
||||||
proc toSeconds*(time: Time): float {.tags: [], raises: [], benign, deprecated.} =
|
proc toSeconds*(time: Time): float {.tags: [], raises: [], benign, deprecated.} =
|
||||||
## Returns the time in seconds since the unix epoch.
|
## Returns the time in seconds since the unix epoch.
|
||||||
|
##
|
||||||
|
## **Deprecated since v0.18.0:** use ``toUnix`` instead
|
||||||
float(time)
|
float(time)
|
||||||
|
|
||||||
proc getLocalTime*(time: Time): DateTime {.tags: [], raises: [], benign, deprecated.} =
|
proc getLocalTime*(time: Time): DateTime {.tags: [], raises: [], benign, deprecated.} =
|
||||||
## Converts the calendar time `time` to broken-time representation,
|
## Converts the calendar time `time` to broken-time representation,
|
||||||
## expressed relative to the user's specified time zone.
|
## expressed relative to the user's specified time zone.
|
||||||
|
##
|
||||||
|
## **Deprecated since v0.18.0:** use ``local`` instead
|
||||||
time.local
|
time.local
|
||||||
|
|
||||||
proc getGMTime*(time: Time): DateTime {.tags: [], raises: [], benign, deprecated.} =
|
proc getGMTime*(time: Time): DateTime {.tags: [], raises: [], benign, deprecated.} =
|
||||||
## Converts the calendar time `time` to broken-down time representation,
|
## Converts the calendar time `time` to broken-down time representation,
|
||||||
## expressed in Coordinated Universal Time (UTC).
|
## expressed in Coordinated Universal Time (UTC).
|
||||||
|
##
|
||||||
|
## **Deprecated since v0.18.0:** use ``utc`` instead
|
||||||
time.utc
|
time.utc
|
||||||
|
|
||||||
proc getTimezone*(): int {.tags: [TimeEffect], raises: [], benign, deprecated.} =
|
proc getTimezone*(): int {.tags: [TimeEffect], raises: [], benign, deprecated.} =
|
||||||
## Returns the offset of the local (non-DST) timezone in seconds west of UTC.
|
## Returns the offset of the local (non-DST) timezone in seconds west of UTC.
|
||||||
|
##
|
||||||
|
## **Deprecated since v0.18.0:** use ``now().utcOffset`` to get the current
|
||||||
|
## utc offset (including DST).
|
||||||
when defined(JS):
|
when defined(JS):
|
||||||
return newDate().getTimezoneOffset() * 60
|
return newDate().getTimezoneOffset() * 60
|
||||||
elif defined(freebsd) or defined(netbsd) or defined(openbsd):
|
elif defined(freebsd) or defined(netbsd) or defined(openbsd):
|
||||||
|
|
|
||||||
|
|
@ -318,7 +318,7 @@ proc initGC() =
|
||||||
init(gch.marked)
|
init(gch.marked)
|
||||||
init(gch.additionalRoots)
|
init(gch.additionalRoots)
|
||||||
when hasThreadSupport:
|
when hasThreadSupport:
|
||||||
gch.toDispose = initSharedList[pointer]()
|
init(gch.toDispose)
|
||||||
|
|
||||||
when useMarkForDebug or useBackupGc:
|
when useMarkForDebug or useBackupGc:
|
||||||
type
|
type
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ proc initGC() =
|
||||||
init(gch.additionalRoots)
|
init(gch.additionalRoots)
|
||||||
init(gch.greyStack)
|
init(gch.greyStack)
|
||||||
when hasThreadSupport:
|
when hasThreadSupport:
|
||||||
gch.toDispose = initSharedList[pointer]()
|
init(gch.toDispose)
|
||||||
|
|
||||||
# Which color to use for new objects is tricky: When we're marking,
|
# Which color to use for new objects is tricky: When we're marking,
|
||||||
# they have to be *white* so that everything is marked that is only
|
# they have to be *white* so that everything is marked that is only
|
||||||
|
|
|
||||||
|
|
@ -233,7 +233,7 @@ proc initGC() =
|
||||||
init(gch.allocated)
|
init(gch.allocated)
|
||||||
init(gch.marked)
|
init(gch.marked)
|
||||||
when hasThreadSupport:
|
when hasThreadSupport:
|
||||||
gch.toDispose = initSharedList[pointer]()
|
init(gch.toDispose)
|
||||||
|
|
||||||
proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: WalkOp) {.benign.} =
|
proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: WalkOp) {.benign.} =
|
||||||
var d = cast[ByteAddress](dest)
|
var d = cast[ByteAddress](dest)
|
||||||
|
|
|
||||||
|
|
@ -213,7 +213,8 @@ block clearCountTableTest:
|
||||||
assert t.len() == 0
|
assert t.len() == 0
|
||||||
|
|
||||||
block withKeyTest:
|
block withKeyTest:
|
||||||
var t = initSharedTable[int, int]()
|
var t: SharedTable[int, int]
|
||||||
|
t.init()
|
||||||
t.withKey(1) do (k: int, v: var int, pairExists: var bool):
|
t.withKey(1) do (k: int, v: var int, pairExists: var bool):
|
||||||
assert(v == 0)
|
assert(v == 0)
|
||||||
pairExists = true
|
pairExists = true
|
||||||
|
|
|
||||||
|
|
@ -290,20 +290,6 @@ proc compilerOutputTests(test: TTest, target: TTarget, given: var TSpec,
|
||||||
if given.err == reSuccess: inc(r.passed)
|
if given.err == reSuccess: inc(r.passed)
|
||||||
r.addResult(test, target, expectedmsg, givenmsg, given.err)
|
r.addResult(test, target, expectedmsg, givenmsg, given.err)
|
||||||
|
|
||||||
proc analyzeAndConsolidateOutput(s: string): string =
|
|
||||||
result = ""
|
|
||||||
let rows = s.splitLines
|
|
||||||
for i in 0 ..< rows.len:
|
|
||||||
if (let pos = find(rows[i], "Traceback (most recent call last)"); pos != -1):
|
|
||||||
result = substr(rows[i], pos) & "\n"
|
|
||||||
for i in i+1 ..< rows.len:
|
|
||||||
result.add rows[i] & "\n"
|
|
||||||
if not (rows[i] =~ peg"['(']+ '(' \d+ ')' \s+"):
|
|
||||||
return
|
|
||||||
elif (let pos = find(rows[i], "SIGSEGV: Illegal storage access."); pos != -1):
|
|
||||||
result = substr(rows[i], pos)
|
|
||||||
return
|
|
||||||
|
|
||||||
proc testSpec(r: var TResults, test: TTest, target = targetC) =
|
proc testSpec(r: var TResults, test: TTest, target = targetC) =
|
||||||
let tname = test.name.addFileExt(".nim")
|
let tname = test.name.addFileExt(".nim")
|
||||||
#echo "TESTING ", tname
|
#echo "TESTING ", tname
|
||||||
|
|
@ -376,8 +362,7 @@ proc testSpec(r: var TResults, test: TTest, target = targetC) =
|
||||||
if exitCode != expected.exitCode:
|
if exitCode != expected.exitCode:
|
||||||
r.addResult(test, target, "exitcode: " & $expected.exitCode,
|
r.addResult(test, target, "exitcode: " & $expected.exitCode,
|
||||||
"exitcode: " & $exitCode & "\n\nOutput:\n" &
|
"exitcode: " & $exitCode & "\n\nOutput:\n" &
|
||||||
analyzeAndConsolidateOutput(bufB),
|
bufB, reExitCodesDiffer)
|
||||||
reExitCodesDiffer)
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if bufB != expectedOut and expected.action != actionRunNoSpec:
|
if bufB != expectedOut and expected.action != actionRunNoSpec:
|
||||||
|
|
|
||||||
120
tests/vm/tcastint.nim
Normal file
120
tests/vm/tcastint.nim
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
discard """
|
||||||
|
file: "tcastint.nim"
|
||||||
|
output: "OK"
|
||||||
|
"""
|
||||||
|
|
||||||
|
type
|
||||||
|
Dollar = distinct int
|
||||||
|
XCoord = distinct int32
|
||||||
|
Digit = range[-9..0]
|
||||||
|
|
||||||
|
# those are necessary for comparisons below.
|
||||||
|
proc `==`(x, y: Dollar): bool {.borrow.}
|
||||||
|
proc `==`(x, y: XCoord): bool {.borrow.}
|
||||||
|
|
||||||
|
proc dummy[T](x: T): T = x
|
||||||
|
|
||||||
|
proc test() =
|
||||||
|
let U8 = 0b1011_0010'u8
|
||||||
|
let I8 = 0b1011_0010'i8
|
||||||
|
let C8 = 0b1011_0010'u8.char
|
||||||
|
let C8_1 = 0b1011_0011'u8.char
|
||||||
|
let U16 = 0b10100111_00101000'u16
|
||||||
|
let I16 = 0b10100111_00101000'i16
|
||||||
|
let U32 = 0b11010101_10011100_11011010_01010000'u32
|
||||||
|
let I32 = 0b11010101_10011100_11011010_01010000'i32
|
||||||
|
let U64A = 0b11000100_00111111_01111100_10001010_10011001_01001000_01111010_00010001'u64
|
||||||
|
let I64A = 0b11000100_00111111_01111100_10001010_10011001_01001000_01111010_00010001'i64
|
||||||
|
let U64B = 0b00110010_11011101_10001111_00101000_00000000_00000000_00000000_00000000'u64
|
||||||
|
let I64B = 0b00110010_11011101_10001111_00101000_00000000_00000000_00000000_00000000'i64
|
||||||
|
when sizeof(int) == 8:
|
||||||
|
let UX = U64A.uint
|
||||||
|
let IX = I64A.int
|
||||||
|
elif sizeof(int) == 4:
|
||||||
|
let UX = U32.uint
|
||||||
|
let IX = I32.int
|
||||||
|
elif sizeof(int) == 2:
|
||||||
|
let UX = U16.uint
|
||||||
|
let IX = I16.int
|
||||||
|
else:
|
||||||
|
let UX = U8.uint
|
||||||
|
let IX = I8.int
|
||||||
|
|
||||||
|
doAssert(cast[char](I8) == C8)
|
||||||
|
doAssert(cast[uint8](I8) == U8)
|
||||||
|
doAssert(cast[uint16](I16) == U16)
|
||||||
|
doAssert(cast[uint32](I32) == U32)
|
||||||
|
doAssert(cast[uint64](I64A) == U64A)
|
||||||
|
doAssert(cast[uint64](I64B) == U64B)
|
||||||
|
doAssert(cast[int8](U8) == I8)
|
||||||
|
doAssert(cast[int16](U16) == I16)
|
||||||
|
doAssert(cast[int32](U32) == I32)
|
||||||
|
doAssert(cast[int64](U64A) == I64A)
|
||||||
|
doAssert(cast[int64](U64B) == I64B)
|
||||||
|
doAssert(cast[uint](IX) == UX)
|
||||||
|
doAssert(cast[int](UX) == IX)
|
||||||
|
|
||||||
|
doAssert(cast[char](I8 + 1) == C8_1)
|
||||||
|
doAssert(cast[uint8](I8 + 1) == U8 + 1)
|
||||||
|
doAssert(cast[uint16](I16 + 1) == U16 + 1)
|
||||||
|
doAssert(cast[uint32](I32 + 1) == U32 + 1)
|
||||||
|
doAssert(cast[uint64](I64A + 1) == U64A + 1)
|
||||||
|
doAssert(cast[uint64](I64B + 1) == U64B + 1)
|
||||||
|
doAssert(cast[int8](U8 + 1) == I8 + 1)
|
||||||
|
doAssert(cast[int16](U16 + 1) == I16 + 1)
|
||||||
|
doAssert(cast[int32](U32 + 1) == I32 + 1)
|
||||||
|
doAssert(cast[int64](U64A + 1) == I64A + 1)
|
||||||
|
doAssert(cast[int64](U64B + 1) == I64B + 1)
|
||||||
|
doAssert(cast[uint](IX + 1) == UX + 1)
|
||||||
|
doAssert(cast[int](UX + 1) == IX + 1)
|
||||||
|
|
||||||
|
doAssert(cast[char](I8.dummy) == C8.dummy)
|
||||||
|
doAssert(cast[uint8](I8.dummy) == U8.dummy)
|
||||||
|
doAssert(cast[uint16](I16.dummy) == U16.dummy)
|
||||||
|
doAssert(cast[uint32](I32.dummy) == U32.dummy)
|
||||||
|
doAssert(cast[uint64](I64A.dummy) == U64A.dummy)
|
||||||
|
doAssert(cast[uint64](I64B.dummy) == U64B.dummy)
|
||||||
|
doAssert(cast[int8](U8.dummy) == I8.dummy)
|
||||||
|
doAssert(cast[int16](U16.dummy) == I16.dummy)
|
||||||
|
doAssert(cast[int32](U32.dummy) == I32.dummy)
|
||||||
|
doAssert(cast[int64](U64A.dummy) == I64A.dummy)
|
||||||
|
doAssert(cast[int64](U64B.dummy) == I64B.dummy)
|
||||||
|
doAssert(cast[uint](IX.dummy) == UX.dummy)
|
||||||
|
doAssert(cast[int](UX.dummy) == IX.dummy)
|
||||||
|
|
||||||
|
|
||||||
|
doAssert(cast[int64](if false: U64B else: 0'u64) == (if false: I64B else: 0'i64))
|
||||||
|
|
||||||
|
block:
|
||||||
|
let raw = 3
|
||||||
|
let money = Dollar(raw) # this must be a variable, is otherwise constant folded.
|
||||||
|
doAssert(cast[int](money) == raw)
|
||||||
|
doAssert(cast[Dollar](raw) == money)
|
||||||
|
block:
|
||||||
|
let raw = 150'i32
|
||||||
|
let position = XCoord(raw) # this must be a variable, is otherwise constant folded.
|
||||||
|
doAssert(cast[int32](position) == raw)
|
||||||
|
doAssert(cast[XCoord](raw) == position)
|
||||||
|
block:
|
||||||
|
let raw = -2
|
||||||
|
let digit = Digit(raw)
|
||||||
|
doAssert(cast[int](digit) == raw)
|
||||||
|
doAssert(cast[Digit](raw) == digit)
|
||||||
|
|
||||||
|
when defined nimvm:
|
||||||
|
doAssert(not compiles(cast[float](I64A)))
|
||||||
|
doAssert(not compiles(cast[float32](I64A)))
|
||||||
|
|
||||||
|
doAssert(not compiles(cast[char](I64A)))
|
||||||
|
doAssert(not compiles(cast[uint16](I64A)))
|
||||||
|
doAssert(not compiles(cast[uint32](I64A)))
|
||||||
|
|
||||||
|
doAssert(not compiles(cast[uint16](I8)))
|
||||||
|
doAssert(not compiles(cast[uint32](I8)))
|
||||||
|
doAssert(not compiles(cast[uint64](I8)))
|
||||||
|
|
||||||
|
test()
|
||||||
|
static:
|
||||||
|
test()
|
||||||
|
|
||||||
|
echo "OK"
|
||||||
|
|
@ -51,6 +51,7 @@ srcdoc2: "pure/ropes;pure/unidecode/unidecode;pure/xmldom;pure/xmldomparser"
|
||||||
srcdoc2: "pure/xmlparser;pure/htmlparser;pure/xmltree;pure/colors;pure/mimetypes"
|
srcdoc2: "pure/xmlparser;pure/htmlparser;pure/xmltree;pure/colors;pure/mimetypes"
|
||||||
srcdoc2: "pure/json;pure/base64;pure/scgi"
|
srcdoc2: "pure/json;pure/base64;pure/scgi"
|
||||||
srcdoc2: "pure/collections/tables;pure/collections/sets;pure/collections/lists"
|
srcdoc2: "pure/collections/tables;pure/collections/sets;pure/collections/lists"
|
||||||
|
srcdoc2: "pure/collections/sharedlist;pure/collections/sharedtables"
|
||||||
srcdoc2: "pure/collections/intsets;pure/collections/queues;pure/collections/deques;pure/encodings"
|
srcdoc2: "pure/collections/intsets;pure/collections/queues;pure/collections/deques;pure/encodings"
|
||||||
srcdoc2: "pure/events;pure/collections/sequtils;pure/cookies"
|
srcdoc2: "pure/events;pure/collections/sequtils;pure/cookies"
|
||||||
srcdoc2: "pure/memfiles;pure/subexes;pure/collections/critbits"
|
srcdoc2: "pure/memfiles;pure/subexes;pure/collections/critbits"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue