Skip to content

Commit

Permalink
move formatfloat out of system (#20195)
Browse files Browse the repository at this point in the history
* move formatfloat out of system

* fixes doc

* Update changelog.md

* careless

* fixes

* deprecate system/formatfloat

* better handling
  • Loading branch information
ringabout authored Aug 24, 2022
1 parent 12f23d5 commit b6bfe38
Show file tree
Hide file tree
Showing 23 changed files with 201 additions and 176 deletions.
3 changes: 1 addition & 2 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
- `addr` is now available for all addressable locations,
`unsafeAddr` is now deprecated and an alias for `addr`.

- `io` and `assertions` are about to move out of the `system` module.
You may instead import `std/syncio` and `std/assertions`.
- `io`, `assertions`, `formatfloat` are about to move out of the `system` module. You may instead import `std/syncio`, `std/assertions` and `std/formatfloat`.
The `-d:nimPreviewSlimSystem` option makes these imports required.

- The `gc:v2` option is removed.
Expand Down
2 changes: 1 addition & 1 deletion compiler/ic/ic.nim
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import ".." / [ast, idents, lineinfos, msgs, ropes, options,
from os import removeFile, isAbsolute

when defined(nimPreviewSlimSystem):
import std/[syncio, assertions]
import std/[syncio, assertions, formatfloat]

type
PackedConfig* = object
Expand Down
2 changes: 1 addition & 1 deletion compiler/lexer.nim
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import
wordrecg, lineinfos, pathutils, parseutils

when defined(nimPreviewSlimSystem):
import std/assertions
import std/[assertions, formatfloat]

const
MaxLineLength* = 80 # lines longer than this lead to a warning
Expand Down
2 changes: 1 addition & 1 deletion compiler/renderer.nim
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import
lexer, options, idents, strutils, ast, msgs, lineinfos

when defined(nimPreviewSlimSystem):
import std/[syncio, assertions]
import std/[syncio, assertions, formatfloat]

type
TRenderFlag* = enum
Expand Down
2 changes: 1 addition & 1 deletion compiler/rodutils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ when not declared(signbit):
proc signbit*(x: SomeFloat): bool {.inline.} =
result = c_signbit(x) != 0

import system/formatfloat
import std/formatfloat

proc toStrMaxPrecision*(f: BiggestFloat | float32): string =
const literalPostfix = when f is float32: "f" else: ""
Expand Down
2 changes: 1 addition & 1 deletion compiler/ropes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ import
from pathutils import AbsoluteFile

when defined(nimPreviewSlimSystem):
import std/[assertions, syncio]
import std/[assertions, syncio, formatfloat]


type
Expand Down
3 changes: 3 additions & 0 deletions compiler/sem.nim
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ when defined(nimfix):
when not defined(leanCompiler):
import spawn

when defined(nimPreviewSlimSystem):
import std/formatfloat

# implementation

proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}, expectedType: PType = nil): PNode
Expand Down
2 changes: 1 addition & 1 deletion compiler/semfold.nim
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import
from system/memory import nimCStrLen

when defined(nimPreviewSlimSystem):
import std/assertions
import std/[assertions, formatfloat]

proc errorType*(g: ModuleGraph): PType =
## creates a type representing an error state
Expand Down
2 changes: 1 addition & 1 deletion compiler/types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import
lineinfos, int128, modulegraphs, astmsgs

when defined(nimPreviewSlimSystem):
import std/assertions
import std/[assertions, formatfloat]

type
TPreferedDesc* = enum
Expand Down
3 changes: 3 additions & 0 deletions compiler/vm.nim
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ import
gorgeimpl, lineinfos, btrees, macrocacheimpl,
modulegraphs, sighashes, int128, vmprofiler

when defined(nimPreviewSlimSystem):
import std/formatfloat

import ast except getstr
from semfold import leValueConv, ordinalValToString
from evaltempl import evalTemplate
Expand Down
2 changes: 1 addition & 1 deletion compiler/vmmarshal.nim
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import streams, json, intsets, tables, ast, astalgo, idents, types, msgs,
options, lineinfos

when defined(nimPreviewSlimSystem):
import std/assertions
import std/[assertions, formatfloat]

proc ptrToInt(x: PNode): int {.inline.} =
result = cast[int](x) # don't skip alignment
Expand Down
4 changes: 2 additions & 2 deletions compiler/vmops.nim
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ from std/os import getEnv, existsEnv, delEnv, putEnv, envPairs,
from std/times import cpuTime
from std/hashes import hash
from std/osproc import nil
from system/formatfloat import addFloatRoundtrip, addFloatSprintf


when defined(nimPreviewSlimSystem):
import std/syncio

else:
from std/formatfloat import addFloatRoundtrip, addFloatSprintf

# There are some useful procs in vmconv.
import vmconv, vmmarshal
Expand Down
2 changes: 1 addition & 1 deletion lib/core/macros.nim
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ include "system/inclrtl"
import std/private/since

when defined(nimPreviewSlimSystem):
import std/assertions
import std/[assertions, formatfloat]


## This module contains the interface to the compiler's abstract syntax
Expand Down
2 changes: 1 addition & 1 deletion lib/packages/docutils/rstgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import strutils, os, hashes, strtabs, rstast, rst, highlite, tables, sequtils,


when defined(nimPreviewSlimSystem):
import std/[assertions, syncio]
import std/[assertions, syncio, formatfloat]


import ../../std/private/since
Expand Down
2 changes: 1 addition & 1 deletion lib/pure/json.nim
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ import options # xxx remove this dependency using same approach as https://githu
import std/private/since

when defined(nimPreviewSlimSystem):
import std/[syncio, assertions]
import std/[syncio, assertions, formatfloat]

export
tables.`$`
Expand Down
142 changes: 142 additions & 0 deletions lib/std/formatfloat.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
#
#
# Nim's Runtime Library
# (c) Copyright 2022 Nim contributors
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#

when defined(nimPreviewSlimSystem):
import std/assertions
else:
{.deprecated: "formatfloat is about to move out of system; use `-d:nimPreviewSlimSystem` and import `std/formatfloat`".}

proc c_memcpy(a, b: pointer, size: csize_t): pointer {.importc: "memcpy", header: "<string.h>", discardable.}

proc addCstringN(result: var string, buf: cstring; buflen: int) =
# no nimvm support needed, so it doesn't need to be fast here either
let oldLen = result.len
let newLen = oldLen + buflen
result.setLen newLen
c_memcpy(result[oldLen].addr, buf, buflen.csize_t)

import std/private/[dragonbox, schubfach]

proc writeFloatToBufferRoundtrip*(buf: var array[65, char]; value: BiggestFloat): int =
## This is the implementation to format floats.
##
## returns the amount of bytes written to `buf` not counting the
## terminating '\0' character.
result = toChars(buf, value, forceTrailingDotZero=true)
buf[result] = '\0'

proc writeFloatToBufferRoundtrip*(buf: var array[65, char]; value: float32): int =
result = float32ToChars(buf, value, forceTrailingDotZero=true)
buf[result] = '\0'

proc c_sprintf(buf, frmt: cstring): cint {.header: "<stdio.h>",
importc: "sprintf", varargs, noSideEffect.}

proc writeToBuffer(buf: var array[65, char]; value: cstring) =
var i = 0
while value[i] != '\0':
buf[i] = value[i]
inc i

proc writeFloatToBufferSprintf*(buf: var array[65, char]; value: BiggestFloat): int =
## This is the implementation to format floats.
##
## returns the amount of bytes written to `buf` not counting the
## terminating '\0' character.
var n: int = c_sprintf(addr buf, "%.16g", value)
var hasDot = false
for i in 0..n-1:
if buf[i] == ',':
buf[i] = '.'
hasDot = true
elif buf[i] in {'a'..'z', 'A'..'Z', '.'}:
hasDot = true
if not hasDot:
buf[n] = '.'
buf[n+1] = '0'
buf[n+2] = '\0'
result = n + 2
else:
result = n
# On Windows nice numbers like '1.#INF', '-1.#INF' or '1.#NAN' or 'nan(ind)'
# of '-1.#IND' are produced.
# We want to get rid of these here:
if buf[n-1] in {'n', 'N', 'D', 'd', ')'}:
writeToBuffer(buf, "nan")
result = 3
elif buf[n-1] == 'F':
if buf[0] == '-':
writeToBuffer(buf, "-inf")
result = 4
else:
writeToBuffer(buf, "inf")
result = 3

proc writeFloatToBuffer*(buf: var array[65, char]; value: BiggestFloat | float32): int {.inline.} =
when defined(nimPreviewFloatRoundtrip) or defined(nimPreviewSlimSystem):
writeFloatToBufferRoundtrip(buf, value)
else:
writeFloatToBufferSprintf(buf, value)

proc addFloatRoundtrip*(result: var string; x: float | float32) =
when nimvm:
doAssert false
else:
var buffer {.noinit.}: array[65, char]
let n = writeFloatToBufferRoundtrip(buffer, x)
result.addCstringN(cstring(buffer[0].addr), n)

proc addFloatSprintf*(result: var string; x: float) =
when nimvm:
doAssert false
else:
var buffer {.noinit.}: array[65, char]
let n = writeFloatToBufferSprintf(buffer, x)
result.addCstringN(cstring(buffer[0].addr), n)

proc nimFloatToString(a: float): cstring =
## ensures the result doesn't print like an integer, i.e. return 2.0, not 2
# print `-0.0` properly
asm """
function nimOnlyDigitsOrMinus(n) {
return n.toString().match(/^-?\d+$/);
}
if (Number.isSafeInteger(`a`))
`result` = `a` === 0 && 1 / `a` < 0 ? "-0.0" : `a`+".0"
else {
`result` = `a`+""
if(nimOnlyDigitsOrMinus(`result`)){
`result` = `a`+".0"
}
}
"""

proc addFloat*(result: var string; x: float | float32) {.inline.} =
## Converts float to its string representation and appends it to `result`.
runnableExamples:
var
s = "foo:"
b = 45.67
s.addFloat(45.67)
assert s == "foo:45.67"
template impl =
when defined(nimPreviewFloatRoundtrip) or defined(nimPreviewSlimSystem):
addFloatRoundtrip(result, x)
else:
addFloatSprintf(result, x)
when defined(js):
when nimvm: impl()
else:
result.add nimFloatToString(x)
else: impl()

when defined(nimPreviewSlimSystem):
func `$`*(x: float | float32): string =
## Outplace version of `addFloat`.
result.addFloat(x)
27 changes: 13 additions & 14 deletions lib/system/dragonbox.nim → lib/std/private/dragonbox.nim
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,20 @@ when defined(nimPreviewSlimSystem):
const
dtoaMinBufferLength*: cint = 64

## --------------------------------------------------------------------------------------------------
## This file contains an implementation of Junekey Jeon's Dragonbox algorithm.
##
## It is a simplified version of the reference implementation found here:
## https://github.com/jk-jeon/dragonbox
##
## The reference implementation also works with single-precision floating-point numbers and
## has options to configure the rounding mode.
## --------------------------------------------------------------------------------------------------

template dragonbox_Assert*(x: untyped): untyped =
assert(x)

## ==================================================================================================
##
## ==================================================================================================
# ==================================================================================================
#
# ==================================================================================================

type
ValueType* = float
Expand Down Expand Up @@ -106,10 +104,11 @@ proc isZero*(this: Double): bool {.noSideEffect.} =
proc signBit*(this: Double): int {.noSideEffect.} =
return ord((this.bits and signMask) != 0)


# ==================================================================================================
#
# ==================================================================================================
## namespace
## ==================================================================================================
##
## ==================================================================================================
## Returns floor(x / 2^n).
##
## Technically, right-shift of negative integers is implementation defined...
Expand All @@ -133,9 +132,9 @@ proc floorLog10ThreeQuartersPow2*(e: int32): int32 {.inline.} =
dragonbox_Assert(e <= 1500)
return floorDivPow2(e * 1262611 - 524031, 22)

## ==================================================================================================
##
## ==================================================================================================
# ==================================================================================================
#
# ==================================================================================================

type
uint64x2* {.bycopy.} = object
Expand Down Expand Up @@ -1040,9 +1039,9 @@ proc toDecimal64*(ieeeSignificand: uint64; ieeeExponent: uint64): FloatingDecima
dec(q)
return FloatingDecimal64(significand: q, exponent: minusK + kappa)

## ==================================================================================================
## ToChars
## ==================================================================================================
# ==================================================================================================
# ToChars
# ==================================================================================================

when false:
template `+!`(x: cstring; offset: int): cstring = cast[cstring](cast[uint](x) + uint(offset))
Expand Down
12 changes: 6 additions & 6 deletions lib/system/schubfach.nim → lib/std/private/schubfach.nim
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
## Distributed under the Boost Software License, Version 1.0.
## (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)

## --------------------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------------------
## This file contains an implementation of the Schubfach algorithm as described in
##
## [1] Raffaello Giulietti, "The Schubfach way to render doubles",
## https://drive.google.com/open?id=1luHhyQF9zKlM8yJ1nebU0OgVYhfC6CBN
## --------------------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------------------

import std/private/digitsutils

Expand All @@ -19,9 +19,9 @@ when defined(nimPreviewSlimSystem):
template sf_Assert(x: untyped): untyped =
assert(x)

## ==================================================================================================
##
## ==================================================================================================
# ==================================================================================================
#
# ==================================================================================================

type
ValueType = float32
Expand Down Expand Up @@ -68,7 +68,7 @@ proc isZero(this: Single): bool {.noSideEffect.} =
proc signBit(this: Single): int {.noSideEffect.} =
return int((this.bits and signMask) != 0)

## ==================================================================================================
# ==================================================================================================
## Returns floor(x / 2^n).
##
## Technically, right-shift of negative integers is implementation defined...
Expand Down
2 changes: 1 addition & 1 deletion lib/std/syncio.nim
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

include system/inclrtl
import std/private/since
import system/formatfloat
import std/formatfloat

# ----------------- IO Part ------------------------------------------------
type
Expand Down
Loading

0 comments on commit b6bfe38

Please sign in to comment.