tyInt tyUint fit target int bit width (#20829)
This commit is contained in:
parent
a70d3abd37
commit
658b28dc57
17 changed files with 306 additions and 267 deletions
|
|
@ -373,14 +373,16 @@ proc concreteType(c: TCandidate, t: PType; f: PType = nil): PType =
|
||||||
else:
|
else:
|
||||||
result = t # Note: empty is valid here
|
result = t # Note: empty is valid here
|
||||||
|
|
||||||
proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
|
proc handleRange(c: PContext, f, a: PType, min, max: TTypeKind): TTypeRelation =
|
||||||
if a.kind == f.kind:
|
if a.kind == f.kind:
|
||||||
result = isEqual
|
result = isEqual
|
||||||
else:
|
else:
|
||||||
let ab = skipTypes(a, {tyRange})
|
let ab = skipTypes(a, {tyRange})
|
||||||
let k = ab.kind
|
let k = ab.kind
|
||||||
|
let nf = c.config.normalizeKind(f.kind)
|
||||||
|
let na = c.config.normalizeKind(k)
|
||||||
if k == f.kind: result = isSubrange
|
if k == f.kind: result = isSubrange
|
||||||
elif k == tyInt and f.kind in {tyRange, tyInt8..tyInt64,
|
elif k == tyInt and f.kind in {tyRange, tyInt..tyInt64,
|
||||||
tyUInt..tyUInt64} and
|
tyUInt..tyUInt64} and
|
||||||
isIntLit(ab) and getInt(ab.n) >= firstOrd(nil, f) and
|
isIntLit(ab) and getInt(ab.n) >= firstOrd(nil, f) and
|
||||||
getInt(ab.n) <= lastOrd(nil, f):
|
getInt(ab.n) <= lastOrd(nil, f):
|
||||||
|
|
@ -389,9 +391,13 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
|
||||||
# integer literal in the proper range; we want ``i16 + 4`` to stay an
|
# integer literal in the proper range; we want ``i16 + 4`` to stay an
|
||||||
# ``int16`` operation so we declare the ``4`` pseudo-equal to int16
|
# ``int16`` operation so we declare the ``4`` pseudo-equal to int16
|
||||||
result = isFromIntLit
|
result = isFromIntLit
|
||||||
elif f.kind == tyInt and k in {tyInt8..tyInt32}:
|
elif a.kind == tyInt and nf == c.config.targetSizeSignedToKind:
|
||||||
result = isIntConv
|
result = isIntConv
|
||||||
elif f.kind == tyUInt and k in {tyUInt8..tyUInt32}:
|
elif a.kind == tyUInt and nf == c.config.targetSizeUnsignedToKind:
|
||||||
|
result = isIntConv
|
||||||
|
elif f.kind == tyInt and na in {tyInt8 .. c.config.targetSizeSignedToKind}:
|
||||||
|
result = isIntConv
|
||||||
|
elif f.kind == tyUInt and na in {tyUInt8 .. c.config.targetSizeUnsignedToKind}:
|
||||||
result = isIntConv
|
result = isIntConv
|
||||||
elif k >= min and k <= max:
|
elif k >= min and k <= max:
|
||||||
result = isConvertible
|
result = isConvertible
|
||||||
|
|
@ -405,7 +411,7 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
|
||||||
result = isConvertible
|
result = isConvertible
|
||||||
else: result = isNone
|
else: result = isNone
|
||||||
|
|
||||||
proc isConvertibleToRange(f, a: PType): bool =
|
proc isConvertibleToRange(c: PContext, f, a: PType): bool =
|
||||||
if f.kind in {tyInt..tyInt64, tyUInt..tyUInt64} and
|
if f.kind in {tyInt..tyInt64, tyUInt..tyUInt64} and
|
||||||
a.kind in {tyInt..tyInt64, tyUInt..tyUInt64}:
|
a.kind in {tyInt..tyInt64, tyUInt..tyUInt64}:
|
||||||
case f.kind
|
case f.kind
|
||||||
|
|
@ -413,13 +419,14 @@ proc isConvertibleToRange(f, a: PType): bool =
|
||||||
of tyInt16: result = isIntLit(a) or a.kind in {tyInt8, tyInt16}
|
of tyInt16: result = isIntLit(a) or a.kind in {tyInt8, tyInt16}
|
||||||
of tyInt32: result = isIntLit(a) or a.kind in {tyInt8, tyInt16, tyInt32}
|
of tyInt32: result = isIntLit(a) or a.kind in {tyInt8, tyInt16, tyInt32}
|
||||||
# This is wrong, but seems like there's a lot of code that relies on it :(
|
# This is wrong, but seems like there's a lot of code that relies on it :(
|
||||||
of tyInt, tyUInt, tyUInt64: result = true
|
of tyInt, tyUInt: result = true
|
||||||
|
# of tyInt: result = isIntLit(a) or a.kind in {tyInt8 .. c.config.targetSizeSignedToKind}
|
||||||
of tyInt64: result = isIntLit(a) or a.kind in {tyInt8, tyInt16, tyInt32, tyInt, tyInt64}
|
of tyInt64: result = isIntLit(a) or a.kind in {tyInt8, tyInt16, tyInt32, tyInt, tyInt64}
|
||||||
of tyUInt8: result = isIntLit(a) or a.kind in {tyUInt8}
|
of tyUInt8: result = isIntLit(a) or a.kind in {tyUInt8}
|
||||||
of tyUInt16: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16}
|
of tyUInt16: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16}
|
||||||
of tyUInt32: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32}
|
of tyUInt32: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32}
|
||||||
#of tyUInt: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt}
|
# of tyUInt: result = isIntLit(a) or a.kind in {tyUInt8 .. c.config.targetSizeUnsignedToKind}
|
||||||
#of tyUInt64: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt, tyUInt64}
|
of tyUInt64: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt64}
|
||||||
else: result = false
|
else: result = false
|
||||||
elif f.kind in {tyFloat..tyFloat128}:
|
elif f.kind in {tyFloat..tyFloat128}:
|
||||||
# `isIntLit` is correct and should be used above as well, see PR:
|
# `isIntLit` is correct and should be used above as well, see PR:
|
||||||
|
|
@ -1148,18 +1155,18 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
||||||
let f = skipTypes(f, {tyRange})
|
let f = skipTypes(f, {tyRange})
|
||||||
if f.kind == a.kind and (f.kind != tyEnum or sameEnumTypes(f, a)):
|
if f.kind == a.kind and (f.kind != tyEnum or sameEnumTypes(f, a)):
|
||||||
result = isIntConv
|
result = isIntConv
|
||||||
elif isConvertibleToRange(f, a):
|
elif isConvertibleToRange(c.c, f, a):
|
||||||
result = isConvertible # a convertible to f
|
result = isConvertible # a convertible to f
|
||||||
of tyInt: result = handleRange(f, a, tyInt8, tyInt32)
|
of tyInt: result = handleRange(c.c, f, a, tyInt8, c.c.config.targetSizeSignedToKind)
|
||||||
of tyInt8: result = handleRange(f, a, tyInt8, tyInt8)
|
of tyInt8: result = handleRange(c.c, f, a, tyInt8, tyInt8)
|
||||||
of tyInt16: result = handleRange(f, a, tyInt8, tyInt16)
|
of tyInt16: result = handleRange(c.c, f, a, tyInt8, tyInt16)
|
||||||
of tyInt32: result = handleRange(f, a, tyInt8, tyInt32)
|
of tyInt32: result = handleRange(c.c, f, a, tyInt8, tyInt32)
|
||||||
of tyInt64: result = handleRange(f, a, tyInt, tyInt64)
|
of tyInt64: result = handleRange(c.c, f, a, tyInt, tyInt64)
|
||||||
of tyUInt: result = handleRange(f, a, tyUInt8, tyUInt32)
|
of tyUInt: result = handleRange(c.c, f, a, tyUInt8, c.c.config.targetSizeUnsignedToKind)
|
||||||
of tyUInt8: result = handleRange(f, a, tyUInt8, tyUInt8)
|
of tyUInt8: result = handleRange(c.c, f, a, tyUInt8, tyUInt8)
|
||||||
of tyUInt16: result = handleRange(f, a, tyUInt8, tyUInt16)
|
of tyUInt16: result = handleRange(c.c, f, a, tyUInt8, tyUInt16)
|
||||||
of tyUInt32: result = handleRange(f, a, tyUInt8, tyUInt32)
|
of tyUInt32: result = handleRange(c.c, f, a, tyUInt8, tyUInt32)
|
||||||
of tyUInt64: result = handleRange(f, a, tyUInt, tyUInt64)
|
of tyUInt64: result = handleRange(c.c, f, a, tyUInt, tyUInt64)
|
||||||
of tyFloat: result = handleFloatRange(f, a)
|
of tyFloat: result = handleFloatRange(f, a)
|
||||||
of tyFloat32: result = handleFloatRange(f, a)
|
of tyFloat32: result = handleFloatRange(f, a)
|
||||||
of tyFloat64: result = handleFloatRange(f, a)
|
of tyFloat64: result = handleFloatRange(f, a)
|
||||||
|
|
@ -2114,6 +2121,8 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType,
|
||||||
of isIntConv:
|
of isIntConv:
|
||||||
# I'm too lazy to introduce another ``*matches`` field, so we conflate
|
# I'm too lazy to introduce another ``*matches`` field, so we conflate
|
||||||
# ``isIntConv`` and ``isIntLit`` here:
|
# ``isIntConv`` and ``isIntLit`` here:
|
||||||
|
if f.skipTypes({tyRange}).kind notin {tyInt, tyUInt}:
|
||||||
|
inc(m.intConvMatches)
|
||||||
inc(m.intConvMatches)
|
inc(m.intConvMatches)
|
||||||
result = implicitConv(nkHiddenStdConv, f, arg, m, c)
|
result = implicitConv(nkHiddenStdConv, f, arg, m, c)
|
||||||
of isSubtype:
|
of isSubtype:
|
||||||
|
|
|
||||||
|
|
@ -753,8 +753,13 @@ proc firstOrd*(conf: ConfigRef; t: PType): Int128 =
|
||||||
assert(t.n.kind == nkRange)
|
assert(t.n.kind == nkRange)
|
||||||
result = getOrdValue(t.n[0])
|
result = getOrdValue(t.n[0])
|
||||||
of tyInt:
|
of tyInt:
|
||||||
if conf != nil and conf.target.intSize == 4:
|
if conf != nil:
|
||||||
result = toInt128(-2147483648)
|
case conf.target.intSize
|
||||||
|
of 8: result = toInt128(0x8000000000000000'i64)
|
||||||
|
of 4: result = toInt128(-2147483648)
|
||||||
|
of 2: result = toInt128(-32768)
|
||||||
|
of 1: result = toInt128(-128)
|
||||||
|
else: discard
|
||||||
else:
|
else:
|
||||||
result = toInt128(0x8000000000000000'i64)
|
result = toInt128(0x8000000000000000'i64)
|
||||||
of tyInt8: result = toInt128(-128)
|
of tyInt8: result = toInt128(-128)
|
||||||
|
|
@ -797,6 +802,29 @@ proc firstFloat*(t: PType): BiggestFloat =
|
||||||
internalError(newPartialConfigRef(), "invalid kind for firstFloat(" & $t.kind & ')')
|
internalError(newPartialConfigRef(), "invalid kind for firstFloat(" & $t.kind & ')')
|
||||||
NaN
|
NaN
|
||||||
|
|
||||||
|
proc targetSizeSignedToKind*(conf: ConfigRef): TTypeKind =
|
||||||
|
case conf.target.intSize
|
||||||
|
of 8: result = tyInt64
|
||||||
|
of 4: result = tyInt32
|
||||||
|
of 2: result = tyInt16
|
||||||
|
else: discard
|
||||||
|
|
||||||
|
proc targetSizeUnsignedToKind*(conf: ConfigRef): TTypeKind =
|
||||||
|
case conf.target.intSize
|
||||||
|
of 8: result = tyUInt64
|
||||||
|
of 4: result = tyUInt32
|
||||||
|
of 2: result = tyUInt16
|
||||||
|
else: discard
|
||||||
|
|
||||||
|
proc normalizeKind*(conf: ConfigRef, k: TTypeKind): TTypeKind =
|
||||||
|
case k
|
||||||
|
of tyInt:
|
||||||
|
result = conf.targetSizeSignedToKind()
|
||||||
|
of tyUInt:
|
||||||
|
result = conf.targetSizeUnsignedToKind()
|
||||||
|
else:
|
||||||
|
result = k
|
||||||
|
|
||||||
proc lastOrd*(conf: ConfigRef; t: PType): Int128 =
|
proc lastOrd*(conf: ConfigRef; t: PType): Int128 =
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyBool: result = toInt128(1'u)
|
of tyBool: result = toInt128(1'u)
|
||||||
|
|
@ -808,7 +836,13 @@ proc lastOrd*(conf: ConfigRef; t: PType): Int128 =
|
||||||
assert(t.n.kind == nkRange)
|
assert(t.n.kind == nkRange)
|
||||||
result = getOrdValue(t.n[1])
|
result = getOrdValue(t.n[1])
|
||||||
of tyInt:
|
of tyInt:
|
||||||
if conf != nil and conf.target.intSize == 4: result = toInt128(0x7FFFFFFF)
|
if conf != nil:
|
||||||
|
case conf.target.intSize
|
||||||
|
of 8: result = toInt128(0x7FFFFFFFFFFFFFFF'u64)
|
||||||
|
of 4: result = toInt128(0x7FFFFFFF)
|
||||||
|
of 2: result = toInt128(0x00007FFF)
|
||||||
|
of 1: result = toInt128(0x0000007F)
|
||||||
|
else: discard
|
||||||
else: result = toInt128(0x7FFFFFFFFFFFFFFF'u64)
|
else: result = toInt128(0x7FFFFFFFFFFFFFFF'u64)
|
||||||
of tyInt8: result = toInt128(0x0000007F)
|
of tyInt8: result = toInt128(0x0000007F)
|
||||||
of tyInt16: result = toInt128(0x00007FFF)
|
of tyInt16: result = toInt128(0x00007FFF)
|
||||||
|
|
|
||||||
|
|
@ -28,11 +28,11 @@ proc writeFloatToBufferRoundtrip*(buf: var array[65, char]; value: BiggestFloat)
|
||||||
##
|
##
|
||||||
## returns the amount of bytes written to `buf` not counting the
|
## returns the amount of bytes written to `buf` not counting the
|
||||||
## terminating '\0' character.
|
## terminating '\0' character.
|
||||||
result = toChars(buf, value, forceTrailingDotZero=true)
|
result = toChars(buf, value, forceTrailingDotZero=true).int
|
||||||
buf[result] = '\0'
|
buf[result] = '\0'
|
||||||
|
|
||||||
proc writeFloatToBufferRoundtrip*(buf: var array[65, char]; value: float32): int =
|
proc writeFloatToBufferRoundtrip*(buf: var array[65, char]; value: float32): int =
|
||||||
result = float32ToChars(buf, value, forceTrailingDotZero=true)
|
result = float32ToChars(buf, value, forceTrailingDotZero=true).int
|
||||||
buf[result] = '\0'
|
buf[result] = '\0'
|
||||||
|
|
||||||
proc c_sprintf(buf, frmt: cstring): cint {.header: "<stdio.h>",
|
proc c_sprintf(buf, frmt: cstring): cint {.header: "<stdio.h>",
|
||||||
|
|
@ -49,7 +49,7 @@ proc writeFloatToBufferSprintf*(buf: var array[65, char]; value: BiggestFloat):
|
||||||
##
|
##
|
||||||
## returns the amount of bytes written to `buf` not counting the
|
## returns the amount of bytes written to `buf` not counting the
|
||||||
## terminating '\0' character.
|
## terminating '\0' character.
|
||||||
var n: int = c_sprintf(cast[cstring](addr buf), "%.16g", value)
|
var n = c_sprintf(cast[cstring](addr buf), "%.16g", value).int
|
||||||
var hasDot = false
|
var hasDot = false
|
||||||
for i in 0..n-1:
|
for i in 0..n-1:
|
||||||
if buf[i] == ',':
|
if buf[i] == ',':
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ proc utoa2Digits*(buf: var openArray[char]; pos: int; digits: uint32) {.inline.}
|
||||||
#copyMem(buf, unsafeAddr(digits100[2 * digits]), 2 * sizeof((char)))
|
#copyMem(buf, unsafeAddr(digits100[2 * digits]), 2 * sizeof((char)))
|
||||||
|
|
||||||
proc trailingZeros2Digits*(digits: uint32): int32 {.inline.} =
|
proc trailingZeros2Digits*(digits: uint32): int32 {.inline.} =
|
||||||
return trailingZeros100[digits]
|
return trailingZeros100[digits.int8]
|
||||||
|
|
||||||
when defined(js):
|
when defined(js):
|
||||||
proc numToString(a: SomeInteger): cstring {.importjs: "((#) + \"\")".}
|
proc numToString(a: SomeInteger): cstring {.importjs: "((#) + \"\")".}
|
||||||
|
|
@ -63,14 +63,14 @@ func addIntImpl(result: var string, x: uint64) {.inline.} =
|
||||||
while num >= nbatch:
|
while num >= nbatch:
|
||||||
let originNum = num
|
let originNum = num
|
||||||
num = num div nbatch
|
num = num div nbatch
|
||||||
let index = (originNum - num * nbatch) shl 1
|
let index = int16((originNum - num * nbatch) shl 1)
|
||||||
tmp[next] = digits100[index + 1]
|
tmp[next] = digits100[index + 1]
|
||||||
tmp[next - 1] = digits100[index]
|
tmp[next - 1] = digits100[index]
|
||||||
dec(next, 2)
|
dec(next, 2)
|
||||||
|
|
||||||
# process last 1-2 digits
|
# process last 1-2 digits
|
||||||
if num < 10:
|
if num < 10:
|
||||||
tmp[next] = chr(ord('0') + num)
|
tmp[next] = chr(ord('0') + num.uint8)
|
||||||
else:
|
else:
|
||||||
let index = num * 2
|
let index = num * 2
|
||||||
tmp[next] = digits100[index + 1]
|
tmp[next] = digits100[index + 1]
|
||||||
|
|
|
||||||
|
|
@ -1146,7 +1146,7 @@ proc printDecimalDigitsBackwards*(buf: var openArray[char]; pos: int; output64:
|
||||||
buf[pos] = chr(ord('0') + q)
|
buf[pos] = chr(ord('0') + q)
|
||||||
return tz
|
return tz
|
||||||
|
|
||||||
proc decimalLength*(v: uint64): int32 {.inline.} =
|
proc decimalLength*(v: uint64): int {.inline.} =
|
||||||
dragonbox_Assert(v >= 1)
|
dragonbox_Assert(v >= 1)
|
||||||
dragonbox_Assert(v <= 99999999999999999'u64)
|
dragonbox_Assert(v <= 99999999999999999'u64)
|
||||||
if cast[uint32](v shr 32) != 0:
|
if cast[uint32](v shr 32) != 0:
|
||||||
|
|
@ -1166,48 +1166,48 @@ proc decimalLength*(v: uint64): int32 {.inline.} =
|
||||||
return 11
|
return 11
|
||||||
return 10
|
return 10
|
||||||
let v32: uint32 = cast[uint32](v)
|
let v32: uint32 = cast[uint32](v)
|
||||||
if v32 >= 1000000000'u:
|
if v32 >= 1000000000'u32:
|
||||||
return 10
|
return 10
|
||||||
if v32 >= 100000000'u:
|
if v32 >= 100000000'u32:
|
||||||
return 9
|
return 9
|
||||||
if v32 >= 10000000'u:
|
if v32 >= 10000000'u32:
|
||||||
return 8
|
return 8
|
||||||
if v32 >= 1000000'u:
|
if v32 >= 1000000'u32:
|
||||||
return 7
|
return 7
|
||||||
if v32 >= 100000'u:
|
if v32 >= 100000'u32:
|
||||||
return 6
|
return 6
|
||||||
if v32 >= 10000'u:
|
if v32 >= 10000'u32:
|
||||||
return 5
|
return 5
|
||||||
if v32 >= 1000'u:
|
if v32 >= 1000'u32:
|
||||||
return 4
|
return 4
|
||||||
if v32 >= 100'u:
|
if v32 >= 100'u32:
|
||||||
return 3
|
return 3
|
||||||
if v32 >= 10'u:
|
if v32 >= 10'u32:
|
||||||
return 2
|
return 2
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
proc formatDigits*(buffer: var openArray[char]; pos: int; digits: uint64; decimalExponent: int32;
|
proc formatDigits*[T: Ordinal](buffer: var openArray[char]; pos: T; digits: uint64; decimalExponent: int;
|
||||||
forceTrailingDotZero = false): int {.inline.} =
|
forceTrailingDotZero = false): int {.inline.} =
|
||||||
const
|
const
|
||||||
minFixedDecimalPoint: int32 = -6
|
minFixedDecimalPoint = -6
|
||||||
const
|
const
|
||||||
maxFixedDecimalPoint: int32 = 17
|
maxFixedDecimalPoint = 17
|
||||||
var pos = pos
|
var pos:int = pos.int
|
||||||
assert(minFixedDecimalPoint <= -1, "internal error")
|
assert(minFixedDecimalPoint <= -1, "internal error")
|
||||||
assert(maxFixedDecimalPoint >= 17, "internal error")
|
assert(maxFixedDecimalPoint >= 17, "internal error")
|
||||||
dragonbox_Assert(digits >= 1)
|
dragonbox_Assert(digits >= 1)
|
||||||
dragonbox_Assert(digits <= 99999999999999999'u64)
|
dragonbox_Assert(digits <= 99999999999999999'u64)
|
||||||
dragonbox_Assert(decimalExponent >= -999)
|
dragonbox_Assert(decimalExponent >= -999)
|
||||||
dragonbox_Assert(decimalExponent <= 999)
|
dragonbox_Assert(decimalExponent <= 999)
|
||||||
var numDigits: int32 = decimalLength(digits)
|
var numDigits = decimalLength(digits)
|
||||||
let decimalPoint: int32 = numDigits + decimalExponent
|
let decimalPoint = numDigits + decimalExponent
|
||||||
let useFixed: bool = minFixedDecimalPoint <= decimalPoint and
|
let useFixed: bool = minFixedDecimalPoint <= decimalPoint and
|
||||||
decimalPoint <= maxFixedDecimalPoint
|
decimalPoint <= maxFixedDecimalPoint
|
||||||
## Prepare the buffer.
|
## Prepare the buffer.
|
||||||
for i in 0..<32: buffer[pos+i] = '0'
|
for i in 0..<32: buffer[pos+i] = '0'
|
||||||
assert(minFixedDecimalPoint >= -30, "internal error")
|
assert(minFixedDecimalPoint >= -30, "internal error")
|
||||||
assert(maxFixedDecimalPoint <= 32, "internal error")
|
assert(maxFixedDecimalPoint <= 32, "internal error")
|
||||||
var decimalDigitsPosition: int32
|
var decimalDigitsPosition: int
|
||||||
if useFixed:
|
if useFixed:
|
||||||
if decimalPoint <= 0:
|
if decimalPoint <= 0:
|
||||||
## 0.[000]digits
|
## 0.[000]digits
|
||||||
|
|
@ -1258,7 +1258,7 @@ proc formatDigits*(buffer: var openArray[char]; pos: int; digits: uint64; decima
|
||||||
## d.igitsE+123
|
## d.igitsE+123
|
||||||
buffer[pos+1] = '.'
|
buffer[pos+1] = '.'
|
||||||
pos = digitsEnd
|
pos = digitsEnd
|
||||||
let scientificExponent: int32 = decimalPoint - 1
|
let scientificExponent: int = decimalPoint - 1
|
||||||
## SF_ASSERT(scientific_exponent != 0);
|
## SF_ASSERT(scientific_exponent != 0);
|
||||||
buffer[pos] = 'e'
|
buffer[pos] = 'e'
|
||||||
buffer[pos+1] = if scientificExponent < 0: '-' else: '+'
|
buffer[pos+1] = if scientificExponent < 0: '-' else: '+'
|
||||||
|
|
@ -1291,7 +1291,7 @@ proc toChars*(buffer: var openArray[char]; v: float; forceTrailingDotZero = fals
|
||||||
if exponent != 0 or significand != 0:
|
if exponent != 0 or significand != 0:
|
||||||
## != 0
|
## != 0
|
||||||
let dec = toDecimal64(significand, exponent)
|
let dec = toDecimal64(significand, exponent)
|
||||||
return formatDigits(buffer, pos, dec.significand, dec.exponent,
|
return formatDigits(buffer, pos, dec.significand, dec.exponent.int,
|
||||||
forceTrailingDotZero)
|
forceTrailingDotZero)
|
||||||
else:
|
else:
|
||||||
buffer[pos] = '0'
|
buffer[pos] = '0'
|
||||||
|
|
|
||||||
|
|
@ -244,7 +244,7 @@ proc toDecimal32(ieeeSignificand: uint32; ieeeExponent: uint32): FloatingDecimal
|
||||||
## ToChars
|
## ToChars
|
||||||
## ==================================================================================================
|
## ==================================================================================================
|
||||||
|
|
||||||
proc printDecimalDigitsBackwards(buf: var openArray[char]; pos: int; output: uint32): int32 {.inline.} =
|
proc printDecimalDigitsBackwards[T: Ordinal](buf: var openArray[char]; pos: T; output: uint32): int32 {.inline.} =
|
||||||
var output = output
|
var output = output
|
||||||
var pos = pos
|
var pos = pos
|
||||||
var tz: int32 = 0
|
var tz: int32 = 0
|
||||||
|
|
@ -300,7 +300,7 @@ proc printDecimalDigitsBackwards(buf: var openArray[char]; pos: int; output: uin
|
||||||
buf[pos] = chr(uint32('0') + q)
|
buf[pos] = chr(uint32('0') + q)
|
||||||
return tz
|
return tz
|
||||||
|
|
||||||
proc decimalLength(v: uint32): int32 {.inline.} =
|
proc decimalLength(v: uint32): int {.inline.} =
|
||||||
sf_Assert(v >= 1)
|
sf_Assert(v >= 1)
|
||||||
sf_Assert(v <= 999999999'u)
|
sf_Assert(v <= 999999999'u)
|
||||||
if v >= 100000000'u:
|
if v >= 100000000'u:
|
||||||
|
|
@ -321,7 +321,7 @@ proc decimalLength(v: uint32): int32 {.inline.} =
|
||||||
return 2
|
return 2
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
proc formatDigits(buffer: var openArray[char]; pos: int; digits: uint32; decimalExponent: int32;
|
proc formatDigits[T: Ordinal](buffer: var openArray[char]; pos: T; digits: uint32; decimalExponent: int;
|
||||||
forceTrailingDotZero: bool = false): int {.inline.} =
|
forceTrailingDotZero: bool = false): int {.inline.} =
|
||||||
const
|
const
|
||||||
minFixedDecimalPoint: int32 = -4
|
minFixedDecimalPoint: int32 = -4
|
||||||
|
|
@ -333,8 +333,8 @@ proc formatDigits(buffer: var openArray[char]; pos: int; digits: uint32; decimal
|
||||||
sf_Assert(digits <= 999999999'u)
|
sf_Assert(digits <= 999999999'u)
|
||||||
sf_Assert(decimalExponent >= -99)
|
sf_Assert(decimalExponent >= -99)
|
||||||
sf_Assert(decimalExponent <= 99)
|
sf_Assert(decimalExponent <= 99)
|
||||||
var numDigits: int32 = decimalLength(digits)
|
var numDigits = decimalLength(digits)
|
||||||
let decimalPoint: int32 = numDigits + decimalExponent
|
let decimalPoint = numDigits + decimalExponent
|
||||||
let useFixed: bool = minFixedDecimalPoint <= decimalPoint and
|
let useFixed: bool = minFixedDecimalPoint <= decimalPoint and
|
||||||
decimalPoint <= maxFixedDecimalPoint
|
decimalPoint <= maxFixedDecimalPoint
|
||||||
## Prepare the buffer.
|
## Prepare the buffer.
|
||||||
|
|
@ -342,7 +342,7 @@ proc formatDigits(buffer: var openArray[char]; pos: int; digits: uint32; decimal
|
||||||
for i in 0..<32: buffer[pos+i] = '0'
|
for i in 0..<32: buffer[pos+i] = '0'
|
||||||
assert(minFixedDecimalPoint >= -30, "internal error")
|
assert(minFixedDecimalPoint >= -30, "internal error")
|
||||||
assert(maxFixedDecimalPoint <= 32, "internal error")
|
assert(maxFixedDecimalPoint <= 32, "internal error")
|
||||||
var decimalDigitsPosition: int32
|
var decimalDigitsPosition: int
|
||||||
if useFixed:
|
if useFixed:
|
||||||
if decimalPoint <= 0:
|
if decimalPoint <= 0:
|
||||||
## 0.[000]digits
|
## 0.[000]digits
|
||||||
|
|
@ -386,7 +386,7 @@ proc formatDigits(buffer: var openArray[char]; pos: int; digits: uint32; decimal
|
||||||
## d.igitsE+123
|
## d.igitsE+123
|
||||||
buffer[pos+1] = '.'
|
buffer[pos+1] = '.'
|
||||||
pos = digitsEnd
|
pos = digitsEnd
|
||||||
let scientificExponent: int32 = decimalPoint - 1
|
let scientificExponent = decimalPoint - 1
|
||||||
## SF_ASSERT(scientific_exponent != 0);
|
## SF_ASSERT(scientific_exponent != 0);
|
||||||
buffer[pos] = 'e'
|
buffer[pos] = 'e'
|
||||||
buffer[pos+1] = if scientificExponent < 0: '-' else: '+'
|
buffer[pos+1] = if scientificExponent < 0: '-' else: '+'
|
||||||
|
|
@ -412,7 +412,7 @@ proc float32ToChars*(buffer: var openArray[char]; v: float32; forceTrailingDotZe
|
||||||
if exponent != 0 or significand != 0:
|
if exponent != 0 or significand != 0:
|
||||||
## != 0
|
## != 0
|
||||||
let dec: auto = toDecimal32(significand, exponent)
|
let dec: auto = toDecimal32(significand, exponent)
|
||||||
return formatDigits(buffer, pos, dec.digits, dec.exponent, forceTrailingDotZero)
|
return formatDigits(buffer, pos, dec.digits, dec.exponent.int, forceTrailingDotZero)
|
||||||
else:
|
else:
|
||||||
buffer[pos] = '0'
|
buffer[pos] = '0'
|
||||||
buffer[pos+1] = '.'
|
buffer[pos+1] = '.'
|
||||||
|
|
|
||||||
|
|
@ -573,7 +573,7 @@ proc readAllFile(file: File, len: int64): string =
|
||||||
result = newString(len)
|
result = newString(len)
|
||||||
let bytes = readBuffer(file, addr(result[0]), len)
|
let bytes = readBuffer(file, addr(result[0]), len)
|
||||||
if endOfFile(file):
|
if endOfFile(file):
|
||||||
if bytes < len:
|
if bytes.int64 < len:
|
||||||
result.setLen(bytes)
|
result.setLen(bytes)
|
||||||
else:
|
else:
|
||||||
# We read all the bytes but did not reach the EOF
|
# We read all the bytes but did not reach the EOF
|
||||||
|
|
@ -717,7 +717,7 @@ proc open*(f: var File, filename: string,
|
||||||
|
|
||||||
result = true
|
result = true
|
||||||
f = cast[File](p)
|
f = cast[File](p)
|
||||||
if bufSize > 0 and bufSize <= high(cint).int:
|
if bufSize > 0 and bufSize.uint <= high(uint):
|
||||||
discard c_setvbuf(f, nil, IOFBF, cast[csize_t](bufSize))
|
discard c_setvbuf(f, nil, IOFBF, cast[csize_t](bufSize))
|
||||||
elif bufSize == 0:
|
elif bufSize == 0:
|
||||||
discard c_setvbuf(f, nil, IONBF, 0)
|
discard c_setvbuf(f, nil, IONBF, 0)
|
||||||
|
|
@ -821,7 +821,7 @@ when defined(windows) and appType == "console" and
|
||||||
proc getConsoleCP(): cuint {.stdcall, dynlib: "kernel32",
|
proc getConsoleCP(): cuint {.stdcall, dynlib: "kernel32",
|
||||||
importc: "GetConsoleCP".}
|
importc: "GetConsoleCP".}
|
||||||
|
|
||||||
const Utf8codepage = 65001
|
const Utf8codepage = 65001'u32
|
||||||
|
|
||||||
let
|
let
|
||||||
consoleOutputCP = getConsoleOutputCP()
|
consoleOutputCP = getConsoleOutputCP()
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ when defined(genode):
|
||||||
import genode/env
|
import genode/env
|
||||||
|
|
||||||
|
|
||||||
when hasAllocStack or defined(zephyr) or defined(freertos):
|
when hasAllocStack or defined(zephyr) or defined(freertos) or defined(cpu16) or defined(cpu8):
|
||||||
const
|
const
|
||||||
nimThreadStackSize {.intdefine.} = 8192
|
nimThreadStackSize {.intdefine.} = 8192
|
||||||
nimThreadStackGuard {.intdefine.} = 128
|
nimThreadStackGuard {.intdefine.} = 128
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,8 @@
|
||||||
type
|
type
|
||||||
Utf16Char* = distinct int16
|
Utf16Char* = distinct int16
|
||||||
|
|
||||||
when defined(nimv2):
|
when not (defined(cpu16) or defined(cpu8)):
|
||||||
|
when defined(nimv2):
|
||||||
|
|
||||||
type
|
type
|
||||||
WideCString* = ptr UncheckedArray[Utf16Char]
|
WideCString* = ptr UncheckedArray[Utf16Char]
|
||||||
|
|
@ -52,7 +53,7 @@ when defined(nimv2):
|
||||||
converter toWideCString*(x: WideCStringObj): WideCString {.inline.} =
|
converter toWideCString*(x: WideCStringObj): WideCString {.inline.} =
|
||||||
result = x.data
|
result = x.data
|
||||||
|
|
||||||
else:
|
else:
|
||||||
template nullWide(): untyped = nil
|
template nullWide(): untyped = nil
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
@ -62,15 +63,15 @@ else:
|
||||||
template createWide(a; L) =
|
template createWide(a; L) =
|
||||||
unsafeNew(a, L)
|
unsafeNew(a, L)
|
||||||
|
|
||||||
proc ord(arg: Utf16Char): int = int(cast[uint16](arg))
|
proc ord(arg: Utf16Char): int = int(cast[uint16](arg))
|
||||||
|
|
||||||
proc len*(w: WideCString): int =
|
proc len*(w: WideCString): int =
|
||||||
## returns the length of a widestring. This traverses the whole string to
|
## returns the length of a widestring. This traverses the whole string to
|
||||||
## find the binary zero end marker!
|
## find the binary zero end marker!
|
||||||
result = 0
|
result = 0
|
||||||
while int16(w[result]) != 0'i16: inc result
|
while int16(w[result]) != 0'i16: inc result
|
||||||
|
|
||||||
const
|
const
|
||||||
UNI_REPLACEMENT_CHAR = Utf16Char(0xFFFD'i16)
|
UNI_REPLACEMENT_CHAR = Utf16Char(0xFFFD'i16)
|
||||||
UNI_MAX_BMP = 0x0000FFFF
|
UNI_MAX_BMP = 0x0000FFFF
|
||||||
UNI_MAX_UTF16 = 0x0010FFFF
|
UNI_MAX_UTF16 = 0x0010FFFF
|
||||||
|
|
@ -87,9 +88,9 @@ const
|
||||||
UNI_SUR_LOW_END = 0xDFFF
|
UNI_SUR_LOW_END = 0xDFFF
|
||||||
UNI_REPL = 0xFFFD
|
UNI_REPL = 0xFFFD
|
||||||
|
|
||||||
template ones(n: untyped): untyped = ((1 shl n)-1)
|
template ones(n: untyped): untyped = ((1 shl n)-1)
|
||||||
|
|
||||||
template fastRuneAt(s: cstring, i, L: int, result: untyped, doInc = true) =
|
template fastRuneAt(s: cstring, i, L: int, result: untyped, doInc = true) =
|
||||||
## Returns the unicode character `s[i]` in `result`. If `doInc == true`
|
## Returns the unicode character `s[i]` in `result`. If `doInc == true`
|
||||||
## `i` is incremented by the number of bytes that have been processed.
|
## `i` is incremented by the number of bytes that have been processed.
|
||||||
bind ones
|
bind ones
|
||||||
|
|
@ -133,7 +134,7 @@ template fastRuneAt(s: cstring, i, L: int, result: untyped, doInc = true) =
|
||||||
result = 0xFFFD
|
result = 0xFFFD
|
||||||
when doInc: inc(i)
|
when doInc: inc(i)
|
||||||
|
|
||||||
iterator runes(s: cstring, L: int): int =
|
iterator runes(s: cstring, L: int): int =
|
||||||
var
|
var
|
||||||
i = 0
|
i = 0
|
||||||
result: int
|
result: int
|
||||||
|
|
@ -141,10 +142,10 @@ iterator runes(s: cstring, L: int): int =
|
||||||
fastRuneAt(s, i, L, result, true)
|
fastRuneAt(s, i, L, result, true)
|
||||||
yield result
|
yield result
|
||||||
|
|
||||||
proc newWideCString*(size: int): WideCStringObj =
|
proc newWideCString*(size: int): WideCStringObj =
|
||||||
createWide(result, size * 2 + 2)
|
createWide(result, size * 2 + 2)
|
||||||
|
|
||||||
proc newWideCString*(source: cstring, L: int): WideCStringObj =
|
proc newWideCString*(source: cstring, L: int): WideCStringObj =
|
||||||
createWide(result, L * 2 + 2)
|
createWide(result, L * 2 + 2)
|
||||||
var d = 0
|
var d = 0
|
||||||
for ch in runes(source, L):
|
for ch in runes(source, L):
|
||||||
|
|
@ -164,15 +165,15 @@ proc newWideCString*(source: cstring, L: int): WideCStringObj =
|
||||||
inc d
|
inc d
|
||||||
result[d] = Utf16Char(0)
|
result[d] = Utf16Char(0)
|
||||||
|
|
||||||
proc newWideCString*(s: cstring): WideCStringObj =
|
proc newWideCString*(s: cstring): WideCStringObj =
|
||||||
if s.isNil: return nullWide
|
if s.isNil: return nullWide
|
||||||
|
|
||||||
result = newWideCString(s, s.len)
|
result = newWideCString(s, s.len)
|
||||||
|
|
||||||
proc newWideCString*(s: string): WideCStringObj =
|
proc newWideCString*(s: string): WideCStringObj =
|
||||||
result = newWideCString(cstring s, s.len)
|
result = newWideCString(cstring s, s.len)
|
||||||
|
|
||||||
proc `$`*(w: WideCString, estimate: int, replacement: int = 0xFFFD): string =
|
proc `$`*(w: WideCString, estimate: int, replacement: int = 0xFFFD): string =
|
||||||
result = newStringOfCap(estimate + estimate shr 2)
|
result = newStringOfCap(estimate + estimate shr 2)
|
||||||
|
|
||||||
var i = 0
|
var i = 0
|
||||||
|
|
@ -214,10 +215,10 @@ proc `$`*(w: WideCString, estimate: int, replacement: int = 0xFFFD): string =
|
||||||
result.add chr(0xFFFD shr 6 and ones(6) or 0b10_0000_00)
|
result.add chr(0xFFFD shr 6 and ones(6) or 0b10_0000_00)
|
||||||
result.add chr(0xFFFD and ones(6) or 0b10_0000_00)
|
result.add chr(0xFFFD and ones(6) or 0b10_0000_00)
|
||||||
|
|
||||||
proc `$`*(s: WideCString): string =
|
proc `$`*(s: WideCString): string =
|
||||||
result = s $ 80
|
result = s $ 80
|
||||||
|
|
||||||
when defined(nimv2):
|
when defined(nimv2):
|
||||||
proc `$`*(s: WideCStringObj, estimate: int, replacement: int = 0xFFFD): string =
|
proc `$`*(s: WideCStringObj, estimate: int, replacement: int = 0xFFFD): string =
|
||||||
`$`(s.data, estimate, replacement)
|
`$`(s.data, estimate, replacement)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2001,7 +2001,7 @@ when notJSnotNims:
|
||||||
proc equalMem(a, b: pointer, size: Natural): bool =
|
proc equalMem(a, b: pointer, size: Natural): bool =
|
||||||
nimCmpMem(a, b, size) == 0
|
nimCmpMem(a, b, size) == 0
|
||||||
proc cmpMem(a, b: pointer, size: Natural): int =
|
proc cmpMem(a, b: pointer, size: Natural): int =
|
||||||
nimCmpMem(a, b, size)
|
nimCmpMem(a, b, size).int
|
||||||
|
|
||||||
when not defined(js):
|
when not defined(js):
|
||||||
proc cmp(x, y: string): int =
|
proc cmp(x, y: string): int =
|
||||||
|
|
@ -2300,13 +2300,15 @@ else:
|
||||||
type ExitCodeRange = int8
|
type ExitCodeRange = int8
|
||||||
else: # win32 uses low 32 bits
|
else: # win32 uses low 32 bits
|
||||||
type ExitCodeRange = cint
|
type ExitCodeRange = cint
|
||||||
|
when sizeof(errorcode) > sizeof(ExitCodeRange):
|
||||||
if errorcode < low(ExitCodeRange):
|
if errorcode < low(ExitCodeRange):
|
||||||
rawQuit(low(ExitCodeRange).cint)
|
rawQuit(low(ExitCodeRange).cint)
|
||||||
elif errorcode > high(ExitCodeRange):
|
elif errorcode > high(ExitCodeRange):
|
||||||
rawQuit(high(ExitCodeRange).cint)
|
rawQuit(high(ExitCodeRange).cint)
|
||||||
else:
|
else:
|
||||||
rawQuit(errorcode.cint)
|
rawQuit(errorcode.cint)
|
||||||
|
else:
|
||||||
|
rawQuit(errorcode.cint)
|
||||||
|
|
||||||
proc quit*(errormsg: string, errorcode = QuitFailure) {.noreturn.} =
|
proc quit*(errormsg: string, errorcode = QuitFailure) {.noreturn.} =
|
||||||
## A shorthand for `echo(errormsg); quit(errorcode)`.
|
## A shorthand for `echo(errormsg); quit(errorcode)`.
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ template track(op, address, size) =
|
||||||
const
|
const
|
||||||
nimMinHeapPages {.intdefine.} = 128 # 0.5 MB
|
nimMinHeapPages {.intdefine.} = 128 # 0.5 MB
|
||||||
SmallChunkSize = PageSize
|
SmallChunkSize = PageSize
|
||||||
MaxFli = 30
|
MaxFli = when sizeof(int) > 2: 30 else: 14
|
||||||
MaxLog2Sli = 5 # 32, this cannot be increased without changing 'uint32'
|
MaxLog2Sli = 5 # 32, this cannot be increased without changing 'uint32'
|
||||||
# everywhere!
|
# everywhere!
|
||||||
MaxSli = 1 shl MaxLog2Sli
|
MaxSli = 1 shl MaxLog2Sli
|
||||||
|
|
@ -32,7 +32,7 @@ const
|
||||||
RealFli = MaxFli - FliOffset
|
RealFli = MaxFli - FliOffset
|
||||||
|
|
||||||
# size of chunks in last matrix bin
|
# size of chunks in last matrix bin
|
||||||
MaxBigChunkSize = 1 shl MaxFli - 1 shl (MaxFli-MaxLog2Sli-1)
|
MaxBigChunkSize = int(1'i32 shl MaxFli - 1'i32 shl (MaxFli-MaxLog2Sli-1))
|
||||||
HugeChunkSize = MaxBigChunkSize + 1
|
HugeChunkSize = MaxBigChunkSize + 1
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
@ -115,7 +115,7 @@ type
|
||||||
MemRegion = object
|
MemRegion = object
|
||||||
when not defined(gcDestructors):
|
when not defined(gcDestructors):
|
||||||
minLargeObj, maxLargeObj: int
|
minLargeObj, maxLargeObj: int
|
||||||
freeSmallChunks: array[0..SmallChunkSize div MemAlign-1, PSmallChunk]
|
freeSmallChunks: array[0..max(1,SmallChunkSize div MemAlign-1), PSmallChunk]
|
||||||
flBitmap: uint32
|
flBitmap: uint32
|
||||||
slBitmap: array[RealFli, uint32]
|
slBitmap: array[RealFli, uint32]
|
||||||
matrix: array[RealFli, array[MaxSli, PBigChunk]]
|
matrix: array[RealFli, array[MaxSli, PBigChunk]]
|
||||||
|
|
@ -196,7 +196,7 @@ proc mappingSearch(r, fl, sl: var int) {.inline.} =
|
||||||
let t = roundup((1 shl (msbit(uint32 r) - MaxLog2Sli)), PageSize) - 1
|
let t = roundup((1 shl (msbit(uint32 r) - MaxLog2Sli)), PageSize) - 1
|
||||||
r = r + t
|
r = r + t
|
||||||
r = r and not t
|
r = r and not t
|
||||||
r = min(r, MaxBigChunkSize)
|
r = min(r, MaxBigChunkSize).int
|
||||||
fl = msbit(uint32 r)
|
fl = msbit(uint32 r)
|
||||||
sl = (r shr (fl - MaxLog2Sli)) - MaxSli
|
sl = (r shr (fl - MaxLog2Sli)) - MaxSli
|
||||||
dec fl, FliOffset
|
dec fl, FliOffset
|
||||||
|
|
@ -472,7 +472,7 @@ proc requestOsChunks(a: var MemRegion, size: int): PBigChunk =
|
||||||
a.nextChunkSize = PageSize*4
|
a.nextChunkSize = PageSize*4
|
||||||
else:
|
else:
|
||||||
a.nextChunkSize = min(roundup(usedMem shr 2, PageSize), a.nextChunkSize * 2)
|
a.nextChunkSize = min(roundup(usedMem shr 2, PageSize), a.nextChunkSize * 2)
|
||||||
a.nextChunkSize = min(a.nextChunkSize, MaxBigChunkSize)
|
a.nextChunkSize = min(a.nextChunkSize, MaxBigChunkSize).int
|
||||||
|
|
||||||
var size = size
|
var size = size
|
||||||
if size > a.nextChunkSize:
|
if size > a.nextChunkSize:
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
proc succ*[T: Ordinal](x: T, y = 1): T {.magic: "Succ", noSideEffect.} =
|
proc succ*[T, V: Ordinal](x: T, y: V = 1): T {.magic: "Succ", noSideEffect.} =
|
||||||
## Returns the `y`-th successor (default: 1) of the value `x`.
|
## Returns the `y`-th successor (default: 1) of the value `x`.
|
||||||
##
|
##
|
||||||
## If such a value does not exist, `OverflowDefect` is raised
|
## If such a value does not exist, `OverflowDefect` is raised
|
||||||
|
|
@ -7,7 +7,7 @@ proc succ*[T: Ordinal](x: T, y = 1): T {.magic: "Succ", noSideEffect.} =
|
||||||
assert succ(5) == 6
|
assert succ(5) == 6
|
||||||
assert succ(5, 3) == 8
|
assert succ(5, 3) == 8
|
||||||
|
|
||||||
proc pred*[T: Ordinal](x: T, y = 1): T {.magic: "Pred", noSideEffect.} =
|
proc pred*[T, V: Ordinal](x: T, y: V = 1): T {.magic: "Pred", noSideEffect.} =
|
||||||
## Returns the `y`-th predecessor (default: 1) of the value `x`.
|
## Returns the `y`-th predecessor (default: 1) of the value `x`.
|
||||||
##
|
##
|
||||||
## If such a value does not exist, `OverflowDefect` is raised
|
## If such a value does not exist, `OverflowDefect` is raised
|
||||||
|
|
@ -16,7 +16,7 @@ proc pred*[T: Ordinal](x: T, y = 1): T {.magic: "Pred", noSideEffect.} =
|
||||||
assert pred(5) == 4
|
assert pred(5) == 4
|
||||||
assert pred(5, 3) == 2
|
assert pred(5, 3) == 2
|
||||||
|
|
||||||
proc inc*[T: Ordinal](x: var T, y = 1) {.magic: "Inc", noSideEffect.} =
|
proc inc*[T, V: Ordinal](x: var T, y: V = 1) {.magic: "Inc", noSideEffect.} =
|
||||||
## Increments the ordinal `x` by `y`.
|
## Increments the ordinal `x` by `y`.
|
||||||
##
|
##
|
||||||
## If such a value does not exist, `OverflowDefect` is raised or a compile
|
## If such a value does not exist, `OverflowDefect` is raised or a compile
|
||||||
|
|
@ -28,7 +28,7 @@ proc inc*[T: Ordinal](x: var T, y = 1) {.magic: "Inc", noSideEffect.} =
|
||||||
inc(i, 3)
|
inc(i, 3)
|
||||||
assert i == 6
|
assert i == 6
|
||||||
|
|
||||||
proc dec*[T: Ordinal](x: var T, y = 1) {.magic: "Dec", noSideEffect.} =
|
proc dec*[T, V: Ordinal](x: var T, y: V = 1) {.magic: "Dec", noSideEffect.} =
|
||||||
## Decrements the ordinal `x` by `y`.
|
## Decrements the ordinal `x` by `y`.
|
||||||
##
|
##
|
||||||
## If such a value does not exist, `OverflowDefect` is raised or a compile
|
## If such a value does not exist, `OverflowDefect` is raised or a compile
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
# Page size of the system; in most cases 4096 bytes. For exotic OS or
|
# Page size of the system; in most cases 4096 bytes. For exotic OS or
|
||||||
# CPU this needs to be changed:
|
# CPU this needs to be changed:
|
||||||
const
|
const
|
||||||
PageShift = when defined(nimPage256) or defined(cpu16): 8
|
PageShift = when defined(nimPage256) or defined(cpu16): 3
|
||||||
elif defined(nimPage512): 9
|
elif defined(nimPage512): 9
|
||||||
elif defined(nimPage1k): 10
|
elif defined(nimPage1k): 10
|
||||||
else: 12 # \ # my tests showed no improvements for using larger page sizes.
|
else: 12 # \ # my tests showed no improvements for using larger page sizes.
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ proc cmpStrings(a, b: string): int {.inline, compilerproc.} =
|
||||||
let blen = b.len
|
let blen = b.len
|
||||||
let minlen = min(alen, blen)
|
let minlen = min(alen, blen)
|
||||||
if minlen > 0:
|
if minlen > 0:
|
||||||
result = c_memcmp(unsafeAddr a[0], unsafeAddr b[0], cast[csize_t](minlen))
|
result = c_memcmp(unsafeAddr a[0], unsafeAddr b[0], cast[csize_t](minlen)).int
|
||||||
if result == 0:
|
if result == 0:
|
||||||
result = alen - blen
|
result = alen - blen
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ template frees(s) =
|
||||||
|
|
||||||
proc resize(old: int): int {.inline.} =
|
proc resize(old: int): int {.inline.} =
|
||||||
if old <= 0: result = 4
|
if old <= 0: result = 4
|
||||||
elif old < 65536: result = old * 2
|
elif old <= high(int16): result = old * 2
|
||||||
else: result = old * 3 div 2 # for large arrays * 3/2 is better
|
else: result = old * 3 div 2 # for large arrays * 3/2 is better
|
||||||
|
|
||||||
proc prepareAdd(s: var NimStringV2; addlen: int) {.compilerRtl.} =
|
proc prepareAdd(s: var NimStringV2; addlen: int) {.compilerRtl.} =
|
||||||
|
|
|
||||||
2
tests/arithm/t1.nim
Normal file
2
tests/arithm/t1.nim
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
doAssert typeOf(1.int64 + 1.int) is int64
|
||||||
|
doAssert typeOf(1.uint64 + 1.uint) is uint64
|
||||||
|
|
@ -1,14 +1,5 @@
|
||||||
discard """
|
discard """
|
||||||
errormsg: "type mismatch: got <int>"
|
errormsg: "type mismatch: got <int>"
|
||||||
nimout: '''tprevent_forloopvar_mutations.nim(16, 7) Error: type mismatch: got <int>
|
|
||||||
but expected one of:
|
|
||||||
proc inc[T: Ordinal](x: var T; y = 1)
|
|
||||||
first type mismatch at position: 1
|
|
||||||
required type for x: var T: Ordinal
|
|
||||||
but expression 'i' is immutable, not 'var'
|
|
||||||
|
|
||||||
expression: inc i
|
|
||||||
'''
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
for i in 0..10:
|
for i in 0..10:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue