tyInt tyUint fit target int bit width (#20829)

This commit is contained in:
Bung 2022-12-01 20:34:00 +08:00 • committed by GitHub
commit 658b28dc57
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 306 additions and 267 deletions

View file

@ -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:

View file

@ -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)

View file

@ -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] == ',':

View file

@ -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]

View file

@ -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'

View file

@ -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] = '.'

View file

@ -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()

View file

@ -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

View file

@ -15,6 +15,7 @@
type type
Utf16Char* = distinct int16 Utf16Char* = distinct int16
when not (defined(cpu16) or defined(cpu8)):
when defined(nimv2): when defined(nimv2):
type type

View file

@ -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)`.

View file

@ -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:

View file

@ -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

View file

@ -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.

View file

@ -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:

View file

@ -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
View file

@ -0,0 +1,2 @@
doAssert typeOf(1.int64 + 1.int) is int64
doAssert typeOf(1.uint64 + 1.uint) is uint64

View file

@ -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: