@grain/stdlib 0.5.13 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +201 -0
- package/LICENSE +1 -1
- package/README.md +25 -2
- package/array.gr +1512 -199
- package/array.md +2032 -94
- package/bigint.gr +239 -140
- package/bigint.md +450 -106
- package/buffer.gr +595 -102
- package/buffer.md +903 -145
- package/bytes.gr +401 -110
- package/bytes.md +551 -63
- package/char.gr +228 -49
- package/char.md +373 -7
- package/exception.gr +26 -12
- package/exception.md +29 -5
- package/float32.gr +130 -109
- package/float32.md +185 -57
- package/float64.gr +112 -99
- package/float64.md +185 -57
- package/hash.gr +62 -40
- package/hash.md +27 -3
- package/int16.gr +430 -0
- package/int16.md +618 -0
- package/int32.gr +200 -269
- package/int32.md +254 -289
- package/int64.gr +142 -225
- package/int64.md +254 -289
- package/int8.gr +511 -0
- package/int8.md +786 -0
- package/json.gr +2071 -0
- package/json.md +646 -0
- package/list.gr +120 -68
- package/list.md +125 -80
- package/map.gr +560 -57
- package/map.md +672 -56
- package/marshal.gr +239 -227
- package/marshal.md +36 -4
- package/number.gr +626 -676
- package/number.md +738 -153
- package/option.gr +33 -35
- package/option.md +58 -42
- package/package.json +2 -2
- package/path.gr +148 -187
- package/path.md +47 -96
- package/pervasives.gr +75 -416
- package/pervasives.md +85 -180
- package/priorityqueue.gr +433 -74
- package/priorityqueue.md +422 -54
- package/queue.gr +362 -80
- package/queue.md +433 -38
- package/random.gr +67 -75
- package/random.md +68 -40
- package/range.gr +135 -63
- package/range.md +198 -43
- package/rational.gr +284 -0
- package/rational.md +545 -0
- package/regex.gr +933 -1066
- package/regex.md +59 -60
- package/result.gr +23 -25
- package/result.md +54 -39
- package/runtime/atof/common.gr +78 -82
- package/runtime/atof/common.md +22 -10
- package/runtime/atof/decimal.gr +102 -127
- package/runtime/atof/decimal.md +28 -7
- package/runtime/atof/lemire.gr +56 -71
- package/runtime/atof/lemire.md +9 -1
- package/runtime/atof/parse.gr +83 -110
- package/runtime/atof/parse.md +12 -2
- package/runtime/atof/slow.gr +28 -35
- package/runtime/atof/slow.md +9 -1
- package/runtime/atof/table.gr +19 -18
- package/runtime/atof/table.md +10 -2
- package/runtime/atoi/parse.gr +153 -136
- package/runtime/atoi/parse.md +50 -1
- package/runtime/bigint.gr +410 -517
- package/runtime/bigint.md +71 -57
- package/runtime/compare.gr +176 -85
- package/runtime/compare.md +31 -1
- package/runtime/dataStructures.gr +144 -32
- package/runtime/dataStructures.md +267 -31
- package/runtime/debugPrint.gr +34 -15
- package/runtime/debugPrint.md +37 -5
- package/runtime/equal.gr +53 -52
- package/runtime/equal.md +30 -1
- package/runtime/exception.gr +38 -47
- package/runtime/exception.md +10 -8
- package/runtime/gc.gr +23 -152
- package/runtime/gc.md +13 -17
- package/runtime/malloc.gr +31 -31
- package/runtime/malloc.md +11 -3
- package/runtime/numberUtils.gr +193 -174
- package/runtime/numberUtils.md +29 -9
- package/runtime/numbers.gr +1695 -1021
- package/runtime/numbers.md +1098 -134
- package/runtime/string.gr +543 -245
- package/runtime/string.md +76 -6
- package/runtime/unsafe/constants.gr +30 -13
- package/runtime/unsafe/constants.md +80 -0
- package/runtime/unsafe/conv.gr +55 -28
- package/runtime/unsafe/conv.md +41 -9
- package/runtime/unsafe/memory.gr +10 -30
- package/runtime/unsafe/memory.md +15 -19
- package/runtime/unsafe/tags.gr +37 -21
- package/runtime/unsafe/tags.md +88 -8
- package/runtime/unsafe/wasmf32.gr +30 -36
- package/runtime/unsafe/wasmf32.md +64 -56
- package/runtime/unsafe/wasmf64.gr +30 -36
- package/runtime/unsafe/wasmf64.md +64 -56
- package/runtime/unsafe/wasmi32.gr +49 -66
- package/runtime/unsafe/wasmi32.md +102 -94
- package/runtime/unsafe/wasmi64.gr +52 -79
- package/runtime/unsafe/wasmi64.md +108 -100
- package/runtime/utils/printing.gr +13 -15
- package/runtime/utils/printing.md +11 -3
- package/runtime/wasi.gr +294 -295
- package/runtime/wasi.md +62 -42
- package/set.gr +574 -64
- package/set.md +634 -54
- package/stack.gr +181 -64
- package/stack.md +271 -42
- package/string.gr +453 -533
- package/string.md +241 -151
- package/uint16.gr +369 -0
- package/uint16.md +585 -0
- package/uint32.gr +470 -0
- package/uint32.md +737 -0
- package/uint64.gr +471 -0
- package/uint64.md +737 -0
- package/uint8.gr +369 -0
- package/uint8.md +585 -0
- package/uri.gr +1093 -0
- package/uri.md +477 -0
- package/{sys → wasi}/file.gr +914 -500
- package/{sys → wasi}/file.md +454 -50
- package/wasi/process.gr +292 -0
- package/{sys → wasi}/process.md +164 -6
- package/wasi/random.gr +77 -0
- package/wasi/random.md +80 -0
- package/{sys → wasi}/time.gr +15 -22
- package/{sys → wasi}/time.md +5 -5
- package/immutablearray.gr +0 -929
- package/immutablearray.md +0 -1038
- package/immutablemap.gr +0 -493
- package/immutablemap.md +0 -479
- package/immutablepriorityqueue.gr +0 -360
- package/immutablepriorityqueue.md +0 -291
- package/immutableset.gr +0 -498
- package/immutableset.md +0 -449
- package/runtime/debug.gr +0 -2
- package/runtime/debug.md +0 -6
- package/runtime/unsafe/errors.gr +0 -36
- package/runtime/unsafe/errors.md +0 -204
- package/sys/process.gr +0 -254
- package/sys/random.gr +0 -79
- package/sys/random.md +0 -66
package/runtime/atof/decimal.gr
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/* grainc-flags --no-pervasives */
|
|
2
|
-
|
|
3
1
|
// This module was based on Rust's dec2flt
|
|
4
2
|
// https://github.com/rust-lang/rust/blob/1cbc45942d5c0f6eb5d94e3b10762ba541958035/library/core/src/num/dec2flt/decimal.rs
|
|
5
3
|
// Rust's MIT license is provided below:
|
|
@@ -13,11 +11,11 @@
|
|
|
13
11
|
* the Software, and to permit persons to whom the Software
|
|
14
12
|
* is furnished to do so, subject to the following
|
|
15
13
|
* conditions:
|
|
16
|
-
*
|
|
14
|
+
*
|
|
17
15
|
* The above copyright notice and this permission notice
|
|
18
16
|
* shall be included in all copies or substantial portions
|
|
19
17
|
* of the Software.
|
|
20
|
-
*
|
|
18
|
+
*
|
|
21
19
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
|
22
20
|
* ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
|
23
21
|
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
|
@@ -28,13 +26,17 @@
|
|
|
28
26
|
* IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
29
27
|
* DEALINGS IN THE SOFTWARE.
|
|
30
28
|
*/
|
|
29
|
+
@noPervasives
|
|
30
|
+
module Decimal
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
from "runtime/unsafe/wasmi32" include WasmI32
|
|
33
|
+
from "runtime/unsafe/wasmi64" include WasmI64
|
|
34
|
+
from "runtime/unsafe/memory" include Memory
|
|
35
|
+
from "runtime/dataStructures" include DataStructures
|
|
36
|
+
use DataStructures.{ newInt32, allocateBytes }
|
|
36
37
|
|
|
37
|
-
|
|
38
|
+
from "runtime/atof/common" include Common
|
|
39
|
+
use Common.{
|
|
38
40
|
_CHAR_CODE_UNDERSCORE,
|
|
39
41
|
_CHAR_CODE_PLUS,
|
|
40
42
|
_CHAR_CODE_MINUS,
|
|
@@ -43,20 +45,28 @@ import {
|
|
|
43
45
|
_CHAR_CODE_e,
|
|
44
46
|
_CHAR_CODE_DOT,
|
|
45
47
|
is8Digits,
|
|
46
|
-
}
|
|
48
|
+
}
|
|
47
49
|
|
|
48
|
-
primitive (&&)
|
|
49
|
-
primitive (||)
|
|
50
|
-
primitive (!)
|
|
50
|
+
primitive (&&) = "@and"
|
|
51
|
+
primitive (||) = "@or"
|
|
52
|
+
primitive (!) = "@not"
|
|
51
53
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
+
provide record Decimal {
|
|
55
|
+
/**
|
|
56
|
+
* The number of significant digits in the decimal.
|
|
57
|
+
*/
|
|
54
58
|
mut numDigits: Int32,
|
|
55
|
-
|
|
59
|
+
/**
|
|
60
|
+
* The offset of the decimal point in the significant digits.
|
|
61
|
+
*/
|
|
56
62
|
mut decimalPoint: Int32,
|
|
57
|
-
|
|
63
|
+
/**
|
|
64
|
+
* If the number of significant digits stored in the decimal is truncated.
|
|
65
|
+
*/
|
|
58
66
|
mut truncated: Bool,
|
|
59
|
-
|
|
67
|
+
/**
|
|
68
|
+
* Buffer of the raw digits, in the range [0, 9].
|
|
69
|
+
*/
|
|
60
70
|
digits: Bytes,
|
|
61
71
|
}
|
|
62
72
|
|
|
@@ -93,35 +103,33 @@ let _MAX_DIGITS = 768n
|
|
|
93
103
|
@unsafe
|
|
94
104
|
let _MAX_DIGITS_WITHOUT_OVERFLOW = 19n
|
|
95
105
|
@unsafe
|
|
96
|
-
|
|
106
|
+
provide let _DECIMAL_POINT_RANGE = 2047n
|
|
97
107
|
|
|
98
108
|
@unsafe
|
|
99
109
|
let new = () => {
|
|
110
|
+
use WasmI32.{ (+) }
|
|
100
111
|
let digits = allocateBytes(_MAX_DIGITS)
|
|
101
|
-
Memory.fill(
|
|
112
|
+
Memory.fill(digits + 8n, 0n, _MAX_DIGITS)
|
|
102
113
|
let digits = WasmI32.toGrain(digits)
|
|
103
114
|
{ numDigits: 0l, decimalPoint: 0l, truncated: false, digits }
|
|
104
115
|
}
|
|
105
116
|
|
|
106
117
|
// Append a digit to the buffer.
|
|
107
118
|
@unsafe
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
let numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits),
|
|
119
|
+
provide let tryAddDigit = (d, digit) => {
|
|
120
|
+
use WasmI32.{ (+) }
|
|
121
|
+
let numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 4n)
|
|
111
122
|
if (WasmI32.ltU(numDigits, _MAX_DIGITS)) {
|
|
112
123
|
let digits = WasmI32.fromGrain(d.digits)
|
|
113
124
|
WasmI32.store8(digits + numDigits, digit, 8n)
|
|
114
125
|
}
|
|
115
|
-
d.numDigits = WasmI32.toGrain(newInt32(
|
|
126
|
+
d.numDigits = WasmI32.toGrain(newInt32(numDigits + 1n))
|
|
116
127
|
}
|
|
117
128
|
|
|
118
129
|
// Trim trailing zeros from the buffer.
|
|
119
130
|
@unsafe
|
|
120
131
|
let trim = d => {
|
|
121
|
-
|
|
122
|
-
let (==) = WasmI32.eq
|
|
123
|
-
let (+) = WasmI32.add
|
|
124
|
-
let (-) = WasmI32.sub
|
|
132
|
+
use WasmI32.{ (+), (-), (==), (!=) }
|
|
125
133
|
// Calls to `trim` in this module are fine because:
|
|
126
134
|
//
|
|
127
135
|
// 1. `parseDecimal` sets `numDigits` to a max of `_MAX_DIGITS`.
|
|
@@ -130,7 +138,7 @@ let trim = d => {
|
|
|
130
138
|
//
|
|
131
139
|
// Trim is only called in `rightShift` and `leftShift`.
|
|
132
140
|
let digits = WasmI32.fromGrain(d.digits)
|
|
133
|
-
let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits),
|
|
141
|
+
let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 4n)
|
|
134
142
|
while (
|
|
135
143
|
numDigits != 0n &&
|
|
136
144
|
WasmI32.eqz(WasmI32.load8U(digits + (numDigits - 1n), 8n))
|
|
@@ -141,18 +149,12 @@ let trim = d => {
|
|
|
141
149
|
}
|
|
142
150
|
|
|
143
151
|
@unsafe
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
let (+) = WasmI32.add
|
|
148
|
-
let (-) = WasmI32.sub
|
|
149
|
-
let (>) = WasmI32.gtS
|
|
150
|
-
let (>=) = WasmI32.geS
|
|
151
|
-
let (<) = WasmI32.ltS
|
|
152
|
-
let (&) = WasmI32.and
|
|
152
|
+
provide let round = d => {
|
|
153
|
+
use WasmI32.{ (+), (-), (&), (<), (>), (>=), (==), (!=) }
|
|
154
|
+
use WasmI64.{ (+) as addWasmI64, (*) }
|
|
153
155
|
let digits = WasmI32.fromGrain(d.digits)
|
|
154
|
-
let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits),
|
|
155
|
-
let mut decimalPoint = WasmI32.load(WasmI32.fromGrain(d.decimalPoint),
|
|
156
|
+
let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 4n)
|
|
157
|
+
let mut decimalPoint = WasmI32.load(WasmI32.fromGrain(d.decimalPoint), 4n)
|
|
156
158
|
if (numDigits == 0n || decimalPoint < 0n) {
|
|
157
159
|
0N
|
|
158
160
|
} else if (decimalPoint > 18n) {
|
|
@@ -161,9 +163,9 @@ export let round = d => {
|
|
|
161
163
|
let dp = decimalPoint
|
|
162
164
|
let mut n = 0_N
|
|
163
165
|
for (let mut i = 0n; i < dp; i += 1n) {
|
|
164
|
-
n
|
|
166
|
+
n *= 10N
|
|
165
167
|
if (i < numDigits) {
|
|
166
|
-
n =
|
|
168
|
+
n = addWasmI64(n, WasmI64.extendI32U(WasmI32.load8U(digits + i, 8n)))
|
|
167
169
|
}
|
|
168
170
|
}
|
|
169
171
|
let mut roundUp = false
|
|
@@ -176,7 +178,7 @@ export let round = d => {
|
|
|
176
178
|
}
|
|
177
179
|
}
|
|
178
180
|
if (roundUp) {
|
|
179
|
-
n =
|
|
181
|
+
n = addWasmI64(n, 1N)
|
|
180
182
|
}
|
|
181
183
|
n
|
|
182
184
|
}
|
|
@@ -186,8 +188,8 @@ export let round = d => {
|
|
|
186
188
|
let mut _TABLE = -1n
|
|
187
189
|
|
|
188
190
|
@unsafe
|
|
189
|
-
|
|
190
|
-
|
|
191
|
+
provide let get_TABLE = () => {
|
|
192
|
+
use WasmI32.{ (==) }
|
|
191
193
|
if (_TABLE == -1n) {
|
|
192
194
|
_TABLE = Memory.malloc(130n)
|
|
193
195
|
WasmI32.store16(_TABLE, 0x0000n, 0n)
|
|
@@ -263,8 +265,8 @@ export let get_TABLE = () => {
|
|
|
263
265
|
let mut _TABLE_POW5 = -1n
|
|
264
266
|
|
|
265
267
|
@unsafe
|
|
266
|
-
|
|
267
|
-
|
|
268
|
+
provide let get_TABLE_POW5 = () => {
|
|
269
|
+
use WasmI32.{ (==) }
|
|
268
270
|
// formatter-ignore
|
|
269
271
|
if (_TABLE_POW5 == -1n) {
|
|
270
272
|
_TABLE_POW5 = Memory.malloc(0x051Cn)
|
|
@@ -318,25 +320,18 @@ export let get_TABLE_POW5 = () => {
|
|
|
318
320
|
|
|
319
321
|
@unsafe
|
|
320
322
|
let numberOfDigitsDecimalLeftShift = (d, shift) => {
|
|
321
|
-
|
|
322
|
-
let (-) = WasmI32.sub
|
|
323
|
-
let (&) = WasmI32.and
|
|
324
|
-
let (<) = WasmI32.ltU
|
|
325
|
-
let (>=) = WasmI32.geU
|
|
326
|
-
let (>>) = WasmI32.shrU
|
|
327
|
-
let (<<) = WasmI32.shl
|
|
328
|
-
let (==) = WasmI32.eq
|
|
323
|
+
use WasmI32.{ (+), (-), (&), ltU as (<), geU as (>=), (==), (>>>), (<<) }
|
|
329
324
|
|
|
330
325
|
let table = get_TABLE()
|
|
331
326
|
let tablePow5 = get_TABLE_POW5()
|
|
332
327
|
|
|
333
328
|
let digits = WasmI32.fromGrain(d.digits)
|
|
334
|
-
let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits),
|
|
329
|
+
let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 4n)
|
|
335
330
|
|
|
336
331
|
let shift = (shift & 63n) << 1n
|
|
337
332
|
let x_a = WasmI32.load16U(table + shift, 0n)
|
|
338
333
|
let x_b = WasmI32.load16U(table + shift, 2n)
|
|
339
|
-
let mut numNewDigits = x_a
|
|
334
|
+
let mut numNewDigits = x_a >>> 11n
|
|
340
335
|
let pow5_a = 0x7FFn & x_a
|
|
341
336
|
let pow5_b = 0x7FFn & x_b
|
|
342
337
|
let offset = pow5_a
|
|
@@ -360,23 +355,21 @@ let numberOfDigitsDecimalLeftShift = (d, shift) => {
|
|
|
360
355
|
|
|
361
356
|
// Computes decimal * 2^shift.
|
|
362
357
|
@unsafe
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
let (-) = WasmI32.sub
|
|
366
|
-
let (&) = WasmI32.and
|
|
367
|
-
let (<) = WasmI32.ltS
|
|
368
|
-
let (>) = WasmI32.gtS
|
|
369
|
-
let (>=) = WasmI32.geS
|
|
370
|
-
let (==) = WasmI32.eq
|
|
371
|
-
let (!=) = WasmI32.ne
|
|
358
|
+
provide let leftShift = (d, shift) => {
|
|
359
|
+
use WasmI32.{ (+), (-), (&), (<), (>=), (==), (!=) }
|
|
372
360
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
361
|
+
use WasmI64.{
|
|
362
|
+
(+) as addWasmI64,
|
|
363
|
+
(-) as subWasmI64,
|
|
364
|
+
(*),
|
|
365
|
+
divU as (/),
|
|
366
|
+
(<<),
|
|
367
|
+
(>),
|
|
368
|
+
}
|
|
376
369
|
|
|
377
370
|
let digits = WasmI32.fromGrain(d.digits)
|
|
378
|
-
let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits),
|
|
379
|
-
let mut decimalPoint = WasmI32.load(WasmI32.fromGrain(d.decimalPoint),
|
|
371
|
+
let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 4n)
|
|
372
|
+
let mut decimalPoint = WasmI32.load(WasmI32.fromGrain(d.decimalPoint), 4n)
|
|
380
373
|
|
|
381
374
|
if (numDigits != 0n) {
|
|
382
375
|
let numNewDigits = numberOfDigitsDecimalLeftShift(d, shift)
|
|
@@ -386,32 +379,33 @@ export let leftShift = (d, shift) => {
|
|
|
386
379
|
while (readIndex != 0n) {
|
|
387
380
|
readIndex -= 1n
|
|
388
381
|
writeIndex -= 1n
|
|
389
|
-
n =
|
|
382
|
+
n = addWasmI64(
|
|
390
383
|
n,
|
|
391
384
|
WasmI64.extendI32U(WasmI32.load8U(digits + readIndex, 8n)) <<
|
|
392
|
-
|
|
385
|
+
WasmI64.extendI32U(shift)
|
|
393
386
|
)
|
|
394
387
|
let quotient = n / 10N
|
|
395
|
-
let remainder =
|
|
388
|
+
let remainder = subWasmI64(n, 10N * quotient)
|
|
396
389
|
if (writeIndex < _MAX_DIGITS) {
|
|
397
390
|
WasmI32.store8(digits + writeIndex, WasmI32.wrapI64(remainder), 8n)
|
|
398
|
-
} else if (
|
|
391
|
+
} else if (remainder > 0N) {
|
|
399
392
|
d.truncated = true
|
|
400
393
|
}
|
|
401
394
|
n = quotient
|
|
402
395
|
}
|
|
403
|
-
while (
|
|
396
|
+
while (n > 0N) {
|
|
404
397
|
writeIndex -= 1n
|
|
405
398
|
let quotient = n / 10N
|
|
406
|
-
let remainder =
|
|
399
|
+
let remainder = subWasmI64(n, 10N * quotient)
|
|
407
400
|
if (writeIndex < _MAX_DIGITS) {
|
|
408
401
|
WasmI32.store8(digits + writeIndex, WasmI32.wrapI64(remainder), 8n)
|
|
409
|
-
} else if (
|
|
402
|
+
} else if (remainder > 0N) {
|
|
410
403
|
d.truncated = true
|
|
411
404
|
}
|
|
412
405
|
n = quotient
|
|
413
406
|
}
|
|
414
407
|
numDigits += numNewDigits
|
|
408
|
+
use WasmI32.{ (>) }
|
|
415
409
|
if (numDigits > _MAX_DIGITS) {
|
|
416
410
|
numDigits = _MAX_DIGITS
|
|
417
411
|
}
|
|
@@ -425,31 +419,22 @@ export let leftShift = (d, shift) => {
|
|
|
425
419
|
|
|
426
420
|
// Computes decimal * 2^-shift.
|
|
427
421
|
@unsafe
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
let (-) = WasmI32.sub
|
|
431
|
-
let (&) = WasmI32.and
|
|
432
|
-
let (<) = WasmI32.ltS
|
|
433
|
-
let (>) = WasmI32.gtS
|
|
434
|
-
let (>=) = WasmI32.geS
|
|
435
|
-
let (==) = WasmI32.eq
|
|
436
|
-
let (!=) = WasmI32.ne
|
|
422
|
+
provide let rightShift = (d, shift) => {
|
|
423
|
+
use WasmI32.{ (+), (-), (&), (<), (>), (>=), (==), (!=) }
|
|
437
424
|
|
|
438
|
-
|
|
439
|
-
let (>>) = WasmI64.shrU
|
|
440
|
-
let (*) = WasmI64.mul
|
|
425
|
+
use WasmI64.{ (+) as addWasmI64, (-) as subWasmI64, (*), (&), (<<), (>>>) }
|
|
441
426
|
|
|
442
427
|
let digits = WasmI32.fromGrain(d.digits)
|
|
443
|
-
let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits),
|
|
444
|
-
let mut decimalPoint = WasmI32.load(WasmI32.fromGrain(d.decimalPoint),
|
|
428
|
+
let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 4n)
|
|
429
|
+
let mut decimalPoint = WasmI32.load(WasmI32.fromGrain(d.decimalPoint), 4n)
|
|
445
430
|
|
|
446
431
|
let mut readIndex = 0n
|
|
447
432
|
let mut writeIndex = 0n
|
|
448
433
|
let mut n = 0N
|
|
449
434
|
let mut done = false
|
|
450
|
-
while (WasmI64.eqz(n
|
|
435
|
+
while (WasmI64.eqz(n >>> WasmI64.extendI32U(shift))) {
|
|
451
436
|
if (readIndex < numDigits) {
|
|
452
|
-
n =
|
|
437
|
+
n = addWasmI64(
|
|
453
438
|
10N * n,
|
|
454
439
|
WasmI64.extendI32U(WasmI32.load8U(digits + readIndex, 8n))
|
|
455
440
|
)
|
|
@@ -458,7 +443,7 @@ export let rightShift = (d, shift) => {
|
|
|
458
443
|
done = true
|
|
459
444
|
break
|
|
460
445
|
} else {
|
|
461
|
-
while (WasmI64.eqz(n
|
|
446
|
+
while (WasmI64.eqz(n >>> WasmI64.extendI32U(shift))) {
|
|
462
447
|
n *= 10N
|
|
463
448
|
readIndex += 1n
|
|
464
449
|
}
|
|
@@ -475,11 +460,11 @@ export let rightShift = (d, shift) => {
|
|
|
475
460
|
d.numDigits = WasmI32.toGrain(newInt32(numDigits))
|
|
476
461
|
d.decimalPoint = WasmI32.toGrain(newInt32(decimalPoint))
|
|
477
462
|
} else {
|
|
478
|
-
let mask =
|
|
463
|
+
let mask = subWasmI64(1N << WasmI64.extendI32U(shift), 1N)
|
|
479
464
|
while (readIndex < numDigits) {
|
|
480
|
-
let newDigit = n
|
|
481
|
-
n =
|
|
482
|
-
10N *
|
|
465
|
+
let newDigit = n >>> WasmI64.extendI32U(shift)
|
|
466
|
+
n = addWasmI64(
|
|
467
|
+
10N * (n & mask),
|
|
483
468
|
WasmI64.extendI32U(WasmI32.load8U(digits + readIndex, 8n))
|
|
484
469
|
)
|
|
485
470
|
readIndex += 1n
|
|
@@ -487,12 +472,13 @@ export let rightShift = (d, shift) => {
|
|
|
487
472
|
writeIndex += 1n
|
|
488
473
|
}
|
|
489
474
|
while (WasmI64.gtU(n, 0N)) {
|
|
490
|
-
|
|
491
|
-
|
|
475
|
+
use WasmI64.{ (>) }
|
|
476
|
+
let newDigit = n >>> WasmI64.extendI32U(shift)
|
|
477
|
+
n = 10N * (n & mask)
|
|
492
478
|
if (writeIndex < _MAX_DIGITS) {
|
|
493
479
|
WasmI32.store8(digits + writeIndex, WasmI32.wrapI64(newDigit), 8n)
|
|
494
480
|
writeIndex += 1n
|
|
495
|
-
} else if (
|
|
481
|
+
} else if (newDigit > 0N) {
|
|
496
482
|
d.truncated = true
|
|
497
483
|
}
|
|
498
484
|
}
|
|
@@ -507,16 +493,8 @@ export let rightShift = (d, shift) => {
|
|
|
507
493
|
|
|
508
494
|
// Parse a big integer representation of the float as a decimal.
|
|
509
495
|
@unsafe
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
let (*) = WasmI32.mul
|
|
513
|
-
let (-) = WasmI32.sub
|
|
514
|
-
let (&) = WasmI32.and
|
|
515
|
-
let (<) = WasmI32.ltS
|
|
516
|
-
let (>) = WasmI32.gtS
|
|
517
|
-
let (>=) = WasmI32.geS
|
|
518
|
-
let (==) = WasmI32.eq
|
|
519
|
-
let (!=) = WasmI32.ne
|
|
496
|
+
provide let parseDecimal = (s: String) => {
|
|
497
|
+
use WasmI32.{ (+), (-), (*), (&), (<), (>), (>=), (==), (!=) }
|
|
520
498
|
|
|
521
499
|
let d = new()
|
|
522
500
|
let s = WasmI32.fromGrain(s)
|
|
@@ -552,7 +530,7 @@ export let parseDecimal = (s: String) => {
|
|
|
552
530
|
let c = WasmI32.load8U(s + i, 8n)
|
|
553
531
|
if (c == _CHAR_CODE_DOT) {
|
|
554
532
|
i += 1n
|
|
555
|
-
let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits),
|
|
533
|
+
let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 4n)
|
|
556
534
|
let numDigitsBeforeDecimal = numDigits
|
|
557
535
|
// Skip leading zeros.
|
|
558
536
|
if (numDigits == 0n) {
|
|
@@ -566,15 +544,12 @@ export let parseDecimal = (s: String) => {
|
|
|
566
544
|
}
|
|
567
545
|
}
|
|
568
546
|
while (len - i >= 8n && numDigits + 8n < _MAX_DIGITS) {
|
|
547
|
+
use WasmI64.{ (-) }
|
|
569
548
|
let v = WasmI64.load(s + i, 0n)
|
|
570
549
|
if (!is8Digits(v)) {
|
|
571
550
|
break
|
|
572
551
|
}
|
|
573
|
-
WasmI64.store(
|
|
574
|
-
digits + numDigits,
|
|
575
|
-
WasmI64.sub(v, 0x3030_3030_3030_3030N),
|
|
576
|
-
8n
|
|
577
|
-
)
|
|
552
|
+
WasmI64.store(digits + numDigits, v - 0x3030_3030_3030_3030N, 8n)
|
|
578
553
|
numDigits += 8n
|
|
579
554
|
i += 8n
|
|
580
555
|
}
|
|
@@ -591,12 +566,12 @@ export let parseDecimal = (s: String) => {
|
|
|
591
566
|
break
|
|
592
567
|
}
|
|
593
568
|
}
|
|
594
|
-
numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits),
|
|
569
|
+
numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 4n)
|
|
595
570
|
d.decimalPoint = WasmI32.toGrain(
|
|
596
571
|
newInt32(numDigitsBeforeDecimal - numDigits)
|
|
597
572
|
)
|
|
598
573
|
}
|
|
599
|
-
let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits),
|
|
574
|
+
let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 4n)
|
|
600
575
|
if (numDigits != 0n) {
|
|
601
576
|
// Ignore the trailing zeros if there are any
|
|
602
577
|
let mut nTrailingZeros = 0n
|
|
@@ -610,7 +585,7 @@ export let parseDecimal = (s: String) => {
|
|
|
610
585
|
break
|
|
611
586
|
}
|
|
612
587
|
}
|
|
613
|
-
let mut decimalPoint = WasmI32.load(WasmI32.fromGrain(d.decimalPoint),
|
|
588
|
+
let mut decimalPoint = WasmI32.load(WasmI32.fromGrain(d.decimalPoint), 4n)
|
|
614
589
|
decimalPoint += nTrailingZeros
|
|
615
590
|
numDigits -= nTrailingZeros
|
|
616
591
|
decimalPoint += numDigits
|
|
@@ -647,15 +622,15 @@ export let parseDecimal = (s: String) => {
|
|
|
647
622
|
break
|
|
648
623
|
}
|
|
649
624
|
}
|
|
650
|
-
let mut decimalPoint = WasmI32.load(WasmI32.fromGrain(d.decimalPoint),
|
|
625
|
+
let mut decimalPoint = WasmI32.load(WasmI32.fromGrain(d.decimalPoint), 4n)
|
|
651
626
|
decimalPoint += if (negExp) {
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
627
|
+
0n - expNum
|
|
628
|
+
} else {
|
|
629
|
+
expNum
|
|
630
|
+
}
|
|
656
631
|
d.decimalPoint = WasmI32.toGrain(newInt32(decimalPoint))
|
|
657
632
|
}
|
|
658
|
-
let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits),
|
|
633
|
+
let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 4n)
|
|
659
634
|
for (let mut i = numDigits; i < _MAX_DIGITS_WITHOUT_OVERFLOW; i += 1n) {
|
|
660
635
|
WasmI32.store8(digits + i, 0n, 8n)
|
|
661
636
|
}
|
package/runtime/atof/decimal.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Decimal
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Types
|
|
6
|
+
|
|
7
|
+
Type declarations included in the Decimal module.
|
|
8
|
+
|
|
1
9
|
### Decimal.**Decimal**
|
|
2
10
|
|
|
3
11
|
```grain
|
|
@@ -9,6 +17,19 @@ record Decimal {
|
|
|
9
17
|
}
|
|
10
18
|
```
|
|
11
19
|
|
|
20
|
+
Fields:
|
|
21
|
+
|
|
22
|
+
|name|type|description|
|
|
23
|
+
|----|----|-----------|
|
|
24
|
+
|`numDigits`|`Int32`|The number of significant digits in the decimal.|
|
|
25
|
+
|`decimalPoint`|`Int32`|The offset of the decimal point in the significant digits.|
|
|
26
|
+
|`truncated`|`Bool`|If the number of significant digits stored in the decimal is truncated.|
|
|
27
|
+
|`digits`|`Bytes`|Buffer of the raw digits, in the range [0, 9].|
|
|
28
|
+
|
|
29
|
+
## Values
|
|
30
|
+
|
|
31
|
+
Functions and constants included in the Decimal module.
|
|
32
|
+
|
|
12
33
|
### Decimal.**_DECIMAL_POINT_RANGE**
|
|
13
34
|
|
|
14
35
|
```grain
|
|
@@ -18,42 +39,42 @@ _DECIMAL_POINT_RANGE : WasmI32
|
|
|
18
39
|
### Decimal.**tryAddDigit**
|
|
19
40
|
|
|
20
41
|
```grain
|
|
21
|
-
tryAddDigit : (Decimal, WasmI32)
|
|
42
|
+
tryAddDigit : (d: Decimal, digit: WasmI32) => Void
|
|
22
43
|
```
|
|
23
44
|
|
|
24
45
|
### Decimal.**round**
|
|
25
46
|
|
|
26
47
|
```grain
|
|
27
|
-
round : Decimal
|
|
48
|
+
round : (d: Decimal) => WasmI64
|
|
28
49
|
```
|
|
29
50
|
|
|
30
51
|
### Decimal.**get_TABLE**
|
|
31
52
|
|
|
32
53
|
```grain
|
|
33
|
-
get_TABLE : ()
|
|
54
|
+
get_TABLE : () => WasmI32
|
|
34
55
|
```
|
|
35
56
|
|
|
36
57
|
### Decimal.**get_TABLE_POW5**
|
|
37
58
|
|
|
38
59
|
```grain
|
|
39
|
-
get_TABLE_POW5 : ()
|
|
60
|
+
get_TABLE_POW5 : () => WasmI32
|
|
40
61
|
```
|
|
41
62
|
|
|
42
63
|
### Decimal.**leftShift**
|
|
43
64
|
|
|
44
65
|
```grain
|
|
45
|
-
leftShift : (Decimal, WasmI32)
|
|
66
|
+
leftShift : (d: Decimal, shift: WasmI32) => Void
|
|
46
67
|
```
|
|
47
68
|
|
|
48
69
|
### Decimal.**rightShift**
|
|
49
70
|
|
|
50
71
|
```grain
|
|
51
|
-
rightShift : (Decimal, WasmI32)
|
|
72
|
+
rightShift : (d: Decimal, shift: WasmI32) => Void
|
|
52
73
|
```
|
|
53
74
|
|
|
54
75
|
### Decimal.**parseDecimal**
|
|
55
76
|
|
|
56
77
|
```grain
|
|
57
|
-
parseDecimal : String
|
|
78
|
+
parseDecimal : (s: String) => Decimal
|
|
58
79
|
```
|
|
59
80
|
|