Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move formatfloat out of system #20195

Merged
merged 10 commits into from
Aug 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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