Fix to int to biggest int (#12066)

* fix to(Biggest)Int
* kill toFloat magics as well
This commit is contained in:
Arne Döring 2019-08-27 23:18:46 +02:00 • committed by Andreas Rumpf
commit d564130a3b
10 changed files with 43 additions and 64 deletions

View file

@ -622,8 +622,6 @@ type
mUnaryMinusI, mUnaryMinusI64, mAbsI, mNot, mUnaryMinusI, mUnaryMinusI64, mAbsI, mNot,
mUnaryPlusI, mBitnotI, mUnaryPlusI, mBitnotI,
mUnaryPlusF64, mUnaryMinusF64, mAbsF64, mUnaryPlusF64, mUnaryMinusF64, mAbsF64,
mToFloat, mToBiggestFloat,
mToInt, mToBiggestInt,
mCharToStr, mBoolToStr, mIntToStr, mInt64ToStr, mFloatToStr, mCStrToStr, mCharToStr, mBoolToStr, mIntToStr, mInt64ToStr, mFloatToStr, mCStrToStr,
mStrToStr, mEnumToStr, mStrToStr, mEnumToStr,
mAnd, mOr, mAnd, mOr,
@ -692,8 +690,6 @@ const
mEqRef, mEqProc, mEqUntracedRef, mLePtr, mLtPtr, mEqCString, mXor, mEqRef, mEqProc, mEqUntracedRef, mLePtr, mLtPtr, mEqCString, mXor,
mUnaryMinusI, mUnaryMinusI64, mAbsI, mNot, mUnaryPlusI, mBitnotI, mUnaryMinusI, mUnaryMinusI64, mAbsI, mNot, mUnaryPlusI, mBitnotI,
mUnaryPlusF64, mUnaryMinusF64, mAbsF64, mUnaryPlusF64, mUnaryMinusF64, mAbsF64,
mToFloat, mToBiggestFloat,
mToInt, mToBiggestInt,
mCharToStr, mBoolToStr, mIntToStr, mInt64ToStr, mFloatToStr, mCStrToStr, mCharToStr, mBoolToStr, mIntToStr, mInt64ToStr, mFloatToStr, mCStrToStr,
mStrToStr, mEnumToStr, mStrToStr, mEnumToStr,
mAnd, mOr, mAnd, mOr,

View file

@ -666,14 +666,6 @@ proc unaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
of mAbsF64: of mAbsF64:
applyFormat("($1 < 0? -($1) : ($1))") applyFormat("($1 < 0? -($1) : ($1))")
# BUGFIX: fabs() makes problems for Tiny C # BUGFIX: fabs() makes problems for Tiny C
of mToFloat:
applyFormat("((double) ($1))")
of mToBiggestFloat:
applyFormat("((double) ($1))")
of mToInt:
applyFormat("float64ToInt32($1)")
of mToBiggestInt:
applyFormat("float64ToInt64($1)")
else: else:
assert false, $op assert false, $op
@ -2094,7 +2086,7 @@ proc genEnumToStr(p: BProc, e: PNode, d: var TLoc) =
proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) = proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
case op case op
of mOr, mAnd: genAndOr(p, e, d, op) of mOr, mAnd: genAndOr(p, e, d, op)
of mNot..mToBiggestInt: unaryArith(p, e, d, op) of mNot..mAbsF64: unaryArith(p, e, d, op)
of mUnaryMinusI..mAbsI: unaryArithOverflow(p, e, d, op) of mUnaryMinusI..mAbsI: unaryArithOverflow(p, e, d, op)
of mAddF64..mDivF64: binaryFloatArith(p, e, d, op) of mAddF64..mDivF64: binaryFloatArith(p, e, d, op)
of mShrI..mXor: binaryArith(p, e, d, op) of mShrI..mXor: binaryArith(p, e, d, op)

View file

@ -431,10 +431,6 @@ const # magic checked op; magic unchecked op;
["", ""], # UnaryPlusF64 ["", ""], # UnaryPlusF64
["", ""], # UnaryMinusF64 ["", ""], # UnaryMinusF64
["", ""], # AbsF64 ["", ""], # AbsF64
["", ""], # ToFloat
["", ""], # ToBiggestFloat
["", ""], # ToInt
["", ""], # ToBiggestInt
["nimCharToStr", "nimCharToStr"], ["nimCharToStr", "nimCharToStr"],
["nimBoolToStr", "nimBoolToStr"], ["nimBoolToStr", "nimBoolToStr"],
["cstrToNimstr", "cstrToNimstr"], ["cstrToNimstr", "cstrToNimstr"],
@ -612,10 +608,6 @@ proc arithAux(p: PProc, n: PNode, r: var TCompRes, op: TMagic) =
of mUnaryPlusF64: applyFormat("+($1)", "+($1)") of mUnaryPlusF64: applyFormat("+($1)", "+($1)")
of mUnaryMinusF64: applyFormat("-($1)", "-($1)") of mUnaryMinusF64: applyFormat("-($1)", "-($1)")
of mAbsF64: applyFormat("Math.abs($1)", "Math.abs($1)") of mAbsF64: applyFormat("Math.abs($1)", "Math.abs($1)")
of mToFloat: applyFormat("$1", "$1")
of mToBiggestFloat: applyFormat("$1", "$1")
of mToInt: applyFormat("Math.trunc($1)", "Math.trunc($1)")
of mToBiggestInt: applyFormat("Math.trunc($1)", "Math.trunc($1)")
of mCharToStr: applyFormat("nimCharToStr($1)", "nimCharToStr($1)") of mCharToStr: applyFormat("nimCharToStr($1)", "nimCharToStr($1)")
of mBoolToStr: applyFormat("nimBoolToStr($1)", "nimBoolToStr($1)") of mBoolToStr: applyFormat("nimBoolToStr($1)", "nimBoolToStr($1)")
of mIntToStr: applyFormat("cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")") of mIntToStr: applyFormat("cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")")

View file

@ -196,10 +196,7 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode =
else: else:
result = newIntNodeT(toInt128(sonsLen(a)), n, g) result = newIntNodeT(toInt128(sonsLen(a)), n, g)
of mUnaryPlusI, mUnaryPlusF64: result = a # throw `+` away of mUnaryPlusI, mUnaryPlusF64: result = a # throw `+` away
of mToFloat, mToBiggestFloat:
result = newFloatNodeT(toFloat64(getInt(a)), n, g)
# XXX: Hides overflow/underflow # XXX: Hides overflow/underflow
of mToInt, mToBiggestInt: result = newIntNodeT(system.toInt(getFloat(a)), n, g)
of mAbsF64: result = newFloatNodeT(abs(getFloat(a)), n, g) of mAbsF64: result = newFloatNodeT(abs(getFloat(a)), n, g)
of mAbsI: result = foldAbs(getInt(a), n, g) of mAbsI: result = foldAbs(getInt(a), n, g)
of mUnaryLt: result = foldSub(getOrdValue(a), One, n, g) of mUnaryLt: result = foldSub(getOrdValue(a), One, n, g)

View file

@ -873,7 +873,7 @@ proc inferStaticParam*(c: var TCandidate, lhs: PNode, rhs: BiggestInt): bool =
of mUnaryMinusI: of mUnaryMinusI:
return inferStaticParam(c, lhs[1], -rhs) return inferStaticParam(c, lhs[1], -rhs)
of mUnaryPlusI, mToInt, mToBiggestInt: of mUnaryPlusI:
return inferStaticParam(c, lhs[1], rhs) return inferStaticParam(c, lhs[1], rhs)
else: discard else: discard

View file

@ -1058,8 +1058,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
let t = skipTypes(n.typ, abstractVar-{tyTypeDesc}) let t = skipTypes(n.typ, abstractVar-{tyTypeDesc})
if t.kind in {tyUInt8..tyUInt32} or (t.kind == tyUInt and t.size < 8): if t.kind in {tyUInt8..tyUInt32} or (t.kind == tyUInt and t.size < 8):
c.gABC(n, opcNarrowU, dest, TRegister(t.size*8)) c.gABC(n, opcNarrowU, dest, TRegister(t.size*8))
of mToFloat, mToBiggestFloat, mToInt, of mCharToStr, mBoolToStr, mIntToStr, mInt64ToStr,
mToBiggestInt, mCharToStr, mBoolToStr, mIntToStr, mInt64ToStr,
mFloatToStr, mCStrToStr, mStrToStr, mEnumToStr: mFloatToStr, mCStrToStr, mStrToStr, mEnumToStr:
genConv(c, n, n.sons[1], dest) genConv(c, n, n.sons[1], dest)
of mEqStr, mEqCString: genBinaryABC(c, n, dest, opcEqStr) of mEqStr, mEqCString: genBinaryABC(c, n, dest, opcEqStr)

View file

@ -374,18 +374,6 @@ typedef char* NCSTRING;
# define NIM_IMAN 0 # define NIM_IMAN 0
#endif #endif
static N_INLINE(NI, float64ToInt32)(double x) {
/* nowadays no hack necessary anymore */
return x >= 0 ? (NI)(x+0.5) : (NI)(x-0.5);
}
static N_INLINE(NI32, float32ToInt32)(float x) {
/* nowadays no hack necessary anymore */
return x >= 0 ? (NI32)(x+0.5) : (NI32)(x-0.5);
}
#define float64ToInt64(x) ((NI64) (x))
#define NIM_STRLIT_FLAG ((NU)(1) << ((NIM_INTBITS) - 2)) /* This has to be the same as system.strlitFlag! */ #define NIM_STRLIT_FLAG ((NU)(1) << ((NIM_INTBITS) - 2)) /* This has to be the same as system.strlitFlag! */
#define STRING_LITERAL(name, str, length) \ #define STRING_LITERAL(name, str, length) \

View file

@ -1132,57 +1132,57 @@ proc chr*(u: range[0..255]): char {.magic: "Chr", noSideEffect.}
# built-in operators # built-in operators
when defined(nimNoZeroExtendMagic): when defined(nimNoZeroExtendMagic):
proc ze*(x: int8): int = proc ze*(x: int8): int {.deprecated.} =
## zero extends a smaller integer type to ``int``. This treats `x` as ## zero extends a smaller integer type to ``int``. This treats `x` as
## unsigned. ## unsigned.
## **Deprecated since version 0.19.9**: Use unsigned integers instead. ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
cast[int](uint(cast[uint8](x))) cast[int](uint(cast[uint8](x)))
proc ze*(x: int16): int = proc ze*(x: int16): int {.deprecated.} =
## zero extends a smaller integer type to ``int``. This treats `x` as ## zero extends a smaller integer type to ``int``. This treats `x` as
## unsigned. ## unsigned.
## **Deprecated since version 0.19.9**: Use unsigned integers instead. ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
cast[int](uint(cast[uint16](x))) cast[int](uint(cast[uint16](x)))
proc ze64*(x: int8): int64 = proc ze64*(x: int8): int64 {.deprecated.} =
## zero extends a smaller integer type to ``int64``. This treats `x` as ## zero extends a smaller integer type to ``int64``. This treats `x` as
## unsigned. ## unsigned.
## **Deprecated since version 0.19.9**: Use unsigned integers instead. ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
cast[int64](uint64(cast[uint8](x))) cast[int64](uint64(cast[uint8](x)))
proc ze64*(x: int16): int64 = proc ze64*(x: int16): int64 {.deprecated.} =
## zero extends a smaller integer type to ``int64``. This treats `x` as ## zero extends a smaller integer type to ``int64``. This treats `x` as
## unsigned. ## unsigned.
## **Deprecated since version 0.19.9**: Use unsigned integers instead. ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
cast[int64](uint64(cast[uint16](x))) cast[int64](uint64(cast[uint16](x)))
proc ze64*(x: int32): int64 = proc ze64*(x: int32): int64 {.deprecated.} =
## zero extends a smaller integer type to ``int64``. This treats `x` as ## zero extends a smaller integer type to ``int64``. This treats `x` as
## unsigned. ## unsigned.
## **Deprecated since version 0.19.9**: Use unsigned integers instead. ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
cast[int64](uint64(cast[uint32](x))) cast[int64](uint64(cast[uint32](x)))
proc ze64*(x: int): int64 = proc ze64*(x: int): int64 {.deprecated.} =
## zero extends a smaller integer type to ``int64``. This treats `x` as ## zero extends a smaller integer type to ``int64``. This treats `x` as
## unsigned. Does nothing if the size of an ``int`` is the same as ``int64``. ## unsigned. Does nothing if the size of an ``int`` is the same as ``int64``.
## (This is the case on 64 bit processors.) ## (This is the case on 64 bit processors.)
## **Deprecated since version 0.19.9**: Use unsigned integers instead. ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
cast[int64](uint64(cast[uint](x))) cast[int64](uint64(cast[uint](x)))
proc toU8*(x: int): int8 = proc toU8*(x: int): int8 {.deprecated.} =
## treats `x` as unsigned and converts it to a byte by taking the last 8 bits ## treats `x` as unsigned and converts it to a byte by taking the last 8 bits
## from `x`. ## from `x`.
## **Deprecated since version 0.19.9**: Use unsigned integers instead. ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
cast[int8](x) cast[int8](x)
proc toU16*(x: int): int16 = proc toU16*(x: int): int16 {.deprecated.} =
## treats `x` as unsigned and converts it to an ``int16`` by taking the last ## treats `x` as unsigned and converts it to an ``int16`` by taking the last
## 16 bits from `x`. ## 16 bits from `x`.
## **Deprecated since version 0.19.9**: Use unsigned integers instead. ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
cast[int16](x) cast[int16](x)
proc toU32*(x: int64): int32 = proc toU32*(x: int64): int32 {.deprecated.} =
## treats `x` as unsigned and converts it to an ``int32`` by taking the ## treats `x` as unsigned and converts it to an ``int32`` by taking the
## last 32 bits from `x`. ## last 32 bits from `x`.
## **Deprecated since version 0.19.9**: Use unsigned integers instead. ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
@ -2281,8 +2281,7 @@ type # these work for most platforms:
PInt64* = ptr int64 ## An alias for ``ptr int64``. PInt64* = ptr int64 ## An alias for ``ptr int64``.
PInt32* = ptr int32 ## An alias for ``ptr int32``. PInt32* = ptr int32 ## An alias for ``ptr int32``.
proc toFloat*(i: int): float {. proc toFloat*(i: int): float {.noSideEffect, inline.} =
magic: "ToFloat", noSideEffect, importc: "toFloat".}
## Converts an integer `i` into a ``float``. ## Converts an integer `i` into a ``float``.
## ##
## If the conversion fails, `ValueError` is raised. ## If the conversion fails, `ValueError` is raised.
@ -2294,13 +2293,13 @@ proc toFloat*(i: int): float {.
## b = 3.7 ## b = 3.7
## ##
## echo a.toFloat + b # => 5.7 ## echo a.toFloat + b # => 5.7
float(i)
proc toBiggestFloat*(i: BiggestInt): BiggestFloat {. proc toBiggestFloat*(i: BiggestInt): BiggestFloat {.noSideEffect, inline.} =
magic: "ToBiggestFloat", noSideEffect, importc: "toBiggestFloat".}
## Same as `toFloat <#toFloat,int>`_ but for ``BiggestInt`` to ``BiggestFloat``. ## Same as `toFloat <#toFloat,int>`_ but for ``BiggestInt`` to ``BiggestFloat``.
BiggestFloat(i)
proc toInt*(f: float): int {. proc toInt*(f: float): int {.noSideEffect.} =
magic: "ToInt", noSideEffect, importc: "toInt".}
## Converts a floating point number `f` into an ``int``. ## Converts a floating point number `f` into an ``int``.
## ##
## Conversion rounds `f` half away from 0, see ## Conversion rounds `f` half away from 0, see
@ -2314,10 +2313,11 @@ proc toInt*(f: float): int {.
## doAssert toInt(0.49) == 0 ## doAssert toInt(0.49) == 0
## doAssert toInt(0.5) == 1 ## doAssert toInt(0.5) == 1
## doAssert toInt(-0.5) == -1 # rounding is symmetrical ## doAssert toInt(-0.5) == -1 # rounding is symmetrical
if f >= 0: int(f+0.5) else: int(f-0.5)
proc toBiggestInt*(f: BiggestFloat): BiggestInt {. proc toBiggestInt*(f: BiggestFloat): BiggestInt {.noSideEffect.} =
magic: "ToBiggestInt", noSideEffect, importc: "toBiggestInt".}
## Same as `toInt <#toInt,float>`_ but for ``BiggestFloat`` to ``BiggestInt``. ## Same as `toInt <#toInt,float>`_ but for ``BiggestFloat`` to ``BiggestInt``.
if f >= 0: BiggestInt(f+0.5) else: BiggestInt(f-0.5)
proc addQuitProc*(quitProc: proc() {.noconv.}) {. proc addQuitProc*(quitProc: proc() {.noconv.}) {.
importc: "atexit", header: "<stdlib.h>".} importc: "atexit", header: "<stdlib.h>".}

View file

@ -159,3 +159,18 @@ block: # `$`*[T: tuple|object](x: T)
x2:float x2:float
doAssert $Foo(x:2) == "(x: 2, x2: 0.0)" doAssert $Foo(x:2) == "(x: 2, x2: 0.0)"
doAssert $() == "()" doAssert $() == "()"
# this is a call indirection to prevent `toInt` to be resolved at compile time.
proc testToInt(arg: float64, a: int, b: BiggestInt) =
doAssert toInt(arg) == a
doAssert toBiggestInt(arg) == b
testToInt(0.45, 0, 0) # should round towards 0
testToInt(-0.45, 0, 0) # should round towards 0
testToInt(0.5, 1, 1) # should round away from 0
testToInt(-0.5, -1, -1) # should round away from 0
testToInt(13.37, 13, 13) # should round towards 0
testToInt(-13.37, -13, -13) # should round towards 0
testToInt(7.8, 8, 8) # should round away from 0
testToInt(-7.8, -8, -8) # should round away from 0

View file

@ -64,7 +64,7 @@ proc fuzzyMatch*(pattern, str: cstring) : tuple[score: int, matched: bool] =
if not headerMatched and strChar == ':': if not headerMatched and strChar == ':':
headerMatched = true headerMatched = true
scoreState = StartMatch scoreState = StartMatch
score = toInt(floor(HeadingScaleFactor * toFloat(score))) score = int(floor(HeadingScaleFactor * float(score)))
patIndex = 0 patIndex = 0
strIndex += 1 strIndex += 1
continue continue