summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/vmops.nim8
-rw-r--r--lib/pure/strutils.nim107
-rw-r--r--tests/stdlib/tstrformat.nim19
3 files changed, 73 insertions, 61 deletions
diff --git a/compiler/vmops.nim b/compiler/vmops.nim
index bb943b8a0..2b5b2c938 100644
--- a/compiler/vmops.nim
+++ b/compiler/vmops.nim
@@ -36,7 +36,9 @@ from std/osproc import nil
 when defined(nimPreviewSlimSystem):
   import std/syncio
 else:
-  from std/formatfloat import addFloatRoundtrip, addFloatSprintf 
+  from std/formatfloat import addFloatRoundtrip, addFloatSprintf
+
+from std/strutils import formatBiggestFloat, FloatFormatMode
 
 # There are some useful procs in vmconv.
 import vmconv, vmmarshal
@@ -374,6 +376,10 @@ proc registerAdditionalOps*(c: PCtx) =
     let x = a.getFloat(1)
     addFloatSprintf(p.strVal, x)
 
+  registerCallback c, "stdlib.strutils.formatBiggestFloat", proc(a: VmArgs) =
+    setResult(a, formatBiggestFloat(a.getFloat(0), FloatFormatMode(a.getInt(1)),
+                                    a.getInt(2), chr(a.getInt(3))))
+
   wrapIterator("stdlib.envvars.envPairsImplSeq"): envPairs()
 
   registerCallback c, "stdlib.marshal.toVM", proc(a: VmArgs) =
diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim
index dbdd0d6a1..c458d605e 100644
--- a/lib/pure/strutils.nim
+++ b/lib/pure/strutils.nim
@@ -2413,60 +2413,63 @@ func formatBiggestFloat*(f: BiggestFloat, format: FloatFormatMode = ffDefault,
     doAssert x.formatBiggestFloat() == "123.4560000000000"
     doAssert x.formatBiggestFloat(ffDecimal, 4) == "123.4560"
     doAssert x.formatBiggestFloat(ffScientific, 2) == "1.23e+02"
-  when defined(js):
-    var precision = precision
-    if precision == -1:
-      # use the same default precision as c_sprintf
-      precision = 6
-    var res: cstring
-    case format
-    of ffDefault:
-      {.emit: "`res` = `f`.toString();".}
-    of ffDecimal:
-      {.emit: "`res` = `f`.toFixed(`precision`);".}
-    of ffScientific:
-      {.emit: "`res` = `f`.toExponential(`precision`);".}
-    result = $res
-    if 1.0 / f == -Inf:
-      # JavaScript removes the "-" from negative Zero, add it back here
-      result = "-" & $res
-    for i in 0 ..< result.len:
-      # Depending on the locale either dot or comma is produced,
-      # but nothing else is possible:
-      if result[i] in {'.', ','}: result[i] = decimalSep
+  when nimvm:
+    discard "implemented in the vmops"
   else:
-    const floatFormatToChar: array[FloatFormatMode, char] = ['g', 'f', 'e']
-    var
-      frmtstr {.noinit.}: array[0..5, char]
-      buf {.noinit.}: array[0..2500, char]
-      L: cint
-    frmtstr[0] = '%'
-    if precision >= 0:
-      frmtstr[1] = '#'
-      frmtstr[2] = '.'
-      frmtstr[3] = '*'
-      frmtstr[4] = floatFormatToChar[format]
-      frmtstr[5] = '\0'
-      L = c_sprintf(cast[cstring](addr buf), cast[cstring](addr frmtstr), precision, f)
+    when defined(js):
+      var precision = precision
+      if precision == -1:
+        # use the same default precision as c_sprintf
+        precision = 6
+      var res: cstring
+      case format
+      of ffDefault:
+        {.emit: "`res` = `f`.toString();".}
+      of ffDecimal:
+        {.emit: "`res` = `f`.toFixed(`precision`);".}
+      of ffScientific:
+        {.emit: "`res` = `f`.toExponential(`precision`);".}
+      result = $res
+      if 1.0 / f == -Inf:
+        # JavaScript removes the "-" from negative Zero, add it back here
+        result = "-" & $res
+      for i in 0 ..< result.len:
+        # Depending on the locale either dot or comma is produced,
+        # but nothing else is possible:
+        if result[i] in {'.', ','}: result[i] = decimalSep
     else:
-      frmtstr[1] = floatFormatToChar[format]
-      frmtstr[2] = '\0'
-      L = c_sprintf(cast[cstring](addr buf), cast[cstring](addr frmtstr), f)
-    result = newString(L)
-    for i in 0 ..< L:
-      # Depending on the locale either dot or comma is produced,
-      # but nothing else is possible:
-      if buf[i] in {'.', ','}: result[i] = decimalSep
-      else: result[i] = buf[i]
-    when defined(windows):
-      # VS pre 2015 violates the C standard: "The exponent always contains at
-      # least two digits, and only as many more digits as necessary to
-      # represent the exponent." [C11 §7.21.6.1]
-      # The following post-processing fixes this behavior.
-      if result.len > 4 and result[^4] == '+' and result[^3] == '0':
-        result[^3] = result[^2]
-        result[^2] = result[^1]
-        result.setLen(result.len - 1)
+      const floatFormatToChar: array[FloatFormatMode, char] = ['g', 'f', 'e']
+      var
+        frmtstr {.noinit.}: array[0..5, char]
+        buf {.noinit.}: array[0..2500, char]
+        L: cint
+      frmtstr[0] = '%'
+      if precision >= 0:
+        frmtstr[1] = '#'
+        frmtstr[2] = '.'
+        frmtstr[3] = '*'
+        frmtstr[4] = floatFormatToChar[format]
+        frmtstr[5] = '\0'
+        L = c_sprintf(cast[cstring](addr buf), cast[cstring](addr frmtstr), precision, f)
+      else:
+        frmtstr[1] = floatFormatToChar[format]
+        frmtstr[2] = '\0'
+        L = c_sprintf(cast[cstring](addr buf), cast[cstring](addr frmtstr), f)
+      result = newString(L)
+      for i in 0 ..< L:
+        # Depending on the locale either dot or comma is produced,
+        # but nothing else is possible:
+        if buf[i] in {'.', ','}: result[i] = decimalSep
+        else: result[i] = buf[i]
+      when defined(windows):
+        # VS pre 2015 violates the C standard: "The exponent always contains at
+        # least two digits, and only as many more digits as necessary to
+        # represent the exponent." [C11 §7.21.6.1]
+        # The following post-processing fixes this behavior.
+        if result.len > 4 and result[^4] == '+' and result[^3] == '0':
+          result[^3] = result[^2]
+          result[^2] = result[^1]
+          result.setLen(result.len - 1)
 
 func formatFloat*(f: float, format: FloatFormatMode = ffDefault,
                   precision: range[-1..32] = 16; decimalSep = '.'): string {.
diff --git a/tests/stdlib/tstrformat.nim b/tests/stdlib/tstrformat.nim
index b44a11e68..d332e8375 100644
--- a/tests/stdlib/tstrformat.nim
+++ b/tests/stdlib/tstrformat.nim
@@ -475,15 +475,17 @@ proc main() =
 
     # Note: times.format adheres to the format protocol. Test that this
     # works:
+    when nimvm:
+      discard
+    else:
+      var dt = dateTime(2000, mJan, 01, 00, 00, 00)
+      check &"{dt:yyyy-MM-dd}", "2000-01-01"
 
-    var dt = initDateTime(01, mJan, 2000, 00, 00, 00)
-    check &"{dt:yyyy-MM-dd}", "2000-01-01"
+      var tm = fromUnix(0)
+      discard &"{tm}"
 
-    var tm = fromUnix(0)
-    discard &"{tm}"
-
-    var noww = now()
-    check &"{noww}", $noww
+      var noww = now()
+      check &"{noww}", $noww
 
     # Unicode string tests
     check &"""{"αβγ"}""", "αβγ"
@@ -558,5 +560,6 @@ proc main() =
     doAssert &"""{(if true: "'" & "'" & ')' else: "")}""" == "'')"
     doAssert &"{(if true: \"\'\" & \"'\" & ')' else: \"\")}" == "'')"
     doAssert fmt"""{(if true: "'" & ')' else: "")}""" == "')"
-# xxx static: main()
+
+static: main()
 main()
previous revision' href='/ahoang/Nim/blame/compiler/nimsets.nim?h=devel&id=706266d8b728b19fde6d69fd6ccdfb65ae7b6a17'>^
674c05f42 ^
e25474154 ^


















92b8fac94 ^
e25474154 ^

92b8fac94 ^
e25474154 ^
2df9b442c ^
e25474154 ^









438703f59 ^
e25474154 ^



92b8fac94 ^
438703f59 ^
92b8fac94 ^
e25474154 ^








92b8fac94 ^
e25474154 ^
6f1fc1b5b ^
e25474154 ^


6f1fc1b5b ^
e25474154 ^

92b8fac94 ^



e25474154 ^












009730595 ^





e25474154 ^








92b8fac94 ^
e25474154 ^
2df9b442c ^
674c05f42 ^
2df9b442c ^
674c05f42 ^
e25474154 ^






36c67455d ^
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172