@grain/stdlib 0.6.5 → 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 +64 -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 +387 -49
- 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.gr +81 -0
- package/uint16.md +183 -22
- package/uint32.gr +25 -4
- package/uint32.md +63 -28
- package/uint64.gr +25 -5
- package/uint64.md +63 -28
- package/uint8.gr +81 -0
- package/uint8.md +183 -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
package/number.gr
CHANGED
|
@@ -48,6 +48,8 @@ from "runtime/atoi/parse" include Parse as Atoi
|
|
|
48
48
|
from "runtime/atof/parse" include Parse as Atof
|
|
49
49
|
from "runtime/unsafe/tags" include Tags
|
|
50
50
|
from "runtime/exception" include Exception
|
|
51
|
+
from "runtime/math/trig" include Trig
|
|
52
|
+
use Trig.{ sin, cos, tan }
|
|
51
53
|
|
|
52
54
|
use Atoi.{ type ParseIntError }
|
|
53
55
|
|
|
@@ -551,8 +553,8 @@ provide let isClose = (a, b, relativeTolerance=1e-9, absoluteTolerance=0.0) => {
|
|
|
551
553
|
if (a == b) {
|
|
552
554
|
true
|
|
553
555
|
} else if (isFinite(a) && isFinite(b)) {
|
|
554
|
-
abs(a - b)
|
|
555
|
-
max(relativeTolerance * max(abs(a), abs(b)), absoluteTolerance)
|
|
556
|
+
abs(a - b)
|
|
557
|
+
<= max(relativeTolerance * max(abs(a), abs(b)), absoluteTolerance)
|
|
556
558
|
} else {
|
|
557
559
|
// NaN and infinities which were not equal
|
|
558
560
|
false
|
|
@@ -659,28 +661,6 @@ provide let parse = input => {
|
|
|
659
661
|
}
|
|
660
662
|
}
|
|
661
663
|
|
|
662
|
-
/**
|
|
663
|
-
* Computes how many times pi has to be subtracted to achieve the required bounds for sin.
|
|
664
|
-
*/
|
|
665
|
-
let reduceToPiBound = (radians: Number) => {
|
|
666
|
-
floor(radians / pi)
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
/**
|
|
670
|
-
* Computes the sine of a number using Chebyshev polynomials. Requires the input to be bounded to (-pi, pi). More information on the algorithm can be found here: http://mooooo.ooo/chebyshev-sine-approximation/.
|
|
671
|
-
*/
|
|
672
|
-
let chebyshevSine = (radians: Number) => {
|
|
673
|
-
let pi_minor = -0.00000008742278
|
|
674
|
-
let x2 = radians * radians
|
|
675
|
-
let p11 = 0.00000000013291342
|
|
676
|
-
let p9 = p11 * x2 + -0.000000023317787
|
|
677
|
-
let p7 = p9 * x2 + 0.0000025222919
|
|
678
|
-
let p5 = p7 * x2 + -0.00017350505
|
|
679
|
-
let p3 = p5 * x2 + 0.0066208798
|
|
680
|
-
let p1 = p3 * x2 + -0.10132118
|
|
681
|
-
(radians - pi - pi_minor) * (radians + pi + pi_minor) * p1 * radians
|
|
682
|
-
}
|
|
683
|
-
|
|
684
664
|
@unsafe
|
|
685
665
|
let rf = z => {
|
|
686
666
|
// see: musl/src/math/asin.c and SUN COPYRIGHT NOTICE at top of file
|
|
@@ -761,8 +741,8 @@ provide let asin = angle => {
|
|
|
761
741
|
WasmI64.reinterpretF64(s) & 0xFFFFFFFF00000000N
|
|
762
742
|
)
|
|
763
743
|
let c = (z - f * f) / (s + f)
|
|
764
|
-
x = 0.5W * pio2_hi
|
|
765
|
-
(2.0W * s * r - (pio2_lo - 2.0W * c) - (0.5W * pio2_hi - 2.0W * f))
|
|
744
|
+
x = 0.5W * pio2_hi
|
|
745
|
+
- (2.0W * s * r - (pio2_lo - 2.0W * c) - (0.5W * pio2_hi - 2.0W * f))
|
|
766
746
|
}
|
|
767
747
|
x = WasmF64.copySign(x, origAngle)
|
|
768
748
|
return WasmI32.toGrain(newFloat64(x)): Number
|
|
@@ -1065,10 +1045,159 @@ provide let linearMap = (inputRange, outputRange, current) => {
|
|
|
1065
1045
|
throw Exception.InvalidArgument("The outputRange must be finite")
|
|
1066
1046
|
if (isNaN(outputRange.rangeStart) || isNaN(outputRange.rangeEnd))
|
|
1067
1047
|
throw Exception.InvalidArgument("The outputRange must not include NaN")
|
|
1068
|
-
let mapped = (current - inputRange.rangeStart)
|
|
1069
|
-
(outputRange.rangeEnd - outputRange.rangeStart)
|
|
1070
|
-
(inputRange.rangeEnd - inputRange.rangeStart)
|
|
1071
|
-
outputRange.rangeStart
|
|
1048
|
+
let mapped = (current - inputRange.rangeStart)
|
|
1049
|
+
* (outputRange.rangeEnd - outputRange.rangeStart)
|
|
1050
|
+
/ (inputRange.rangeEnd - inputRange.rangeStart)
|
|
1051
|
+
+ outputRange.rangeStart
|
|
1072
1052
|
clamp(outputRange, mapped)
|
|
1073
1053
|
}
|
|
1074
1054
|
}
|
|
1055
|
+
|
|
1056
|
+
/**
|
|
1057
|
+
* Computes the sine of a number (in radians).
|
|
1058
|
+
*
|
|
1059
|
+
* @param radians: The input in radians
|
|
1060
|
+
* @returns The computed sine
|
|
1061
|
+
*
|
|
1062
|
+
* @example Number.sin(0) == 0
|
|
1063
|
+
*
|
|
1064
|
+
* @since v0.7.0
|
|
1065
|
+
*/
|
|
1066
|
+
@unsafe
|
|
1067
|
+
provide let sin = (radians: Number) => {
|
|
1068
|
+
use WasmF64.{ (==) }
|
|
1069
|
+
let xval = coerceNumberToWasmF64(radians)
|
|
1070
|
+
let value = sin(xval)
|
|
1071
|
+
return if (!isFloat(radians) && value == WasmF64.trunc(value)) {
|
|
1072
|
+
WasmI32.toGrain(reducedInteger(WasmI64.truncF64S(value))): Number
|
|
1073
|
+
} else {
|
|
1074
|
+
WasmI32.toGrain(newFloat64(value)): Number
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
/**
|
|
1079
|
+
* Computes the cosine of a number (in radians).
|
|
1080
|
+
*
|
|
1081
|
+
* @param radians: The input in radians
|
|
1082
|
+
* @returns The computed cosine
|
|
1083
|
+
*
|
|
1084
|
+
* @example Number.cos(0) == 1
|
|
1085
|
+
*
|
|
1086
|
+
* @since v0.7.0
|
|
1087
|
+
*/
|
|
1088
|
+
@unsafe
|
|
1089
|
+
provide let cos = (radians: Number) => {
|
|
1090
|
+
use WasmF64.{ (==) }
|
|
1091
|
+
let xval = coerceNumberToWasmF64(radians)
|
|
1092
|
+
let value = cos(xval)
|
|
1093
|
+
return if (!isFloat(radians) && value == WasmF64.trunc(value)) {
|
|
1094
|
+
WasmI32.toGrain(reducedInteger(WasmI64.truncF64S(value))): Number
|
|
1095
|
+
} else {
|
|
1096
|
+
WasmI32.toGrain(newFloat64(value)): Number
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
/**
|
|
1101
|
+
* Computes the tangent of a number (in radians).
|
|
1102
|
+
*
|
|
1103
|
+
* @param radians: The input in radians
|
|
1104
|
+
* @returns The computed tangent
|
|
1105
|
+
*
|
|
1106
|
+
* @example Number.tan(0) == 0
|
|
1107
|
+
*
|
|
1108
|
+
* @since v0.7.0
|
|
1109
|
+
*/
|
|
1110
|
+
@unsafe
|
|
1111
|
+
provide let tan = (radians: Number) => {
|
|
1112
|
+
use WasmF64.{ (==) }
|
|
1113
|
+
let xval = coerceNumberToWasmF64(radians)
|
|
1114
|
+
let value = tan(xval)
|
|
1115
|
+
return if (!isFloat(radians) && value == WasmF64.trunc(value)) {
|
|
1116
|
+
WasmI32.toGrain(reducedInteger(WasmI64.truncF64S(value))): Number
|
|
1117
|
+
} else {
|
|
1118
|
+
WasmI32.toGrain(newFloat64(value)): Number
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
// Math.gamma implemented using the Lanczos approximation
|
|
1123
|
+
// https://en.wikipedia.org/wiki/Lanczos_approximation
|
|
1124
|
+
/**
|
|
1125
|
+
* Computes the gamma function of a value using the Lanczos approximation.
|
|
1126
|
+
*
|
|
1127
|
+
* @param z: The value to interpolate
|
|
1128
|
+
* @returns The gamma of the given value
|
|
1129
|
+
*
|
|
1130
|
+
* @example Number.gamma(1) == 1
|
|
1131
|
+
* @example Number.gamma(3) == 2
|
|
1132
|
+
* @example Number.isClose(Number.gamma(0.5), Number.sqrt(Number.pi))
|
|
1133
|
+
*
|
|
1134
|
+
* @since v0.7.0
|
|
1135
|
+
*/
|
|
1136
|
+
provide let rec gamma = z => {
|
|
1137
|
+
if (z == 0 || isInteger(z) && z < 0) {
|
|
1138
|
+
NaN
|
|
1139
|
+
} else if (isInteger(z) && z > 0) {
|
|
1140
|
+
let mut output = 1
|
|
1141
|
+
for (let mut i = 1; i < z; i += 1) {
|
|
1142
|
+
output *= i
|
|
1143
|
+
}
|
|
1144
|
+
output
|
|
1145
|
+
} else {
|
|
1146
|
+
let mut z = z
|
|
1147
|
+
let g = 7
|
|
1148
|
+
let c = [>
|
|
1149
|
+
0.99999999999980993,
|
|
1150
|
+
676.5203681218851,
|
|
1151
|
+
-1259.1392167224028,
|
|
1152
|
+
771.32342877765313,
|
|
1153
|
+
-176.61502916214059,
|
|
1154
|
+
12.507343278686905,
|
|
1155
|
+
-0.13857109526572012,
|
|
1156
|
+
9.9843695780195716e-6,
|
|
1157
|
+
1.5056327351493116e-7,
|
|
1158
|
+
]
|
|
1159
|
+
let mut output = 0
|
|
1160
|
+
if (z < 0.5) {
|
|
1161
|
+
output = pi / sin(pi * z) / gamma(1 - z)
|
|
1162
|
+
} else if (z == 0.5) {
|
|
1163
|
+
// Handle this case separately because it is out of the domain of Number.pow when calculating
|
|
1164
|
+
output = 1.7724538509055159
|
|
1165
|
+
} else {
|
|
1166
|
+
z -= 1
|
|
1167
|
+
let mut x = c[0]
|
|
1168
|
+
for (let mut i = 1; i < g + 2; i += 1) {
|
|
1169
|
+
x += c[i] / (z + i)
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
let t = z + g + 0.5
|
|
1173
|
+
output = sqrt(2 * pi) * (t ** (z + 0.5)) * exp(t * -1) * x
|
|
1174
|
+
}
|
|
1175
|
+
if (abs(output) == Infinity) Infinity else output
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
/**
|
|
1180
|
+
* Computes the factorial of an integer input or the gamma function of a non-integer input.
|
|
1181
|
+
*
|
|
1182
|
+
* @param n: The value to factorialize
|
|
1183
|
+
* @returns The factorial of the given value
|
|
1184
|
+
*
|
|
1185
|
+
* @throws InvalidArgument(String): When `n` is a negative integer
|
|
1186
|
+
*
|
|
1187
|
+
* @example Number.factorial(0) == 1
|
|
1188
|
+
* @example Number.factorial(3) == 6
|
|
1189
|
+
* @example Number.isClose(Number.factorial(0.5), (1/2) * Number.sqrt(Number.pi))
|
|
1190
|
+
*
|
|
1191
|
+
* @since v0.7.0
|
|
1192
|
+
*/
|
|
1193
|
+
provide let rec factorial = n => {
|
|
1194
|
+
if (isInteger(n) && n < 0) {
|
|
1195
|
+
gamma(abs(n) + 1) * -1
|
|
1196
|
+
} else if (!isInteger(n) && n < 0) {
|
|
1197
|
+
throw Exception.InvalidArgument(
|
|
1198
|
+
"Cannot compute the factorial of a negative non-integer",
|
|
1199
|
+
)
|
|
1200
|
+
} else {
|
|
1201
|
+
gamma(n + 1)
|
|
1202
|
+
}
|
|
1203
|
+
}
|