@grain/stdlib 0.6.6 → 0.7.0
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 +57 -0
- package/LICENSE +1 -1
- package/README.md +2 -2
- package/array.gr +55 -7
- package/array.md +123 -77
- package/bigint.md +30 -30
- package/buffer.gr +20 -53
- package/buffer.md +47 -47
- package/bytes.gr +111 -35
- package/bytes.md +111 -32
- package/char.gr +201 -99
- package/char.md +361 -34
- package/exception.gr +11 -11
- package/exception.md +26 -1
- package/float32.gr +327 -3
- package/float32.md +606 -19
- package/float64.gr +320 -3
- package/float64.md +606 -19
- package/fs.gr +1082 -0
- package/fs.md +630 -0
- package/hash.gr +142 -88
- package/hash.md +102 -14
- package/int16.md +23 -23
- package/int32.gr +25 -4
- package/int32.md +65 -30
- package/int64.gr +26 -1
- package/int64.md +65 -30
- package/int8.md +23 -23
- package/json.gr +366 -51
- package/json.md +418 -2
- package/list.gr +328 -31
- package/list.md +492 -69
- package/map.gr +20 -12
- package/map.md +44 -38
- package/marshal.gr +41 -40
- package/marshal.md +2 -2
- package/number.gr +159 -30
- package/number.md +215 -38
- package/option.md +21 -21
- package/package.json +5 -3
- package/path.gr +48 -0
- package/path.md +103 -12
- package/pervasives.gr +2 -2
- package/pervasives.md +37 -37
- package/priorityqueue.gr +7 -7
- package/priorityqueue.md +19 -19
- package/queue.gr +183 -29
- package/queue.md +296 -40
- package/random.md +6 -6
- package/range.gr +4 -4
- package/range.md +6 -6
- package/rational.md +16 -16
- package/regex.gr +52 -51
- package/regex.md +11 -11
- package/result.md +16 -16
- package/runtime/atof/common.md +39 -39
- package/runtime/atof/decimal.gr +6 -6
- package/runtime/atof/decimal.md +8 -8
- package/runtime/atof/lemire.gr +5 -5
- package/runtime/atof/lemire.md +1 -1
- package/runtime/atof/parse.gr +16 -16
- package/runtime/atof/parse.md +2 -2
- package/runtime/atof/slow.md +1 -1
- package/runtime/atof/table.md +2 -2
- package/runtime/atoi/parse.gr +3 -3
- package/runtime/atoi/parse.md +1 -1
- package/runtime/bigint.gr +15 -47
- package/runtime/bigint.md +54 -60
- package/runtime/compare.gr +2 -2
- package/runtime/compare.md +1 -1
- package/runtime/dataStructures.md +33 -33
- package/runtime/debugPrint.gr +4 -1
- package/runtime/debugPrint.md +9 -9
- package/runtime/equal.gr +99 -77
- package/runtime/equal.md +1 -1
- package/runtime/exception.gr +62 -82
- package/runtime/exception.md +62 -11
- package/runtime/gc.gr +39 -45
- package/runtime/gc.md +4 -4
- package/runtime/malloc.gr +7 -7
- package/runtime/malloc.md +4 -4
- package/runtime/math/kernel/cos.gr +70 -0
- package/runtime/math/kernel/cos.md +14 -0
- package/runtime/math/kernel/sin.gr +65 -0
- package/runtime/math/kernel/sin.md +14 -0
- package/runtime/math/kernel/tan.gr +136 -0
- package/runtime/math/kernel/tan.md +14 -0
- package/runtime/math/rempio2.gr +244 -0
- package/runtime/math/rempio2.md +14 -0
- package/runtime/math/trig.gr +130 -0
- package/runtime/math/trig.md +28 -0
- package/runtime/math/umuldi.gr +26 -0
- package/runtime/math/umuldi.md +14 -0
- package/runtime/numberUtils.gr +29 -29
- package/runtime/numberUtils.md +12 -12
- package/runtime/numbers.gr +373 -381
- package/runtime/numbers.md +79 -73
- package/runtime/string.gr +37 -105
- package/runtime/string.md +3 -9
- package/runtime/unsafe/constants.md +24 -24
- package/runtime/unsafe/conv.md +13 -13
- package/runtime/unsafe/memory.gr +24 -20
- package/runtime/unsafe/memory.md +27 -7
- package/runtime/unsafe/offsets.gr +36 -0
- package/runtime/unsafe/offsets.md +88 -0
- package/runtime/unsafe/panic.gr +28 -0
- package/runtime/unsafe/panic.md +14 -0
- package/runtime/unsafe/tags.md +32 -32
- package/runtime/unsafe/wasmf32.md +28 -28
- package/runtime/unsafe/wasmf64.md +28 -28
- package/runtime/unsafe/wasmi32.md +47 -47
- package/runtime/unsafe/wasmi64.md +50 -50
- package/runtime/utf8.gr +189 -0
- package/runtime/utf8.md +117 -0
- package/runtime/wasi.gr +4 -2
- package/runtime/wasi.md +138 -138
- package/set.gr +18 -11
- package/set.md +42 -36
- package/stack.gr +171 -2
- package/stack.md +297 -15
- package/string.gr +352 -557
- package/string.md +77 -34
- package/uint16.md +22 -22
- package/uint32.gr +25 -4
- package/uint32.md +63 -28
- package/uint64.gr +25 -5
- package/uint64.md +63 -28
- package/uint8.md +22 -22
- package/uri.gr +57 -53
- package/uri.md +11 -12
- package/wasi/file.gr +67 -59
- package/wasi/file.md +39 -39
- package/wasi/process.md +5 -5
- package/wasi/random.md +3 -3
- package/wasi/time.md +4 -4
- package/runtime/utils/printing.gr +0 -60
- package/runtime/utils/printing.md +0 -26
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* ====================================================
|
|
3
|
+
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* Developed at SunSoft, a Sun Microsystems, Inc. business.
|
|
6
|
+
* Permission to use, copy, modify, and distribute this
|
|
7
|
+
* software is freely granted, provided that this notice
|
|
8
|
+
* is preserved.
|
|
9
|
+
* ====================================================
|
|
10
|
+
*/
|
|
11
|
+
module Rempio2
|
|
12
|
+
|
|
13
|
+
from "runtime/unsafe/wasmi32" include WasmI32
|
|
14
|
+
from "runtime/unsafe/wasmi64" include WasmI64
|
|
15
|
+
from "runtime/unsafe/wasmf64" include WasmF64
|
|
16
|
+
from "runtime/unsafe/memory" include Memory
|
|
17
|
+
from "runtime/unsafe/conv" include Conv
|
|
18
|
+
use Conv.{ toInt32, toUint64, toFloat64, fromInt32, fromUint64, fromFloat64 }
|
|
19
|
+
from "runtime/math/umuldi" include Umuldi
|
|
20
|
+
use Umuldi.{ umuldi }
|
|
21
|
+
|
|
22
|
+
// Note: This file could be simplified if we add support for i128
|
|
23
|
+
|
|
24
|
+
@unsafe
|
|
25
|
+
let pio2_right = (q0: WasmI64, q1: WasmI64) => { // see: jdh8/metallic/blob/master/src/math/double/rem_pio2.c
|
|
26
|
+
use WasmI64.{ (-), (|), (<<), (>>>), (<) }
|
|
27
|
+
use WasmF64.{ (+), (*) }
|
|
28
|
+
// Bits of π/4
|
|
29
|
+
let p0 = 0xC4C6628B80DC1CD1N
|
|
30
|
+
let p1 = 0xC90FDAA22168C234N
|
|
31
|
+
|
|
32
|
+
let shift = WasmI64.clz(q1)
|
|
33
|
+
let q1 = q1 << shift | q0 >>> (64N - shift)
|
|
34
|
+
let q0 = WasmF64.convertI64U(q0 << shift)
|
|
35
|
+
|
|
36
|
+
let (lo, hi) = umuldi(p1, q1)
|
|
37
|
+
let lo = fromUint64(lo)
|
|
38
|
+
let hi = fromUint64(hi)
|
|
39
|
+
|
|
40
|
+
let ahi = hi >>> 11N
|
|
41
|
+
let alo = lo >>> 11N | hi << 53N
|
|
42
|
+
let blo = WasmI64.truncF64U(
|
|
43
|
+
0x1p-75W * WasmF64.convertI64U(q1) + 0x1p-75W * WasmF64.convertI64U(p1) * q0
|
|
44
|
+
)
|
|
45
|
+
use WasmI64.{ (+) }
|
|
46
|
+
let y0 = WasmF64.convertI64U(ahi + (if (lo < blo) 1N else 0N))
|
|
47
|
+
let y1 = 0x1p-64W * WasmF64.convertI64U(alo + blo)
|
|
48
|
+
|
|
49
|
+
return (toUint64(shift), toFloat64(y0), toFloat64(y1))
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@unsafe
|
|
53
|
+
let mut _PIO2_TABLE = -1n
|
|
54
|
+
@unsafe
|
|
55
|
+
let pio2_large_quot = (x: WasmF64, i: WasmI64) => { // see: jdh8/metallic/blob/master/src/math/double/rem_pio2.c
|
|
56
|
+
/*
|
|
57
|
+
* Note: The original c implementation makes use of i128,
|
|
58
|
+
* as we do not have i128 the code here has to split
|
|
59
|
+
* high and low bits.
|
|
60
|
+
*/
|
|
61
|
+
use WasmI32.{ (+), (*), (==), (<<), (<=), (>=) }
|
|
62
|
+
use WasmI64.{ (-), (&), (>>>), (|), (!=) }
|
|
63
|
+
let magnitude = i & 0x7FFFFFFFFFFFFFFFN
|
|
64
|
+
// segmentation: note this would be better as a separate function but would require a heap allocation
|
|
65
|
+
let offset = (magnitude >>> 52N) - 1045N
|
|
66
|
+
let shift = offset & 63N
|
|
67
|
+
if (_PIO2_TABLE == -1n) {
|
|
68
|
+
// Note: This leaks memory but only in the sense that it allocates the array globally
|
|
69
|
+
_PIO2_TABLE = Memory.malloc(192n)
|
|
70
|
+
WasmI64.store(_PIO2_TABLE, 0x00000000A2F9836EN, 8n * 0n)
|
|
71
|
+
WasmI64.store(_PIO2_TABLE, 0x4E441529FC2757D1N, 8n * 1n)
|
|
72
|
+
WasmI64.store(_PIO2_TABLE, 0xF534DDC0DB629599N, 8n * 2n)
|
|
73
|
+
WasmI64.store(_PIO2_TABLE, 0x3C439041FE5163ABN, 8n * 3n)
|
|
74
|
+
|
|
75
|
+
WasmI64.store(_PIO2_TABLE, 0xDEBBC561B7246E3AN, 8n * 4n)
|
|
76
|
+
WasmI64.store(_PIO2_TABLE, 0x424DD2E006492EEAN, 8n * 5n)
|
|
77
|
+
WasmI64.store(_PIO2_TABLE, 0x09D1921CFE1DEB1CN, 8n * 6n)
|
|
78
|
+
WasmI64.store(_PIO2_TABLE, 0xB129A73EE88235F5N, 8n * 7n)
|
|
79
|
+
|
|
80
|
+
WasmI64.store(_PIO2_TABLE, 0x2EBB4484E99C7026N, 8n * 8n)
|
|
81
|
+
WasmI64.store(_PIO2_TABLE, 0xB45F7E413991D639N, 8n * 9n)
|
|
82
|
+
WasmI64.store(_PIO2_TABLE, 0x835339F49C845F8BN, 8n * 10n)
|
|
83
|
+
WasmI64.store(_PIO2_TABLE, 0xBDF9283B1FF897FFN, 8n * 11n)
|
|
84
|
+
|
|
85
|
+
WasmI64.store(_PIO2_TABLE, 0xDE05980FEF2F118BN, 8n * 12n)
|
|
86
|
+
WasmI64.store(_PIO2_TABLE, 0x5A0A6D1F6D367ECFN, 8n * 13n)
|
|
87
|
+
WasmI64.store(_PIO2_TABLE, 0x27CB09B74F463F66N, 8n * 14n)
|
|
88
|
+
WasmI64.store(_PIO2_TABLE, 0x9E5FEA2D7527BAC7N, 8n * 15n)
|
|
89
|
+
|
|
90
|
+
WasmI64.store(_PIO2_TABLE, 0xEBE5F17B3D0739F7N, 8n * 16n)
|
|
91
|
+
WasmI64.store(_PIO2_TABLE, 0x8A5292EA6BFB5FB1N, 8n * 17n)
|
|
92
|
+
WasmI64.store(_PIO2_TABLE, 0x1F8D5D0856033046N, 8n * 18n)
|
|
93
|
+
WasmI64.store(_PIO2_TABLE, 0xFC7B6BABF0CFBC20N, 8n * 19n)
|
|
94
|
+
|
|
95
|
+
WasmI64.store(_PIO2_TABLE, 0x9AF4361DA9E39161N, 8n * 20n)
|
|
96
|
+
WasmI64.store(_PIO2_TABLE, 0x5EE61B086599855FN, 8n * 21n)
|
|
97
|
+
WasmI64.store(_PIO2_TABLE, 0x14A068408DFFD880N, 8n * 22n)
|
|
98
|
+
WasmI64.store(_PIO2_TABLE, 0x4D73273106061557N, 8n * 23n)
|
|
99
|
+
}
|
|
100
|
+
let tblPtr = _PIO2_TABLE + (WasmI32.wrapI64(offset >>> 6N) << 3n)
|
|
101
|
+
let b0 = WasmI64.load(tblPtr, 8n * 0n)
|
|
102
|
+
let b1 = WasmI64.load(tblPtr, 8n * 1n)
|
|
103
|
+
let b2 = WasmI64.load(tblPtr, 8n * 2n)
|
|
104
|
+
|
|
105
|
+
// Get 192 bits of 0x1p-31 / π with `offset` bits skipped
|
|
106
|
+
let mut s0 = b0
|
|
107
|
+
let mut s1 = b1
|
|
108
|
+
let mut s2 = b2
|
|
109
|
+
if (shift != 0N) {
|
|
110
|
+
use WasmI64.{ (<<) }
|
|
111
|
+
let b3 = WasmI64.load(tblPtr, 8n * 3n)
|
|
112
|
+
let rshift = 64N - shift
|
|
113
|
+
s0 = b1 >>> rshift | b0 << shift
|
|
114
|
+
s1 = b2 >>> rshift | b1 << shift
|
|
115
|
+
s2 = b3 >>> rshift | b2 << shift
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
use WasmI64.{ (*), (+), (<), (<<) }
|
|
119
|
+
|
|
120
|
+
let significand = i & 0x000FFFFFFFFFFFFFN | 0x0010000000000000N
|
|
121
|
+
|
|
122
|
+
// First 128 bits of fractional part of x/(2π)
|
|
123
|
+
let (blo, bhi) = umuldi(s1, significand)
|
|
124
|
+
let blo = fromUint64(blo)
|
|
125
|
+
let bhi = fromUint64(bhi)
|
|
126
|
+
|
|
127
|
+
let ahi = s0 * significand
|
|
128
|
+
let clo = (s2 >>> 32N) * (significand >>> 32N)
|
|
129
|
+
let productLow = blo + clo
|
|
130
|
+
let productHigh = ahi + bhi + (if (productLow < clo) 1N else 0N)
|
|
131
|
+
// r = product << 2
|
|
132
|
+
let rLow = productLow << 2N
|
|
133
|
+
let rHigh = productHigh << 2N | productLow >>> 62N
|
|
134
|
+
// s = r >> 127
|
|
135
|
+
use WasmI64.{ (>>), (^) }
|
|
136
|
+
let sLow = rHigh >> 63N
|
|
137
|
+
let sHigh = sLow >> 1N
|
|
138
|
+
let q = WasmI32.wrapI64((productHigh >> 62N) - sLow)
|
|
139
|
+
|
|
140
|
+
let (right, y0, y1) = pio2_right(rLow ^ sLow, rHigh ^ sHigh)
|
|
141
|
+
let right = fromUint64(right)
|
|
142
|
+
let y0 = fromFloat64(y0)
|
|
143
|
+
let y1 = fromFloat64(y1)
|
|
144
|
+
|
|
145
|
+
let shifter = 0x3CB0000000000000N - (right << 52N)
|
|
146
|
+
let signbit = (i ^ rHigh) & 0x8000000000000000N
|
|
147
|
+
let coeff = WasmF64.reinterpretI64(shifter | signbit)
|
|
148
|
+
|
|
149
|
+
use WasmF64.{ (*) }
|
|
150
|
+
let y0 = y0 * coeff
|
|
151
|
+
let y1 = y1 * coeff
|
|
152
|
+
|
|
153
|
+
return (toInt32(q), toFloat64(y0), toFloat64(y1))
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
@unsafe
|
|
157
|
+
provide let rempio2 = (x: WasmF64, i: WasmI64, sign: Bool) => {
|
|
158
|
+
use WasmI32.{ (&), (<), (!=) }
|
|
159
|
+
use WasmI64.{ (>>>) }
|
|
160
|
+
use WasmF64.{ (+), (-), (*) }
|
|
161
|
+
let pio2_1 = 1.57079632673412561417e+00W /* 0x3FF921FB, 0x54400000 */
|
|
162
|
+
let pio2_1t = 6.07710050650619224932e-11W /* 0x3DD0B461, 0x1A626331 */
|
|
163
|
+
let pio2_2 = 6.07710050630396597660e-11W /* 0x3DD0B461, 0x1A600000 */
|
|
164
|
+
let pio2_2t = 2.02226624879595063154e-21W /* 0x3BA3198A, 0x2E037073 */
|
|
165
|
+
let pio2_3 = 2.02226624871116645580e-21W /* 0x3BA3198A, 0x2E000000 */
|
|
166
|
+
let pio2_3t = 8.47842766036889956997e-32W /* 0x397B839A, 0x252049C1 */
|
|
167
|
+
let invpio2 = 6.36619772367581382433e-01W /* 0x3FE45F30, 0x6DC9C883 */
|
|
168
|
+
|
|
169
|
+
// High word of x
|
|
170
|
+
let ix = WasmI32.wrapI64(i >>> 32N) & 0x7FFFFFFFn
|
|
171
|
+
|
|
172
|
+
if (ix < 0x4002D97Cn) { // |x| < 3pi/4, special case with n=+-1
|
|
173
|
+
if (!sign) {
|
|
174
|
+
let z = x - pio2_1
|
|
175
|
+
let mut y0 = 0.0W
|
|
176
|
+
let mut y1 = 0.0W
|
|
177
|
+
if (ix != 0x3FF921FBn) { // 33+53 bit pi is good enough
|
|
178
|
+
y0 = z - pio2_1t
|
|
179
|
+
y1 = z - y0 - pio2_1t
|
|
180
|
+
} else { // near pi/2, use 33+33+53 bit pi
|
|
181
|
+
let z = z - pio2_2
|
|
182
|
+
y0 = z - pio2_2t
|
|
183
|
+
y1 = z - y0 - pio2_2t
|
|
184
|
+
}
|
|
185
|
+
return (1l, toFloat64(y0), toFloat64(y1))
|
|
186
|
+
} else {
|
|
187
|
+
let z = x + pio2_1
|
|
188
|
+
let mut y0 = 0.0W
|
|
189
|
+
let mut y1 = 0.0W
|
|
190
|
+
if (ix != 0x3FF921FBn) { // 33+53 bit pi is good enough
|
|
191
|
+
y0 = z + pio2_1t
|
|
192
|
+
y1 = z - y0 + pio2_1t
|
|
193
|
+
} else { // near pi/2, use 33+33+53 bit pi
|
|
194
|
+
let z = z + pio2_2
|
|
195
|
+
y0 = z + pio2_2t
|
|
196
|
+
y1 = z - y0 + pio2_2t
|
|
197
|
+
}
|
|
198
|
+
return (-1l, toFloat64(y0), toFloat64(y1))
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (ix < 0x413921FBn) { // |x| ~< 2^20*pi/2, medium size
|
|
203
|
+
use WasmI32.{ (>>>) }
|
|
204
|
+
let q = WasmF64.nearest(x * invpio2)
|
|
205
|
+
let mut r = x - q * pio2_1
|
|
206
|
+
let mut w = q * pio2_1t // 1st round good to 85 bit
|
|
207
|
+
let j = ix >>> 20n
|
|
208
|
+
let mut y0 = r - w
|
|
209
|
+
use WasmI64.{ (>>>) }
|
|
210
|
+
let hi = WasmI32.wrapI64(WasmI64.reinterpretF64(y0) >>> 32N)
|
|
211
|
+
use WasmI32.{ (-), (>>>), (>) }
|
|
212
|
+
let i = j - (hi >>> 20n & 0x7FFn)
|
|
213
|
+
if (i > 16n) { // 2nd iteration needed, good to 118
|
|
214
|
+
use WasmF64.{ (-) }
|
|
215
|
+
let t = r
|
|
216
|
+
w = q * pio2_2
|
|
217
|
+
r = t - w
|
|
218
|
+
w = q * pio2_2t - (t - r - w)
|
|
219
|
+
y0 = r - w
|
|
220
|
+
use WasmI64.{ (>>>) }
|
|
221
|
+
let hi = WasmI32.wrapI64(WasmI64.reinterpretF64(y0) >>> 32N)
|
|
222
|
+
use WasmI32.{ (-), (>>>) }
|
|
223
|
+
let i = j - (hi >>> 20n & 0x7FFn)
|
|
224
|
+
if (i > 49n) { // 3rd iteration need, 151 bits acc
|
|
225
|
+
use WasmF64.{ (-) }
|
|
226
|
+
let t = r
|
|
227
|
+
w = q * pio2_3
|
|
228
|
+
r = t - w
|
|
229
|
+
w = q * pio2_3t - (t - r - w)
|
|
230
|
+
y0 = r - w
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
use WasmF64.{ (-) }
|
|
234
|
+
let y1 = r - y0 - w
|
|
235
|
+
let q = WasmI32.truncF64S(q)
|
|
236
|
+
return (toInt32(q), toFloat64(y0), toFloat64(y1))
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
let (q, y0, y1) = pio2_large_quot(x, i)
|
|
240
|
+
let q = fromInt32(q)
|
|
241
|
+
use WasmI32.{ (*) }
|
|
242
|
+
let q = if (sign) q * -1n else q
|
|
243
|
+
return (toInt32(q), y0, y1)
|
|
244
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Raw trigonometric functions.
|
|
3
|
+
*/
|
|
4
|
+
module Trig
|
|
5
|
+
|
|
6
|
+
from "runtime/unsafe/wasmi32" include WasmI32
|
|
7
|
+
from "runtime/unsafe/wasmi64" include WasmI64
|
|
8
|
+
from "runtime/unsafe/wasmf64" include WasmF64
|
|
9
|
+
from "runtime/unsafe/conv" include Conv
|
|
10
|
+
use Conv.{ fromInt32, fromFloat64 }
|
|
11
|
+
from "runtime/math/kernel/sin" include Sine
|
|
12
|
+
use Sine.{ sin as kernSin }
|
|
13
|
+
from "runtime/math/kernel/cos" include Cosine
|
|
14
|
+
use Cosine.{ cos as kernCos }
|
|
15
|
+
from "runtime/math/kernel/tan" include Tangent
|
|
16
|
+
use Tangent.{ tan as kernTan }
|
|
17
|
+
from "runtime/math/rempio2" include Rempio2
|
|
18
|
+
use Rempio2.{ rempio2 }
|
|
19
|
+
|
|
20
|
+
@unsafe
|
|
21
|
+
provide let sin = (x: WasmF64) => { // see: musl/src/math/sin.c
|
|
22
|
+
use WasmI32.{ (&), (<), (<=), (>=), (==) }
|
|
23
|
+
use WasmI64.{ (>>>) }
|
|
24
|
+
use WasmF64.{ (-), (*) }
|
|
25
|
+
|
|
26
|
+
let i = WasmI64.reinterpretF64(x)
|
|
27
|
+
// Get high word of x
|
|
28
|
+
let ix = WasmI32.wrapI64(i >>> 32N)
|
|
29
|
+
use WasmI32.{ (>>>) }
|
|
30
|
+
let sign = ix >>> 31n == 1n
|
|
31
|
+
let ix = ix & 0x7FFFFFFFn
|
|
32
|
+
|
|
33
|
+
// |x| ~< pi/4
|
|
34
|
+
if (ix <= 0x3FE921FBn) {
|
|
35
|
+
if (ix < 0x3E500000n) { // |x| < 2**-26
|
|
36
|
+
return x
|
|
37
|
+
}
|
|
38
|
+
return kernSin(x, 0.0W, false)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// sin(Inf or NaN) is NaN
|
|
42
|
+
if (ix >= 0x7FF00000n) return x - x
|
|
43
|
+
|
|
44
|
+
// argument reduction needed
|
|
45
|
+
let (n, y0, y1) = rempio2(x, i, sign)
|
|
46
|
+
let n = fromInt32(n)
|
|
47
|
+
let y0 = fromFloat64(y0)
|
|
48
|
+
let y1 = fromFloat64(y1)
|
|
49
|
+
|
|
50
|
+
return match (n & 3n) {
|
|
51
|
+
0n => kernSin(y0, y1, true),
|
|
52
|
+
1n => kernCos(y0, y1),
|
|
53
|
+
2n => kernSin(y0, y1, true) * -1.0W,
|
|
54
|
+
_ => kernCos(y0, y1) * -1.0W,
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@unsafe
|
|
59
|
+
provide let cos = (x: WasmF64) => { // see: musl/src/math/cos.c
|
|
60
|
+
use WasmI32.{ (&), (<), (<=), (>=), (==) }
|
|
61
|
+
use WasmI64.{ (>>>) }
|
|
62
|
+
use WasmF64.{ (-), (*) }
|
|
63
|
+
let i = WasmI64.reinterpretF64(x)
|
|
64
|
+
|
|
65
|
+
// Get high word of x
|
|
66
|
+
let ix = WasmI32.wrapI64(i >>> 32N)
|
|
67
|
+
use WasmI32.{ (>>>) }
|
|
68
|
+
let sign = ix >>> 31n == 1n
|
|
69
|
+
let ix = ix & 0x7FFFFFFFn
|
|
70
|
+
|
|
71
|
+
// |x| ~< pi/4
|
|
72
|
+
if (ix <= 0x3FE921FBn) {
|
|
73
|
+
if (ix < 0x3E46A09En) { // |x| < 2**-27 * sqrt(2)
|
|
74
|
+
return 1.0W
|
|
75
|
+
}
|
|
76
|
+
return kernCos(x, 0.0W)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// cos(Inf or NaN) is NaN
|
|
80
|
+
if (ix >= 0x7FF00000n) return x - x
|
|
81
|
+
|
|
82
|
+
// argument reduction needed
|
|
83
|
+
let (n, y0, y1) = rempio2(x, i, sign)
|
|
84
|
+
let n = fromInt32(n)
|
|
85
|
+
let y0 = fromFloat64(y0)
|
|
86
|
+
let y1 = fromFloat64(y1)
|
|
87
|
+
|
|
88
|
+
return match (n & 3n) {
|
|
89
|
+
0n => kernCos(y0, y1),
|
|
90
|
+
1n => kernSin(y0, y1, true) * -1.0W,
|
|
91
|
+
2n => kernCos(y0, y1) * -1.0W,
|
|
92
|
+
_ => kernSin(y0, y1, true),
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
@unsafe
|
|
97
|
+
provide let tan = (x: WasmF64) => { // see: musl/src/math/tan.c
|
|
98
|
+
use WasmI32.{ (&), (<=), (<), (>=), (==) }
|
|
99
|
+
use WasmI64.{ (>>>) }
|
|
100
|
+
use WasmF64.{ (-) }
|
|
101
|
+
let i = WasmI64.reinterpretF64(x)
|
|
102
|
+
// Get high word of x
|
|
103
|
+
let ix = WasmI32.wrapI64(i >>> 32N)
|
|
104
|
+
use WasmI32.{ (>>>) }
|
|
105
|
+
let sign = ix >>> 31n == 1n
|
|
106
|
+
let ix = ix & 0x7FFFFFFFn
|
|
107
|
+
|
|
108
|
+
// |x| ~< pi/4
|
|
109
|
+
if (ix <= 0x3FE921FBn) {
|
|
110
|
+
if (ix < 0x3E400000n) { // |x| < 2**-27
|
|
111
|
+
return x
|
|
112
|
+
}
|
|
113
|
+
return kernTan(x, 0.0W, true)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// tan(Inf or NaN) is NaN
|
|
117
|
+
if (ix >= 0x7FF00000n) return x - x
|
|
118
|
+
|
|
119
|
+
let (n, y0, y1) = rempio2(x, i, sign)
|
|
120
|
+
let n = fromInt32(n)
|
|
121
|
+
let y0 = fromFloat64(y0)
|
|
122
|
+
let y1 = fromFloat64(y1)
|
|
123
|
+
use WasmI32.{ (-), (&), (<<), (!=) }
|
|
124
|
+
return match (n & 3n) {
|
|
125
|
+
0n => kernTan(y0, y1, true),
|
|
126
|
+
1n => kernTan(y0, y1, false),
|
|
127
|
+
2n => kernTan(y0, y1, true),
|
|
128
|
+
_ => kernTan(y0, y1, false),
|
|
129
|
+
}
|
|
130
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Trig
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Raw trigonometric functions.
|
|
6
|
+
|
|
7
|
+
## Values
|
|
8
|
+
|
|
9
|
+
Functions and constants included in the Trig module.
|
|
10
|
+
|
|
11
|
+
### Trig.**sin**
|
|
12
|
+
|
|
13
|
+
```grain
|
|
14
|
+
sin: (x: WasmF64) => WasmF64
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Trig.**cos**
|
|
18
|
+
|
|
19
|
+
```grain
|
|
20
|
+
cos: (x: WasmF64) => WasmF64
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Trig.**tan**
|
|
24
|
+
|
|
25
|
+
```grain
|
|
26
|
+
tan: (x: WasmF64) => WasmF64
|
|
27
|
+
```
|
|
28
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Umuldi
|
|
2
|
+
|
|
3
|
+
from "runtime/unsafe/wasmi32" include WasmI32
|
|
4
|
+
from "runtime/unsafe/wasmi64" include WasmI64
|
|
5
|
+
from "runtime/unsafe/conv" include Conv
|
|
6
|
+
use Conv.{ toUint64 }
|
|
7
|
+
|
|
8
|
+
@unsafe
|
|
9
|
+
provide let umuldi = (u: WasmI64, v: WasmI64) => { // see: jdh8/metallic/blob/master/src/soft/integer/umulditi3.h
|
|
10
|
+
use WasmI64.{ (+), (*), (&), (>>>), (<<) }
|
|
11
|
+
let u1 = u & 0xFFFFFFFFN
|
|
12
|
+
let v1 = v & 0xFFFFFFFFN
|
|
13
|
+
|
|
14
|
+
let a1 = u >>> 32N
|
|
15
|
+
let b1 = v >>> 32N
|
|
16
|
+
|
|
17
|
+
let t = u1 * v1
|
|
18
|
+
let w0 = t & 0xFFFFFFFFN
|
|
19
|
+
let t = a1 * v1 + (t >>> 32N)
|
|
20
|
+
let w1 = t >>> 32N
|
|
21
|
+
let t = u1 * b1 + (t & 0xFFFFFFFFN)
|
|
22
|
+
|
|
23
|
+
let result = (t << 32N) + w0
|
|
24
|
+
let res128_hi = a1 * b1 + w1 + (t >>> 32N)
|
|
25
|
+
return (toUint64(result), toUint64(res128_hi))
|
|
26
|
+
}
|
package/runtime/numberUtils.gr
CHANGED
|
@@ -730,17 +730,17 @@ provide let decimalCount32 = value => {
|
|
|
730
730
|
if (WasmI32.ltU(value, 100n)) {
|
|
731
731
|
1n + (if (WasmI32.geU(value, 10n)) 1n else 0n)
|
|
732
732
|
} else {
|
|
733
|
-
3n
|
|
734
|
-
(if (WasmI32.geU(value, 10000n)) 1n else 0n)
|
|
735
|
-
(if (WasmI32.geU(value, 1000n)) 1n else 0n)
|
|
733
|
+
3n
|
|
734
|
+
+ (if (WasmI32.geU(value, 10000n)) 1n else 0n)
|
|
735
|
+
+ (if (WasmI32.geU(value, 1000n)) 1n else 0n)
|
|
736
736
|
}
|
|
737
737
|
} else {
|
|
738
738
|
if (WasmI32.ltU(value, 10000000n)) {
|
|
739
739
|
6n + (if (WasmI32.geU(value, 1000000n)) 1n else 0n)
|
|
740
740
|
} else {
|
|
741
|
-
8n
|
|
742
|
-
(if (WasmI32.geU(value, 1000000000n)) 1n else 0n)
|
|
743
|
-
(if (WasmI32.geU(value, 100000000n)) 1n else 0n)
|
|
741
|
+
8n
|
|
742
|
+
+ (if (WasmI32.geU(value, 1000000000n)) 1n else 0n)
|
|
743
|
+
+ (if (WasmI32.geU(value, 100000000n)) 1n else 0n)
|
|
744
744
|
}
|
|
745
745
|
}
|
|
746
746
|
}
|
|
@@ -751,21 +751,21 @@ provide let decimalCount32 = value => {
|
|
|
751
751
|
let decimalCount64High = value => {
|
|
752
752
|
if (WasmI64.ltU(value, 1000000000000000N)) {
|
|
753
753
|
if (WasmI64.ltU(value, 1000000000000N)) {
|
|
754
|
-
10n
|
|
755
|
-
(if (WasmI64.geU(value, 100000000000N)) 1n else 0n)
|
|
756
|
-
(if (WasmI64.geU(value, 10000000000N)) 1n else 0n)
|
|
754
|
+
10n
|
|
755
|
+
+ (if (WasmI64.geU(value, 100000000000N)) 1n else 0n)
|
|
756
|
+
+ (if (WasmI64.geU(value, 10000000000N)) 1n else 0n)
|
|
757
757
|
} else {
|
|
758
|
-
13n
|
|
759
|
-
(if (WasmI64.geU(value, 100000000000000N)) 1n else 0n)
|
|
760
|
-
(if (WasmI64.geU(value, 10000000000000N)) 1n else 0n)
|
|
758
|
+
13n
|
|
759
|
+
+ (if (WasmI64.geU(value, 100000000000000N)) 1n else 0n)
|
|
760
|
+
+ (if (WasmI64.geU(value, 10000000000000N)) 1n else 0n)
|
|
761
761
|
}
|
|
762
762
|
} else {
|
|
763
763
|
if (WasmI64.ltU(value, 100000000000000000N)) {
|
|
764
764
|
16n + (if (WasmI64.geU(value, 10000000000000000N)) 1n else 0n)
|
|
765
765
|
} else {
|
|
766
|
-
18n
|
|
767
|
-
(if (WasmI64.geU(value, 0x8AC7230489E80000N)) 1n else 0n)
|
|
768
|
-
(if (WasmI64.geU(value, 1000000000000000000N)) 1n else 0n)
|
|
766
|
+
18n
|
|
767
|
+
+ (if (WasmI64.geU(value, 0x8AC7230489E80000N)) 1n else 0n)
|
|
768
|
+
+ (if (WasmI64.geU(value, 1000000000000000000N)) 1n else 0n)
|
|
769
769
|
}
|
|
770
770
|
}
|
|
771
771
|
}
|
|
@@ -778,8 +778,8 @@ let ulog_base = (num, base) => {
|
|
|
778
778
|
WasmI32.divU(
|
|
779
779
|
63n - WasmI32.wrapI64(WasmI64.clz(num)),
|
|
780
780
|
31n - WasmI32.clz(base)
|
|
781
|
-
)
|
|
782
|
-
1n
|
|
781
|
+
)
|
|
782
|
+
+ 1n
|
|
783
783
|
} else {
|
|
784
784
|
let b64 = WasmI64.extendI32U(base)
|
|
785
785
|
let mut b = b64
|
|
@@ -1113,9 +1113,9 @@ provide let itoa64 = (value, radix) => {
|
|
|
1113
1113
|
WasmI32.toGrain(out): String
|
|
1114
1114
|
}
|
|
1115
1115
|
} else if (radix == 16n) {
|
|
1116
|
-
let decimals = ((63n - WasmI32.wrapI64(WasmI64.clz(value))) >>> 2n)
|
|
1117
|
-
1n
|
|
1118
|
-
sign
|
|
1116
|
+
let decimals = ((63n - WasmI32.wrapI64(WasmI64.clz(value))) >>> 2n)
|
|
1117
|
+
+ 1n
|
|
1118
|
+
+ sign
|
|
1119
1119
|
let out = allocateString(decimals)
|
|
1120
1120
|
utoa64_hex_core(out + 8n, value, decimals)
|
|
1121
1121
|
WasmI32.toGrain(out): String
|
|
@@ -1166,11 +1166,11 @@ let grisuRound = (buffer, len, delta, rest, ten_kappa, wp_w) => {
|
|
|
1166
1166
|
let mut rest = rest
|
|
1167
1167
|
use WasmI64.{ (+), (-) }
|
|
1168
1168
|
while (
|
|
1169
|
-
WasmI64.ltU(rest, wp_w)
|
|
1170
|
-
WasmI64.geU(delta - rest, ten_kappa)
|
|
1171
|
-
(
|
|
1172
|
-
WasmI64.ltU(rest + ten_kappa, wp_w)
|
|
1173
|
-
WasmI64.gtU(wp_w - rest, rest + ten_kappa - wp_w)
|
|
1169
|
+
WasmI64.ltU(rest, wp_w)
|
|
1170
|
+
&& WasmI64.geU(delta - rest, ten_kappa)
|
|
1171
|
+
&& (
|
|
1172
|
+
WasmI64.ltU(rest + ten_kappa, wp_w)
|
|
1173
|
+
|| WasmI64.gtU(wp_w - rest, rest + ten_kappa - wp_w)
|
|
1174
1174
|
)
|
|
1175
1175
|
) {
|
|
1176
1176
|
use WasmI32.{ (-) }
|
|
@@ -1273,8 +1273,8 @@ let genDigits = (buffer, w_frc, mp_frc, mp_exp, delta, sign) => {
|
|
|
1273
1273
|
tmp,
|
|
1274
1274
|
WasmI64.extendI32U(
|
|
1275
1275
|
WasmI32.load(get_POWERS10() + shlWasmI32(kappa, 2n), 0n)
|
|
1276
|
-
)
|
|
1277
|
-
WasmI64.extendI32U(one_exp),
|
|
1276
|
+
)
|
|
1277
|
+
<< WasmI64.extendI32U(one_exp),
|
|
1278
1278
|
wp_w_frc
|
|
1279
1279
|
)
|
|
1280
1280
|
done = true
|
|
@@ -1344,8 +1344,8 @@ let grisu2 = (value, buffer, sign) => {
|
|
|
1344
1344
|
let m_norm = 1n + (if (frc == 0x0010000000000000N) 1n else 0n)
|
|
1345
1345
|
|
|
1346
1346
|
let _frc_plus = frc_norm
|
|
1347
|
-
let _frc_minus = subWasmI64(frc << WasmI64.extendI32U(m_norm), 1N)
|
|
1348
|
-
WasmI64.extendI32U(exp - m_norm - exp_norm)
|
|
1347
|
+
let _frc_minus = subWasmI64(frc << WasmI64.extendI32U(m_norm), 1N)
|
|
1348
|
+
<< WasmI64.extendI32U(exp - m_norm - exp_norm)
|
|
1349
1349
|
let _exp = exp_norm
|
|
1350
1350
|
|
|
1351
1351
|
// get cached power
|
package/runtime/numberUtils.md
CHANGED
|
@@ -9,72 +9,72 @@ Functions and constants included in the NumberUtils module.
|
|
|
9
9
|
### NumberUtils.**_MAX_DOUBLE_LENGTH**
|
|
10
10
|
|
|
11
11
|
```grain
|
|
12
|
-
_MAX_DOUBLE_LENGTH
|
|
12
|
+
_MAX_DOUBLE_LENGTH: WasmI32
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
### NumberUtils.**get_POWERS10**
|
|
16
16
|
|
|
17
17
|
```grain
|
|
18
|
-
get_POWERS10
|
|
18
|
+
get_POWERS10: () => WasmI32
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
### NumberUtils.**get_HEX_DIGITS**
|
|
22
22
|
|
|
23
23
|
```grain
|
|
24
|
-
get_HEX_DIGITS
|
|
24
|
+
get_HEX_DIGITS: () => WasmI32
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
### NumberUtils.**decimalCount32**
|
|
28
28
|
|
|
29
29
|
```grain
|
|
30
|
-
decimalCount32
|
|
30
|
+
decimalCount32: (value: WasmI32) => WasmI32
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
### NumberUtils.**utoa32Buffered**
|
|
34
34
|
|
|
35
35
|
```grain
|
|
36
|
-
utoa32Buffered
|
|
36
|
+
utoa32Buffered: (buf: WasmI32, value: WasmI32, radix: WasmI32) => Void
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
### NumberUtils.**utoa32**
|
|
40
40
|
|
|
41
41
|
```grain
|
|
42
|
-
utoa32
|
|
42
|
+
utoa32: (value: WasmI32, radix: WasmI32) => String
|
|
43
43
|
```
|
|
44
44
|
|
|
45
45
|
### NumberUtils.**itoa32**
|
|
46
46
|
|
|
47
47
|
```grain
|
|
48
|
-
itoa32
|
|
48
|
+
itoa32: (value: WasmI32, radix: WasmI32) => String
|
|
49
49
|
```
|
|
50
50
|
|
|
51
51
|
### NumberUtils.**utoa64**
|
|
52
52
|
|
|
53
53
|
```grain
|
|
54
|
-
utoa64
|
|
54
|
+
utoa64: (value: WasmI64, radix: WasmI32) => String
|
|
55
55
|
```
|
|
56
56
|
|
|
57
57
|
### NumberUtils.**itoa64**
|
|
58
58
|
|
|
59
59
|
```grain
|
|
60
|
-
itoa64
|
|
60
|
+
itoa64: (value: WasmI64, radix: WasmI32) => String
|
|
61
61
|
```
|
|
62
62
|
|
|
63
63
|
### NumberUtils.**isFinite**
|
|
64
64
|
|
|
65
65
|
```grain
|
|
66
|
-
isFinite
|
|
66
|
+
isFinite: (value: WasmF64) => Bool
|
|
67
67
|
```
|
|
68
68
|
|
|
69
69
|
### NumberUtils.**isNaN**
|
|
70
70
|
|
|
71
71
|
```grain
|
|
72
|
-
isNaN
|
|
72
|
+
isNaN: (value: WasmF64) => Bool
|
|
73
73
|
```
|
|
74
74
|
|
|
75
75
|
### NumberUtils.**dtoa**
|
|
76
76
|
|
|
77
77
|
```grain
|
|
78
|
-
dtoa
|
|
78
|
+
dtoa: (value: WasmF64) => String
|
|
79
79
|
```
|
|
80
80
|
|