@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/numberUtils.gr
CHANGED
|
@@ -1,32 +1,35 @@
|
|
|
1
|
-
|
|
1
|
+
@noPervasives
|
|
2
|
+
module NumberUtils
|
|
2
3
|
|
|
3
4
|
/*
|
|
4
5
|
* This file was inspired by AssemblyScript's std/assembly/util/number.ts
|
|
5
6
|
*/
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
from "runtime/unsafe/memory" include Memory
|
|
9
|
+
from "runtime/unsafe/wasmi32" include WasmI32
|
|
10
|
+
use WasmI32.{
|
|
11
|
+
(==),
|
|
12
|
+
(!=),
|
|
13
|
+
(+),
|
|
14
|
+
(-),
|
|
15
|
+
(<<),
|
|
16
|
+
(&),
|
|
17
|
+
(|),
|
|
16
18
|
// no signed imports, as care should be taken to use signed or unsigned operators
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
}
|
|
20
|
+
from "runtime/unsafe/wasmi64" include WasmI64
|
|
21
|
+
from "runtime/unsafe/wasmf64" include WasmF64
|
|
22
|
+
from "runtime/exception" include Exception
|
|
23
|
+
from "runtime/dataStructures" include DataStructures
|
|
24
|
+
use DataStructures.{ allocateString }
|
|
22
25
|
|
|
23
|
-
primitive (!)
|
|
24
|
-
primitive (&&)
|
|
25
|
-
primitive (||)
|
|
26
|
-
primitive throw
|
|
26
|
+
primitive (!) = "@not"
|
|
27
|
+
primitive (&&) = "@and"
|
|
28
|
+
primitive (||) = "@or"
|
|
29
|
+
primitive throw = "@throw"
|
|
27
30
|
|
|
28
31
|
@unsafe
|
|
29
|
-
|
|
32
|
+
provide let _MAX_DOUBLE_LENGTH = 28n
|
|
30
33
|
|
|
31
34
|
@unsafe
|
|
32
35
|
let _CHAR_CODE_0 = 0x30n
|
|
@@ -46,7 +49,7 @@ let _I32_MAX = 0xffffffffN
|
|
|
46
49
|
let mut _POWERS10 = -1n
|
|
47
50
|
|
|
48
51
|
@unsafe
|
|
49
|
-
|
|
52
|
+
provide let get_POWERS10 = () => {
|
|
50
53
|
if (_POWERS10 == -1n) {
|
|
51
54
|
_POWERS10 = Memory.malloc(40n)
|
|
52
55
|
WasmI32.store(_POWERS10, 1n, 0n)
|
|
@@ -192,7 +195,7 @@ let get_DIGITS = () => {
|
|
|
192
195
|
let mut _HEX_DIGITS = -1n
|
|
193
196
|
|
|
194
197
|
@unsafe
|
|
195
|
-
|
|
198
|
+
provide let get_HEX_DIGITS = () => {
|
|
196
199
|
if (_HEX_DIGITS == -1n) {
|
|
197
200
|
_HEX_DIGITS = Memory.malloc(512n)
|
|
198
201
|
WasmI32.store16(_HEX_DIGITS, 0x3030n, 0n) // 00
|
|
@@ -722,7 +725,7 @@ let isPowerOf2 = value => {
|
|
|
722
725
|
// Count number of decimals for u32 values
|
|
723
726
|
// In our case input value always non-zero so we can simplify some parts
|
|
724
727
|
@unsafe
|
|
725
|
-
|
|
728
|
+
provide let decimalCount32 = value => {
|
|
726
729
|
if (WasmI32.ltU(value, 100000n)) {
|
|
727
730
|
if (WasmI32.ltU(value, 100n)) {
|
|
728
731
|
1n + (if (WasmI32.geU(value, 10n)) 1n else 0n)
|
|
@@ -769,6 +772,8 @@ let decimalCount64High = value => {
|
|
|
769
772
|
|
|
770
773
|
@unsafe
|
|
771
774
|
let ulog_base = (num, base) => {
|
|
775
|
+
use WasmI32.{ (<<) }
|
|
776
|
+
use WasmI64.{ (*) }
|
|
772
777
|
if (isPowerOf2(base)) {
|
|
773
778
|
WasmI32.divU(
|
|
774
779
|
63n - WasmI32.wrapI64(WasmI64.clz(num)),
|
|
@@ -782,8 +787,8 @@ let ulog_base = (num, base) => {
|
|
|
782
787
|
let mut num = num
|
|
783
788
|
while (WasmI64.geU(num, b)) {
|
|
784
789
|
num = WasmI64.divU(num, b)
|
|
785
|
-
b
|
|
786
|
-
e =
|
|
790
|
+
b *= b
|
|
791
|
+
e = e << 1n
|
|
787
792
|
}
|
|
788
793
|
while (WasmI64.geU(num, 1N)) {
|
|
789
794
|
num = WasmI64.divU(num, b64)
|
|
@@ -839,7 +844,9 @@ let utoa64_dec_lut = (buffer, num, offset) => {
|
|
|
839
844
|
let mut offset = offset
|
|
840
845
|
while (WasmI64.geU(num, 100000000N)) {
|
|
841
846
|
let t = WasmI64.divU(num, 100000000N)
|
|
842
|
-
|
|
847
|
+
use WasmI64.{ (-), (*) }
|
|
848
|
+
let r = WasmI32.wrapI64(num - t * 100000000N)
|
|
849
|
+
use WasmI32.{ (-) }
|
|
843
850
|
num = t
|
|
844
851
|
|
|
845
852
|
let b = WasmI32.divU(r, 10000n)
|
|
@@ -868,6 +875,7 @@ let utoa64_dec_lut = (buffer, num, offset) => {
|
|
|
868
875
|
|
|
869
876
|
@unsafe
|
|
870
877
|
let utoa_hex_lut = (buffer, num, offset) => {
|
|
878
|
+
use WasmI64.{ (>>>) }
|
|
871
879
|
let lut = get_HEX_DIGITS()
|
|
872
880
|
let mut num = num
|
|
873
881
|
let mut offset = offset
|
|
@@ -878,9 +886,9 @@ let utoa_hex_lut = (buffer, num, offset) => {
|
|
|
878
886
|
WasmI32.load16U(lut + ((WasmI32.wrapI64(num) & 0xFFn) << 1n), 0n),
|
|
879
887
|
0n
|
|
880
888
|
)
|
|
881
|
-
num =
|
|
889
|
+
num = num >>> 8N
|
|
882
890
|
}
|
|
883
|
-
if (
|
|
891
|
+
if ((offset & 1n) != 0n) {
|
|
884
892
|
WasmI32.store8(
|
|
885
893
|
buffer,
|
|
886
894
|
WasmI32.load8U(lut + (WasmI32.wrapI64(num) << 5n), 0n),
|
|
@@ -911,33 +919,34 @@ let utoa64_hex_core = (buffer, num, offset) => {
|
|
|
911
919
|
|
|
912
920
|
@unsafe
|
|
913
921
|
let utoa64_any_core = (buffer, num, offset, radix) => {
|
|
922
|
+
use WasmI64.{ (>>>) }
|
|
914
923
|
let lut = get_ANY_DIGITS()
|
|
915
924
|
let base = WasmI64.extendI32U(radix)
|
|
916
925
|
let mut num = num
|
|
917
926
|
let mut offset = offset
|
|
918
927
|
if ((radix & radix - 1n) == 0n) { // for radix which pow of two
|
|
919
928
|
let shift = WasmI64.extendI32U(WasmI32.ctz(radix) & 7n)
|
|
920
|
-
|
|
929
|
+
use WasmI64.{ (-), (&) }
|
|
930
|
+
let mask = base - 1N
|
|
921
931
|
for (;;) {
|
|
932
|
+
use WasmI32.{ (-) }
|
|
922
933
|
offset -= 1n
|
|
923
934
|
WasmI32.store8(
|
|
924
935
|
buffer + offset,
|
|
925
|
-
WasmI32.load8U(lut + WasmI32.wrapI64(
|
|
936
|
+
WasmI32.load8U(lut + WasmI32.wrapI64(num & mask), 0n),
|
|
926
937
|
0n
|
|
927
938
|
)
|
|
928
|
-
num =
|
|
939
|
+
num = num >>> shift
|
|
929
940
|
if (WasmI64.eqz(num)) break
|
|
930
941
|
}
|
|
931
942
|
} else {
|
|
932
943
|
for (;;) {
|
|
933
944
|
offset -= 1n
|
|
945
|
+
use WasmI64.{ (-), (*) }
|
|
934
946
|
let q = WasmI64.divU(num, base)
|
|
935
947
|
WasmI32.store8(
|
|
936
948
|
buffer + offset,
|
|
937
|
-
WasmI32.load8U(
|
|
938
|
-
lut + WasmI32.wrapI64(WasmI64.sub(num, WasmI64.mul(q, base))),
|
|
939
|
-
0n
|
|
940
|
-
),
|
|
949
|
+
WasmI32.load8U(lut + WasmI32.wrapI64(num - q * base), 0n),
|
|
941
950
|
0n
|
|
942
951
|
)
|
|
943
952
|
num = q
|
|
@@ -947,10 +956,11 @@ let utoa64_any_core = (buffer, num, offset, radix) => {
|
|
|
947
956
|
}
|
|
948
957
|
|
|
949
958
|
@unsafe
|
|
950
|
-
|
|
951
|
-
|
|
959
|
+
provide let utoa32Buffered = (buf, value, radix) => {
|
|
960
|
+
use WasmI32.{ (>>>), (<), (>) }
|
|
961
|
+
if (radix < 2n || radix > 36n) {
|
|
952
962
|
throw Exception.InvalidArgument(
|
|
953
|
-
"toString() radix argument must be between 2 and 36"
|
|
963
|
+
"toString() radix argument must be between 2 and 36",
|
|
954
964
|
)
|
|
955
965
|
}
|
|
956
966
|
if (WasmI32.eqz(value)) {
|
|
@@ -959,7 +969,7 @@ export let utoa32Buffered = (buf, value, radix) => {
|
|
|
959
969
|
let decimals = decimalCount32(value)
|
|
960
970
|
utoa32_dec_core(buf, value, decimals)
|
|
961
971
|
} else if (radix == 16n) {
|
|
962
|
-
let decimals =
|
|
972
|
+
let decimals = ((31n - WasmI32.clz(value)) >>> 2n) + 1n
|
|
963
973
|
utoa32_hex_core(buf, value, decimals)
|
|
964
974
|
} else {
|
|
965
975
|
let decimals = ulog_base(WasmI64.extendI32U(value), radix)
|
|
@@ -969,10 +979,11 @@ export let utoa32Buffered = (buf, value, radix) => {
|
|
|
969
979
|
}
|
|
970
980
|
|
|
971
981
|
@unsafe
|
|
972
|
-
|
|
973
|
-
|
|
982
|
+
provide let utoa32 = (value, radix) => {
|
|
983
|
+
use WasmI32.{ (>>>), (<), (>) }
|
|
984
|
+
if (radix < 2n || radix > 36n) {
|
|
974
985
|
throw Exception.InvalidArgument(
|
|
975
|
-
"toString() radix argument must be between 2 and 36"
|
|
986
|
+
"toString() radix argument must be between 2 and 36",
|
|
976
987
|
)
|
|
977
988
|
}
|
|
978
989
|
if (WasmI32.eqz(value)) {
|
|
@@ -980,32 +991,34 @@ export let utoa32 = (value, radix) => {
|
|
|
980
991
|
} else if (radix == 10n) {
|
|
981
992
|
let decimals = decimalCount32(value)
|
|
982
993
|
let out = allocateString(decimals)
|
|
983
|
-
utoa32_dec_core(out, value, decimals)
|
|
994
|
+
utoa32_dec_core(out + 8n, value, decimals)
|
|
984
995
|
WasmI32.toGrain(out): String
|
|
985
996
|
} else if (radix == 16n) {
|
|
986
|
-
let decimals =
|
|
997
|
+
let decimals = ((31n - WasmI32.clz(value)) >>> 2n) + 1n
|
|
987
998
|
let out = allocateString(decimals)
|
|
988
|
-
utoa32_hex_core(out, value, decimals)
|
|
999
|
+
utoa32_hex_core(out + 8n, value, decimals)
|
|
989
1000
|
WasmI32.toGrain(out): String
|
|
990
1001
|
} else {
|
|
991
|
-
let
|
|
1002
|
+
let val64 = WasmI64.extendI32U(value)
|
|
1003
|
+
let decimals = ulog_base(val64, radix)
|
|
992
1004
|
let out = allocateString(decimals)
|
|
993
|
-
utoa64_any_core(out,
|
|
1005
|
+
utoa64_any_core(out + 8n, val64, decimals, radix)
|
|
994
1006
|
WasmI32.toGrain(out): String
|
|
995
1007
|
}
|
|
996
1008
|
}
|
|
997
1009
|
|
|
998
1010
|
@unsafe
|
|
999
|
-
|
|
1011
|
+
provide let itoa32 = (value, radix) => {
|
|
1012
|
+
use WasmI32.{ (>>>), (<), (>) }
|
|
1000
1013
|
let mut value = value
|
|
1001
|
-
if (
|
|
1014
|
+
if (radix < 2n || radix > 36n) {
|
|
1002
1015
|
throw Exception.InvalidArgument(
|
|
1003
|
-
"toString() radix argument must be between 2 and 36"
|
|
1016
|
+
"toString() radix argument must be between 2 and 36",
|
|
1004
1017
|
)
|
|
1005
1018
|
}
|
|
1006
|
-
let sign =
|
|
1019
|
+
let sign = value >>> 31n
|
|
1007
1020
|
|
|
1008
|
-
if (
|
|
1021
|
+
if (sign != 0n) value = 0n - value
|
|
1009
1022
|
|
|
1010
1023
|
let out = if (WasmI32.eqz(value)) {
|
|
1011
1024
|
"0"
|
|
@@ -1015,7 +1028,7 @@ export let itoa32 = (value, radix) => {
|
|
|
1015
1028
|
utoa32_dec_core(out + 8n, value, decimals)
|
|
1016
1029
|
WasmI32.toGrain(out): String
|
|
1017
1030
|
} else if (radix == 16n) {
|
|
1018
|
-
let decimals =
|
|
1031
|
+
let decimals = ((31n - WasmI32.clz(value)) >>> 2n) + 1n + sign
|
|
1019
1032
|
let out = allocateString(decimals)
|
|
1020
1033
|
utoa32_hex_core(out + 8n, value, decimals)
|
|
1021
1034
|
WasmI32.toGrain(out): String
|
|
@@ -1026,16 +1039,16 @@ export let itoa32 = (value, radix) => {
|
|
|
1026
1039
|
utoa64_any_core(out + 8n, val64, decimals, radix)
|
|
1027
1040
|
WasmI32.toGrain(out): String
|
|
1028
1041
|
}
|
|
1029
|
-
if (WasmI32.
|
|
1030
|
-
WasmI32.store8(WasmI32.fromGrain(out), _CHAR_CODE_MINUS, 8n)
|
|
1042
|
+
if (sign != 0n) WasmI32.store8(WasmI32.fromGrain(out), _CHAR_CODE_MINUS, 8n)
|
|
1031
1043
|
out
|
|
1032
1044
|
}
|
|
1033
1045
|
|
|
1034
1046
|
@unsafe
|
|
1035
|
-
|
|
1036
|
-
|
|
1047
|
+
provide let utoa64 = (value, radix) => {
|
|
1048
|
+
use WasmI32.{ (>>>), (<), (>) }
|
|
1049
|
+
if (radix < 2n || radix > 36n) {
|
|
1037
1050
|
throw Exception.InvalidArgument(
|
|
1038
|
-
"toString() radix argument must be between 2 and 36"
|
|
1051
|
+
"toString() radix argument must be between 2 and 36",
|
|
1039
1052
|
)
|
|
1040
1053
|
}
|
|
1041
1054
|
if (WasmI64.eqz(value)) {
|
|
@@ -1054,8 +1067,7 @@ export let utoa64 = (value, radix) => {
|
|
|
1054
1067
|
WasmI32.toGrain(out): String
|
|
1055
1068
|
}
|
|
1056
1069
|
} else if (radix == 16n) {
|
|
1057
|
-
let decimals =
|
|
1058
|
-
1n
|
|
1070
|
+
let decimals = ((63n - WasmI32.wrapI64(WasmI64.clz(value))) >>> 2n) + 1n
|
|
1059
1071
|
let out = allocateString(decimals)
|
|
1060
1072
|
utoa64_hex_core(out + 8n, value, decimals)
|
|
1061
1073
|
WasmI32.toGrain(out): String
|
|
@@ -1068,18 +1080,23 @@ export let utoa64 = (value, radix) => {
|
|
|
1068
1080
|
}
|
|
1069
1081
|
|
|
1070
1082
|
@unsafe
|
|
1071
|
-
|
|
1072
|
-
|
|
1083
|
+
provide let itoa64 = (value, radix) => {
|
|
1084
|
+
use WasmI32.{ (<), (>) }
|
|
1085
|
+
use WasmI64.{ (>>>) }
|
|
1086
|
+
if (radix < 2n || radix > 36n) {
|
|
1073
1087
|
throw Exception.InvalidArgument(
|
|
1074
|
-
"toString() radix argument must be between 2 and 36"
|
|
1088
|
+
"toString() radix argument must be between 2 and 36",
|
|
1075
1089
|
)
|
|
1076
1090
|
}
|
|
1077
1091
|
|
|
1078
1092
|
let mut value = value
|
|
1079
1093
|
|
|
1080
|
-
let sign = WasmI32.wrapI64(
|
|
1081
|
-
if (sign != 0n)
|
|
1082
|
-
|
|
1094
|
+
let sign = WasmI32.wrapI64(value >>> 63N)
|
|
1095
|
+
if (sign != 0n) {
|
|
1096
|
+
use WasmI64.{ (-) }
|
|
1097
|
+
value = 0N - value
|
|
1098
|
+
}
|
|
1099
|
+
use WasmI32.{ (>>>) }
|
|
1083
1100
|
let out = if (WasmI64.eqz(value)) {
|
|
1084
1101
|
"0"
|
|
1085
1102
|
} else if (radix == 10n) {
|
|
@@ -1096,7 +1113,7 @@ export let itoa64 = (value, radix) => {
|
|
|
1096
1113
|
WasmI32.toGrain(out): String
|
|
1097
1114
|
}
|
|
1098
1115
|
} else if (radix == 16n) {
|
|
1099
|
-
let decimals =
|
|
1116
|
+
let decimals = ((63n - WasmI32.wrapI64(WasmI64.clz(value))) >>> 2n) +
|
|
1100
1117
|
1n +
|
|
1101
1118
|
sign
|
|
1102
1119
|
let out = allocateString(decimals)
|
|
@@ -1117,22 +1134,24 @@ let mut _K = 0n
|
|
|
1117
1134
|
|
|
1118
1135
|
@unsafe
|
|
1119
1136
|
let umul64f = (u, v) => {
|
|
1120
|
-
|
|
1121
|
-
|
|
1137
|
+
use WasmI64.{ (>>>) }
|
|
1138
|
+
use WasmI64.{ (+), (*), (&) }
|
|
1139
|
+
let u0 = u & 0xFFFFFFFFN
|
|
1140
|
+
let v0 = v & 0xFFFFFFFFN
|
|
1122
1141
|
|
|
1123
|
-
let u1 =
|
|
1124
|
-
let v1 =
|
|
1142
|
+
let u1 = u >>> 32N
|
|
1143
|
+
let v1 = v >>> 32N
|
|
1125
1144
|
|
|
1126
|
-
let l =
|
|
1127
|
-
let mut t =
|
|
1128
|
-
let mut w =
|
|
1145
|
+
let l = u0 * v0
|
|
1146
|
+
let mut t = u1 * v0 + (l >>> 32N)
|
|
1147
|
+
let mut w = u0 * v1 + (t & 0xFFFFFFFFN)
|
|
1129
1148
|
|
|
1130
|
-
w
|
|
1149
|
+
w += 0x7FFFFFFFN // rounding
|
|
1131
1150
|
|
|
1132
|
-
t =
|
|
1133
|
-
w =
|
|
1151
|
+
t = t >>> 32N
|
|
1152
|
+
w = w >>> 32N
|
|
1134
1153
|
|
|
1135
|
-
|
|
1154
|
+
u1 * v1 + t + w
|
|
1136
1155
|
}
|
|
1137
1156
|
|
|
1138
1157
|
@unsafe
|
|
@@ -1145,41 +1164,48 @@ let grisuRound = (buffer, len, delta, rest, ten_kappa, wp_w) => {
|
|
|
1145
1164
|
let mut lastp = buffer + len - 1n
|
|
1146
1165
|
let mut digit = WasmI32.load8U(lastp, 0n)
|
|
1147
1166
|
let mut rest = rest
|
|
1167
|
+
use WasmI64.{ (+), (-) }
|
|
1148
1168
|
while (
|
|
1149
1169
|
WasmI64.ltU(rest, wp_w) &&
|
|
1150
|
-
WasmI64.geU(
|
|
1151
|
-
(
|
|
1152
|
-
WasmI64.
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
))
|
|
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
|
+
)
|
|
1156
1175
|
) {
|
|
1176
|
+
use WasmI32.{ (-) }
|
|
1157
1177
|
digit -= 1n
|
|
1158
|
-
rest
|
|
1178
|
+
rest += ten_kappa
|
|
1159
1179
|
}
|
|
1160
1180
|
WasmI32.store8(lastp, digit, 0n)
|
|
1161
1181
|
}
|
|
1162
1182
|
|
|
1163
1183
|
@unsafe
|
|
1164
1184
|
let genDigits = (buffer, w_frc, mp_frc, mp_exp, delta, sign) => {
|
|
1185
|
+
use WasmI32.{ (>) }
|
|
1186
|
+
use WasmI64.{
|
|
1187
|
+
(+) as addWasmI64,
|
|
1188
|
+
(-) as subWasmI64,
|
|
1189
|
+
(&) as andWasmI64,
|
|
1190
|
+
(<<),
|
|
1191
|
+
(>>>),
|
|
1192
|
+
}
|
|
1165
1193
|
let mut delta = delta
|
|
1166
1194
|
let one_exp = 0n - mp_exp
|
|
1167
|
-
let one_frc =
|
|
1168
|
-
let mask =
|
|
1195
|
+
let one_frc = 1N << WasmI64.extendI32U(one_exp)
|
|
1196
|
+
let mask = subWasmI64(one_frc, 1N)
|
|
1169
1197
|
|
|
1170
|
-
let mut wp_w_frc =
|
|
1198
|
+
let mut wp_w_frc = subWasmI64(mp_frc, w_frc)
|
|
1171
1199
|
|
|
1172
|
-
let mut p1 = WasmI32.wrapI64(
|
|
1173
|
-
|
|
1174
|
-
)
|
|
1175
|
-
let mut p2 = WasmI64.and(mp_frc, mask)
|
|
1200
|
+
let mut p1 = WasmI32.wrapI64(mp_frc >>> WasmI64.extendI32U(one_exp))
|
|
1201
|
+
let mut p2 = andWasmI64(mp_frc, mask)
|
|
1176
1202
|
|
|
1177
1203
|
let mut kappa = decimalCount32(p1)
|
|
1178
1204
|
let mut len = sign
|
|
1179
1205
|
|
|
1180
1206
|
let mut done = false
|
|
1181
1207
|
|
|
1182
|
-
while (
|
|
1208
|
+
while (kappa > 0n) {
|
|
1183
1209
|
let mut d = 0n
|
|
1184
1210
|
match (kappa) {
|
|
1185
1211
|
10n => {
|
|
@@ -1227,70 +1253,69 @@ let genDigits = (buffer, w_frc, mp_frc, mp_exp, delta, sign) => {
|
|
|
1227
1253
|
},
|
|
1228
1254
|
}
|
|
1229
1255
|
|
|
1230
|
-
if (
|
|
1256
|
+
if ((d | len) != 0n) {
|
|
1231
1257
|
WasmI32.store8(buffer + len, _CHAR_CODE_0 + (d & 0xffn), 0n)
|
|
1232
1258
|
len += 1n
|
|
1233
1259
|
}
|
|
1234
1260
|
|
|
1235
1261
|
kappa -= 1n
|
|
1236
|
-
let tmp =
|
|
1237
|
-
WasmI64.
|
|
1262
|
+
let tmp = addWasmI64(
|
|
1263
|
+
WasmI64.extendI32U(p1) << WasmI64.extendI32U(one_exp),
|
|
1238
1264
|
p2
|
|
1239
1265
|
)
|
|
1240
1266
|
if (WasmI64.leU(tmp, delta)) {
|
|
1267
|
+
use WasmI32.{ (<<) as shlWasmI32 }
|
|
1241
1268
|
_K += kappa
|
|
1242
1269
|
grisuRound(
|
|
1243
1270
|
buffer,
|
|
1244
1271
|
len,
|
|
1245
1272
|
delta,
|
|
1246
1273
|
tmp,
|
|
1247
|
-
WasmI64.
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1274
|
+
WasmI64.extendI32U(
|
|
1275
|
+
WasmI32.load(get_POWERS10() + shlWasmI32(kappa, 2n), 0n)
|
|
1276
|
+
) <<
|
|
1277
|
+
WasmI64.extendI32U(one_exp),
|
|
1251
1278
|
wp_w_frc
|
|
1252
1279
|
)
|
|
1253
1280
|
done = true
|
|
1254
1281
|
break
|
|
1255
1282
|
}
|
|
1256
1283
|
}
|
|
1284
|
+
if (!done) while (true) {
|
|
1285
|
+
use WasmI64.{ (!=), (*), (|), (>>>) }
|
|
1286
|
+
p2 *= 10N
|
|
1287
|
+
delta *= 10N
|
|
1257
1288
|
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
}
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
wp_w_frc,
|
|
1279
|
-
WasmI64.extendI32U(
|
|
1280
|
-
WasmI32.load(get_POWERS10() + ((0n - kappa) << 2n), 0n)
|
|
1281
|
-
)
|
|
1282
|
-
)
|
|
1283
|
-
grisuRound(buffer, len, delta, p2, one_frc, wp_w_frc)
|
|
1284
|
-
break
|
|
1285
|
-
}
|
|
1289
|
+
let d = p2 >>> WasmI64.extendI32U(one_exp)
|
|
1290
|
+
if ((d | WasmI64.extendI32U(len)) != 0N) {
|
|
1291
|
+
WasmI32.store8(
|
|
1292
|
+
buffer + len,
|
|
1293
|
+
_CHAR_CODE_0 + (WasmI32.wrapI64(d) & 0xffn),
|
|
1294
|
+
0n
|
|
1295
|
+
)
|
|
1296
|
+
len += 1n
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
p2 = andWasmI64(p2, mask)
|
|
1300
|
+
kappa -= 1n
|
|
1301
|
+
if (WasmI64.ltU(p2, delta)) {
|
|
1302
|
+
use WasmI32.{ (<<) }
|
|
1303
|
+
_K += kappa
|
|
1304
|
+
wp_w_frc *= WasmI64.extendI32U(
|
|
1305
|
+
WasmI32.load(get_POWERS10() + ((0n - kappa) << 2n), 0n)
|
|
1306
|
+
)
|
|
1307
|
+
grisuRound(buffer, len, delta, p2, one_frc, wp_w_frc)
|
|
1308
|
+
break
|
|
1286
1309
|
}
|
|
1310
|
+
}
|
|
1287
1311
|
len
|
|
1288
1312
|
}
|
|
1289
1313
|
|
|
1290
1314
|
@unsafe
|
|
1291
1315
|
let genExponent = (buffer, k) => {
|
|
1316
|
+
use WasmI32.{ (<) }
|
|
1292
1317
|
let mut k = k
|
|
1293
|
-
let sign =
|
|
1318
|
+
let sign = k < 0n
|
|
1294
1319
|
if (sign) k = 0n - k
|
|
1295
1320
|
let decimals = decimalCount32(k) + 1n
|
|
1296
1321
|
utoa32_dec_core(buffer, k, decimals)
|
|
@@ -1300,54 +1325,45 @@ let genExponent = (buffer, k) => {
|
|
|
1300
1325
|
|
|
1301
1326
|
@unsafe
|
|
1302
1327
|
let grisu2 = (value, buffer, sign) => {
|
|
1328
|
+
use WasmI32.{ (>>) }
|
|
1329
|
+
use WasmI64.{ (==), (+) as addWasmI64, (-) as subWasmI64, (&), (<<), (>>>) }
|
|
1303
1330
|
// frexp routine
|
|
1304
1331
|
let uv = WasmI64.reinterpretF64(value)
|
|
1305
|
-
let mut exp = WasmI32.wrapI64(
|
|
1306
|
-
|
|
1307
|
-
)
|
|
1308
|
-
let sid = WasmI64.and(uv, 0x000FFFFFFFFFFFFFN)
|
|
1309
|
-
let mut frc = WasmI64.add(
|
|
1310
|
-
WasmI64.shl(if (WasmI32.eqz(exp)) 0N else 1N, 52N),
|
|
1311
|
-
sid
|
|
1312
|
-
)
|
|
1332
|
+
let mut exp = WasmI32.wrapI64((uv & 0x7FF0000000000000N) >>> 52N)
|
|
1333
|
+
let sid = uv & 0x000FFFFFFFFFFFFFN
|
|
1334
|
+
let mut frc = addWasmI64((if (WasmI32.eqz(exp)) 0N else 1N) << 52N, sid)
|
|
1313
1335
|
exp = (if (WasmI32.eqz(exp)) 1n else exp) - (0x3FFn + 52n)
|
|
1314
1336
|
|
|
1315
1337
|
// normalize boundaries
|
|
1316
|
-
let mut frc_norm =
|
|
1338
|
+
let mut frc_norm = addWasmI64(frc << 1N, 1N)
|
|
1317
1339
|
let mut exp_norm = exp - 1n
|
|
1318
1340
|
let off_norm = WasmI64.clz(frc_norm)
|
|
1319
|
-
frc_norm =
|
|
1341
|
+
frc_norm = frc_norm << off_norm
|
|
1320
1342
|
exp_norm -= WasmI32.wrapI64(off_norm)
|
|
1321
1343
|
|
|
1322
|
-
let m_norm = 1n + (if (
|
|
1344
|
+
let m_norm = 1n + (if (frc == 0x0010000000000000N) 1n else 0n)
|
|
1323
1345
|
|
|
1324
1346
|
let _frc_plus = frc_norm
|
|
1325
|
-
let _frc_minus = WasmI64.
|
|
1326
|
-
WasmI64.sub(WasmI64.shl(frc, WasmI64.extendI32U(m_norm)), 1N),
|
|
1347
|
+
let _frc_minus = subWasmI64(frc << WasmI64.extendI32U(m_norm), 1N) <<
|
|
1327
1348
|
WasmI64.extendI32U(exp - m_norm - exp_norm)
|
|
1328
|
-
)
|
|
1329
1349
|
let _exp = exp_norm
|
|
1330
1350
|
|
|
1331
1351
|
// get cached power
|
|
1332
|
-
let c = WasmF64.reinterpretI64(
|
|
1333
|
-
|
|
1334
|
-
) //
|
|
1335
|
-
let dk = WasmF64.add(
|
|
1336
|
-
WasmF64.mul(WasmF64.convertI32S(-61n - _exp), c),
|
|
1337
|
-
347.0W
|
|
1338
|
-
) // dk must be positive, so can do ceiling in positive
|
|
1352
|
+
let c = WasmF64.reinterpretI64(0x3FD34413509F79FEN) // 1 / lg(10) = 0.30102999566398114
|
|
1353
|
+
use WasmF64.{ (+) as addWasmF64, (*) as mulWasmF64, (!=) as neWasmF64 }
|
|
1354
|
+
let dk = addWasmF64(mulWasmF64(WasmF64.convertI32S(-61n - _exp), c), 347.0W) // dk must be positive, so can do ceiling in positive
|
|
1339
1355
|
let mut k = WasmI32.truncF64S(dk)
|
|
1340
|
-
k += if (
|
|
1341
|
-
else 0n // conversion with ceil
|
|
1356
|
+
k += if (neWasmF64(WasmF64.convertI32S(k), dk)) 1n else 0n // conversion with ceil
|
|
1342
1357
|
|
|
1343
|
-
let index =
|
|
1358
|
+
let index = (k >> 3n) + 1n
|
|
1359
|
+
use WasmI32.{ (<<) }
|
|
1344
1360
|
_K = 348n - (index << 3n) // decimal exponent doesn't need lookup table
|
|
1345
1361
|
let _frc_pow = WasmI64.load(get_FRC_POWERS() + (index << 3n), 0n)
|
|
1346
1362
|
let _exp_pow = WasmI32.load16S(get_EXP_POWERS() + (index << 1n), 0n)
|
|
1347
|
-
|
|
1363
|
+
use WasmI64.{ (<<) }
|
|
1348
1364
|
// normalize
|
|
1349
1365
|
let off = WasmI32.wrapI64(WasmI64.clz(frc))
|
|
1350
|
-
frc =
|
|
1366
|
+
frc = frc << WasmI64.extendI32U(off)
|
|
1351
1367
|
exp -= off
|
|
1352
1368
|
|
|
1353
1369
|
let frc_pow = _frc_pow
|
|
@@ -1355,41 +1371,42 @@ let grisu2 = (value, buffer, sign) => {
|
|
|
1355
1371
|
|
|
1356
1372
|
let w_frc = umul64f(frc, frc_pow)
|
|
1357
1373
|
|
|
1358
|
-
let wp_frc =
|
|
1374
|
+
let wp_frc = subWasmI64(umul64f(_frc_plus, frc_pow), 1N)
|
|
1359
1375
|
let wp_exp = umul64e(_exp, exp_pow)
|
|
1360
1376
|
|
|
1361
|
-
let wm_frc =
|
|
1362
|
-
let delta =
|
|
1377
|
+
let wm_frc = addWasmI64(umul64f(_frc_minus, frc_pow), 1N)
|
|
1378
|
+
let delta = subWasmI64(wp_frc, wm_frc)
|
|
1363
1379
|
|
|
1364
1380
|
genDigits(buffer, w_frc, wp_frc, wp_exp, delta, sign)
|
|
1365
1381
|
}
|
|
1366
1382
|
|
|
1367
1383
|
@unsafe
|
|
1368
1384
|
let prettify = (buffer, length, k) => {
|
|
1385
|
+
use WasmI32.{ (<), (<=), (>) }
|
|
1369
1386
|
let mut length = length
|
|
1370
1387
|
let kk = length + k
|
|
1371
1388
|
if (WasmI32.eqz(k)) {
|
|
1372
1389
|
WasmI32.store16(buffer + length, _CHAR_CODE_DOT | _CHAR_CODE_0 << 8n, 0n)
|
|
1373
1390
|
length + 2n
|
|
1374
|
-
} else if (
|
|
1391
|
+
} else if (length <= kk && kk <= 21n) {
|
|
1375
1392
|
// 1234e7 -> 12340000000
|
|
1376
|
-
for (let mut i = length;
|
|
1393
|
+
for (let mut i = length; i < kk; i += 1n) {
|
|
1377
1394
|
WasmI32.store8(buffer + i, _CHAR_CODE_0, 0n)
|
|
1378
1395
|
}
|
|
1379
1396
|
WasmI32.store16(buffer + kk, _CHAR_CODE_DOT | _CHAR_CODE_0 << 8n, 0n)
|
|
1380
1397
|
kk + 2n
|
|
1381
|
-
} else if (
|
|
1398
|
+
} else if (kk > 0n && kk <= 21n) {
|
|
1382
1399
|
// 1234e-2 -> 12.34
|
|
1383
1400
|
let ptr = buffer + kk
|
|
1384
1401
|
Memory.copy(ptr + 1n, ptr, 0n - k)
|
|
1385
1402
|
WasmI32.store8(buffer + kk, _CHAR_CODE_DOT, 0n)
|
|
1386
1403
|
length + 1n
|
|
1387
|
-
} else if (
|
|
1404
|
+
} else if (-6n < kk && kk <= 0n) {
|
|
1388
1405
|
// 1234e-6 -> 0.001234
|
|
1389
1406
|
let offset = 2n - kk
|
|
1390
1407
|
Memory.copy(buffer + offset, buffer, length)
|
|
1391
1408
|
WasmI32.store16(buffer, _CHAR_CODE_0 | _CHAR_CODE_DOT << 8n, 0n)
|
|
1392
|
-
for (let mut i = 2n;
|
|
1409
|
+
for (let mut i = 2n; i < offset; i += 1n) {
|
|
1393
1410
|
WasmI32.store8(buffer + i, _CHAR_CODE_0, 0n)
|
|
1394
1411
|
}
|
|
1395
1412
|
length + offset
|
|
@@ -1410,8 +1427,9 @@ let prettify = (buffer, length, k) => {
|
|
|
1410
1427
|
|
|
1411
1428
|
@unsafe
|
|
1412
1429
|
let dtoa_core = (buffer, value) => {
|
|
1430
|
+
use WasmF64.{ (<) }
|
|
1413
1431
|
let mut value = value
|
|
1414
|
-
let hasSign =
|
|
1432
|
+
let hasSign = value < 0.0W
|
|
1415
1433
|
if (hasSign) {
|
|
1416
1434
|
value = WasmF64.neg(value)
|
|
1417
1435
|
WasmI32.store8(buffer, _CHAR_CODE_MINUS, 0n)
|
|
@@ -1434,29 +1452,33 @@ let get_dtoa_buf = () => {
|
|
|
1434
1452
|
}
|
|
1435
1453
|
|
|
1436
1454
|
@unsafe
|
|
1437
|
-
let isFinite = value => {
|
|
1438
|
-
WasmF64.
|
|
1455
|
+
provide let isFinite = value => {
|
|
1456
|
+
use WasmF64.{ (==), (-) }
|
|
1457
|
+
value - value == 0.0W
|
|
1439
1458
|
}
|
|
1440
1459
|
|
|
1441
1460
|
@unsafe
|
|
1442
|
-
let isNaN = value => {
|
|
1443
|
-
WasmF64.
|
|
1461
|
+
provide let isNaN = value => {
|
|
1462
|
+
use WasmF64.{ (!=) }
|
|
1463
|
+
value != value
|
|
1444
1464
|
}
|
|
1445
1465
|
|
|
1446
1466
|
@unsafe
|
|
1447
|
-
|
|
1448
|
-
|
|
1467
|
+
provide let dtoa = value => {
|
|
1468
|
+
use WasmF64.{ (==) }
|
|
1469
|
+
let str = if (value == 0.0W) {
|
|
1449
1470
|
let ret = allocateString(3n)
|
|
1450
1471
|
WasmI32.store8(ret, _CHAR_CODE_0, 8n)
|
|
1451
1472
|
WasmI32.store8(ret, _CHAR_CODE_DOT, 9n)
|
|
1452
1473
|
WasmI32.store8(ret, _CHAR_CODE_0, 10n)
|
|
1453
1474
|
ret
|
|
1454
1475
|
} else if (!isFinite(value)) {
|
|
1476
|
+
use WasmF64.{ (<) }
|
|
1455
1477
|
if (isNaN(value)) {
|
|
1456
1478
|
let ret = allocateString(3n)
|
|
1457
1479
|
WasmI32.store(ret, 0x4E614En, 8n) // NaN
|
|
1458
1480
|
ret
|
|
1459
|
-
} else if (
|
|
1481
|
+
} else if (value < 0.0W) {
|
|
1460
1482
|
let ret = allocateString(9n)
|
|
1461
1483
|
WasmI64.store(ret, 0x74696E69666E492DN, 8n) // tinifnI-
|
|
1462
1484
|
WasmI32.store8(ret, 0x79n, 16n) // y
|
|
@@ -1474,6 +1496,3 @@ export let dtoa = value => {
|
|
|
1474
1496
|
}
|
|
1475
1497
|
WasmI32.toGrain(str): String
|
|
1476
1498
|
}
|
|
1477
|
-
|
|
1478
|
-
Memory.utoa32Buffered := utoa32Buffered
|
|
1479
|
-
Memory.decimalCount32 := decimalCount32
|