@grain/stdlib 0.4.4 → 0.4.5
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 +7 -0
- package/array.gr +76 -57
- package/buffer.gr +7 -4
- package/bytes.gr +10 -10
- package/char.gr +112 -56
- package/char.md +200 -0
- package/hash.gr +17 -13
- package/list.gr +78 -61
- package/map.gr +106 -110
- package/number.gr +25 -7
- package/number.md +34 -0
- package/option.gr +25 -25
- package/package.json +1 -1
- package/pervasives.gr +32 -20
- package/queue.gr +4 -1
- package/range.gr +26 -26
- package/runtime/dataStructures.gr +28 -29
- package/runtime/debug.gr +0 -1
- package/runtime/equal.gr +37 -16
- package/runtime/exception.gr +28 -15
- package/runtime/gc.gr +31 -18
- package/runtime/malloc.gr +19 -11
- package/runtime/numberUtils.gr +208 -105
- package/runtime/numbers.gr +217 -118
- package/runtime/string.gr +98 -39
- package/runtime/stringUtils.gr +6 -2
- package/runtime/unsafe/conv.gr +10 -10
- package/runtime/unsafe/memory.gr +14 -3
- package/runtime/unsafe/printWasm.gr +4 -4
- package/runtime/unsafe/tags.gr +2 -2
- package/runtime/unsafe/wasmf32.gr +9 -2
- package/runtime/unsafe/wasmf64.gr +9 -2
- package/runtime/unsafe/wasmi32.gr +65 -47
- package/runtime/unsafe/wasmi64.gr +78 -50
- package/runtime/wasi.gr +199 -45
- package/set.gr +111 -116
- package/stack.gr +26 -26
- package/string.gr +273 -119
- package/sys/file.gr +356 -177
- package/sys/process.gr +10 -6
- package/sys/random.gr +3 -6
- package/sys/time.gr +3 -3
package/map.gr
CHANGED
|
@@ -11,21 +11,18 @@ import { allocateArray } from "runtime/dataStructures"
|
|
|
11
11
|
record Bucket<k, v> {
|
|
12
12
|
mut key: k,
|
|
13
13
|
mut value: v,
|
|
14
|
-
mut next: Option<Bucket<k, v
|
|
14
|
+
mut next: Option<Bucket<k, v>>,
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
record Map<k, v> {
|
|
18
18
|
mut size: Number,
|
|
19
|
-
mut buckets: Array<Option<Bucket<k, v
|
|
19
|
+
mut buckets: Array<Option<Bucket<k, v>>>,
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
// TODO: This could take an `eq` function to custom comparisons
|
|
23
|
-
export let makeSized =
|
|
24
|
-
let buckets = Array.make(size, None)
|
|
25
|
-
{
|
|
26
|
-
size: 0,
|
|
27
|
-
buckets
|
|
28
|
-
}
|
|
23
|
+
export let makeSized = size => {
|
|
24
|
+
let buckets = Array.make(size, None)
|
|
25
|
+
{ size: 0, buckets }
|
|
29
26
|
}
|
|
30
27
|
|
|
31
28
|
export let make = () => {
|
|
@@ -33,8 +30,8 @@ export let make = () => {
|
|
|
33
30
|
}
|
|
34
31
|
|
|
35
32
|
let getBucketIndex = (key, buckets) => {
|
|
36
|
-
let bucketsLength = Array.length(buckets)
|
|
37
|
-
let hashedKey = hash(key)
|
|
33
|
+
let bucketsLength = Array.length(buckets)
|
|
34
|
+
let hashedKey = hash(key)
|
|
38
35
|
hashedKey % bucketsLength
|
|
39
36
|
}
|
|
40
37
|
|
|
@@ -42,45 +39,45 @@ let rec copyNodeWithNewHash = (oldNode, next, tail) => {
|
|
|
42
39
|
match (oldNode) {
|
|
43
40
|
None => void,
|
|
44
41
|
Some(node) => {
|
|
45
|
-
let idx = getBucketIndex(node.key, next)
|
|
46
|
-
let newNode = Some(node)
|
|
42
|
+
let idx = getBucketIndex(node.key, next)
|
|
43
|
+
let newNode = Some(node)
|
|
47
44
|
match (tail[idx]) {
|
|
48
45
|
None => {
|
|
49
|
-
next[idx] = newNode
|
|
46
|
+
next[idx] = newNode
|
|
50
47
|
},
|
|
51
48
|
Some(tailNode) => {
|
|
52
49
|
// If there's already a tail node, we add this to the end
|
|
53
|
-
tailNode.next = newNode
|
|
54
|
-
}
|
|
50
|
+
tailNode.next = newNode
|
|
51
|
+
},
|
|
55
52
|
}
|
|
56
53
|
// Always place this node as the new tail
|
|
57
|
-
tail[idx] = newNode
|
|
54
|
+
tail[idx] = newNode
|
|
58
55
|
// Recurse with the next node
|
|
59
|
-
copyNodeWithNewHash(node.next, next, tail)
|
|
60
|
-
}
|
|
56
|
+
copyNodeWithNewHash(node.next, next, tail)
|
|
57
|
+
},
|
|
61
58
|
}
|
|
62
59
|
}
|
|
63
60
|
|
|
64
|
-
let resize =
|
|
65
|
-
let currentBuckets = map.buckets
|
|
66
|
-
let currentSize = Array.length(currentBuckets)
|
|
67
|
-
let nextSize = currentSize * 2
|
|
61
|
+
let resize = map => {
|
|
62
|
+
let currentBuckets = map.buckets
|
|
63
|
+
let currentSize = Array.length(currentBuckets)
|
|
64
|
+
let nextSize = currentSize * 2
|
|
68
65
|
if (nextSize >= currentSize) {
|
|
69
|
-
let nextBuckets = Array.make(nextSize, None)
|
|
66
|
+
let nextBuckets = Array.make(nextSize, None)
|
|
70
67
|
// This tracks the tail nodes so we can set their `next` to None
|
|
71
|
-
let tailNodes = Array.make(nextSize, None)
|
|
72
|
-
map.buckets = nextBuckets
|
|
73
|
-
Array.forEach(
|
|
74
|
-
copyNodeWithNewHash(old, nextBuckets, tailNodes)
|
|
75
|
-
}, currentBuckets)
|
|
76
|
-
Array.forEach(
|
|
68
|
+
let tailNodes = Array.make(nextSize, None)
|
|
69
|
+
map.buckets = nextBuckets
|
|
70
|
+
Array.forEach(old => {
|
|
71
|
+
copyNodeWithNewHash(old, nextBuckets, tailNodes)
|
|
72
|
+
}, currentBuckets)
|
|
73
|
+
Array.forEach(tail => {
|
|
77
74
|
match (tail) {
|
|
78
75
|
None => void,
|
|
79
76
|
Some(node) => {
|
|
80
|
-
node.next = None
|
|
81
|
-
}
|
|
77
|
+
node.next = None
|
|
78
|
+
},
|
|
82
79
|
}
|
|
83
|
-
}, tailNodes)
|
|
80
|
+
}, tailNodes)
|
|
84
81
|
} else {
|
|
85
82
|
void
|
|
86
83
|
}
|
|
@@ -88,35 +85,35 @@ let resize = (map) => {
|
|
|
88
85
|
|
|
89
86
|
let rec replaceInBucket = (key, value, node) => {
|
|
90
87
|
if (key == node.key) {
|
|
91
|
-
node.value = value
|
|
88
|
+
node.value = value
|
|
92
89
|
false
|
|
93
90
|
} else {
|
|
94
91
|
match (node.next) {
|
|
95
92
|
None => true,
|
|
96
|
-
Some(next) => replaceInBucket(key, value, next)
|
|
93
|
+
Some(next) => replaceInBucket(key, value, next),
|
|
97
94
|
}
|
|
98
95
|
}
|
|
99
96
|
}
|
|
100
97
|
|
|
101
98
|
export let set = (key, value, map) => {
|
|
102
|
-
let buckets = map.buckets
|
|
99
|
+
let buckets = map.buckets
|
|
103
100
|
let idx = getBucketIndex(key, buckets)
|
|
104
|
-
let bucket = buckets[idx]
|
|
101
|
+
let bucket = buckets[idx]
|
|
105
102
|
match (bucket) {
|
|
106
103
|
None => {
|
|
107
|
-
buckets[idx] = Some({ key, value, next: None })
|
|
108
|
-
map.size = incr(map.size)
|
|
104
|
+
buckets[idx] = Some({ key, value, next: None })
|
|
105
|
+
map.size = incr(map.size)
|
|
109
106
|
},
|
|
110
107
|
Some(node) => {
|
|
111
108
|
if (replaceInBucket(key, value, node)) {
|
|
112
|
-
buckets[idx] = Some({ key, value, next: bucket })
|
|
113
|
-
map.size = incr(map.size)
|
|
114
|
-
}
|
|
115
|
-
}
|
|
109
|
+
buckets[idx] = Some({ key, value, next: bucket })
|
|
110
|
+
map.size = incr(map.size)
|
|
111
|
+
}
|
|
112
|
+
},
|
|
116
113
|
}
|
|
117
114
|
// Resize if there are more than 2x the amount of nodes as buckets
|
|
118
|
-
if (map.size >
|
|
119
|
-
resize(map)
|
|
115
|
+
if (map.size > Array.length(buckets) * 2) {
|
|
116
|
+
resize(map)
|
|
120
117
|
} else {
|
|
121
118
|
void
|
|
122
119
|
}
|
|
@@ -128,18 +125,18 @@ let rec valueFromBucket = (key, node) => {
|
|
|
128
125
|
} else {
|
|
129
126
|
match (node.next) {
|
|
130
127
|
None => None,
|
|
131
|
-
Some(next) => valueFromBucket(key, next)
|
|
128
|
+
Some(next) => valueFromBucket(key, next),
|
|
132
129
|
}
|
|
133
130
|
}
|
|
134
131
|
}
|
|
135
132
|
|
|
136
133
|
export let get = (key, map) => {
|
|
137
|
-
let buckets = map.buckets
|
|
138
|
-
let idx = getBucketIndex(key, buckets)
|
|
139
|
-
let bucket = buckets[idx]
|
|
134
|
+
let buckets = map.buckets
|
|
135
|
+
let idx = getBucketIndex(key, buckets)
|
|
136
|
+
let bucket = buckets[idx]
|
|
140
137
|
match (bucket) {
|
|
141
138
|
None => None,
|
|
142
|
-
Some(node) => valueFromBucket(key, node)
|
|
139
|
+
Some(node) => valueFromBucket(key, node),
|
|
143
140
|
}
|
|
144
141
|
}
|
|
145
142
|
|
|
@@ -149,18 +146,18 @@ let rec nodeInBucket = (key, node) => {
|
|
|
149
146
|
} else {
|
|
150
147
|
match (node.next) {
|
|
151
148
|
None => false,
|
|
152
|
-
Some(next) => nodeInBucket(key, next)
|
|
149
|
+
Some(next) => nodeInBucket(key, next),
|
|
153
150
|
}
|
|
154
151
|
}
|
|
155
152
|
}
|
|
156
153
|
|
|
157
154
|
export let contains = (key, map) => {
|
|
158
|
-
let buckets = map.buckets
|
|
159
|
-
let idx = getBucketIndex(key, buckets)
|
|
160
|
-
let bucket = buckets[idx]
|
|
155
|
+
let buckets = map.buckets
|
|
156
|
+
let idx = getBucketIndex(key, buckets)
|
|
157
|
+
let bucket = buckets[idx]
|
|
161
158
|
match (bucket) {
|
|
162
159
|
None => false,
|
|
163
|
-
Some(node) => nodeInBucket(key, node)
|
|
160
|
+
Some(node) => nodeInBucket(key, node),
|
|
164
161
|
}
|
|
165
162
|
}
|
|
166
163
|
|
|
@@ -169,115 +166,115 @@ let rec removeInBucket = (key, node) => {
|
|
|
169
166
|
None => false,
|
|
170
167
|
Some(next) => {
|
|
171
168
|
if (key == next.key) {
|
|
172
|
-
node.next = next.next
|
|
169
|
+
node.next = next.next
|
|
173
170
|
true
|
|
174
171
|
} else {
|
|
175
172
|
removeInBucket(key, next)
|
|
176
173
|
}
|
|
177
|
-
}
|
|
174
|
+
},
|
|
178
175
|
}
|
|
179
176
|
}
|
|
180
177
|
|
|
181
178
|
export let remove = (key, map) => {
|
|
182
|
-
let buckets = map.buckets
|
|
183
|
-
let idx = getBucketIndex(key, buckets)
|
|
184
|
-
let bucket = buckets[idx]
|
|
179
|
+
let buckets = map.buckets
|
|
180
|
+
let idx = getBucketIndex(key, buckets)
|
|
181
|
+
let bucket = buckets[idx]
|
|
185
182
|
match (bucket) {
|
|
186
183
|
None => void,
|
|
187
184
|
Some(node) => {
|
|
188
185
|
// If it is a top-level node, just replace with next node
|
|
189
186
|
if (key == node.key) {
|
|
190
|
-
map.size = decr(map.size)
|
|
191
|
-
buckets[idx] = node.next
|
|
187
|
+
map.size = decr(map.size)
|
|
188
|
+
buckets[idx] = node.next
|
|
192
189
|
} else {
|
|
193
190
|
if (removeInBucket(key, node)) {
|
|
194
|
-
map.size = decr(map.size)
|
|
191
|
+
map.size = decr(map.size)
|
|
195
192
|
}
|
|
196
193
|
}
|
|
197
|
-
}
|
|
194
|
+
},
|
|
198
195
|
}
|
|
199
196
|
}
|
|
200
197
|
|
|
201
198
|
export let update = (key, fn, map) => {
|
|
202
|
-
let val = get(key, map)
|
|
199
|
+
let val = get(key, map)
|
|
203
200
|
match (fn(val)) {
|
|
204
201
|
Some(next) => set(key, next, map),
|
|
205
|
-
None => remove(key, map)
|
|
202
|
+
None => remove(key, map),
|
|
206
203
|
}
|
|
207
204
|
}
|
|
208
205
|
|
|
209
|
-
export let size =
|
|
206
|
+
export let size = map => {
|
|
210
207
|
map.size
|
|
211
208
|
}
|
|
212
209
|
|
|
213
|
-
export let isEmpty =
|
|
210
|
+
export let isEmpty = map => {
|
|
214
211
|
size(map) == 0
|
|
215
212
|
}
|
|
216
213
|
|
|
217
|
-
export let clear =
|
|
218
|
-
map.size = 0
|
|
219
|
-
let buckets = map.buckets
|
|
214
|
+
export let clear = map => {
|
|
215
|
+
map.size = 0
|
|
216
|
+
let buckets = map.buckets
|
|
220
217
|
Array.forEachi((bucket, idx) => {
|
|
221
|
-
buckets[idx] = None
|
|
222
|
-
}, buckets)
|
|
218
|
+
buckets[idx] = None
|
|
219
|
+
}, buckets)
|
|
223
220
|
}
|
|
224
221
|
|
|
225
222
|
let rec forEachBucket = (fn, node) => {
|
|
226
223
|
match (node) {
|
|
227
224
|
None => void,
|
|
228
225
|
Some({ key, value, next }) => {
|
|
229
|
-
fn(key, value)
|
|
230
|
-
forEachBucket(fn, next)
|
|
231
|
-
}
|
|
226
|
+
fn(key, value)
|
|
227
|
+
forEachBucket(fn, next)
|
|
228
|
+
},
|
|
232
229
|
}
|
|
233
230
|
}
|
|
234
231
|
|
|
235
232
|
export let forEach = (fn, map) => {
|
|
236
|
-
let buckets = map.buckets
|
|
237
|
-
Array.forEach(
|
|
233
|
+
let buckets = map.buckets
|
|
234
|
+
Array.forEach(bucket => {
|
|
238
235
|
forEachBucket(fn, bucket)
|
|
239
|
-
}, buckets)
|
|
236
|
+
}, buckets)
|
|
240
237
|
}
|
|
241
238
|
|
|
242
239
|
let rec reduceEachBucket = (fn, node, acc) => {
|
|
243
240
|
match (node) {
|
|
244
241
|
None => acc,
|
|
245
242
|
Some({ key, value, next }) =>
|
|
246
|
-
reduceEachBucket(fn, next, fn(acc, key, value))
|
|
243
|
+
reduceEachBucket(fn, next, fn(acc, key, value)),
|
|
247
244
|
}
|
|
248
245
|
}
|
|
249
246
|
|
|
250
247
|
export let reduce = (fn, init, map) => {
|
|
251
|
-
let buckets = map.buckets
|
|
252
|
-
let mut acc = init
|
|
253
|
-
Array.forEach(
|
|
248
|
+
let buckets = map.buckets
|
|
249
|
+
let mut acc = init
|
|
250
|
+
Array.forEach(bucket => {
|
|
254
251
|
acc = reduceEachBucket(fn, bucket, acc)
|
|
255
|
-
}, buckets)
|
|
252
|
+
}, buckets)
|
|
256
253
|
acc
|
|
257
254
|
}
|
|
258
255
|
|
|
259
|
-
export let keys =
|
|
256
|
+
export let keys = map => {
|
|
260
257
|
reduce((list, key, _value) => [key, ...list], [], map)
|
|
261
258
|
}
|
|
262
259
|
|
|
263
|
-
export let values =
|
|
260
|
+
export let values = map => {
|
|
264
261
|
reduce((list, _key, value) => [value, ...list], [], map)
|
|
265
262
|
}
|
|
266
263
|
|
|
267
|
-
export let toList =
|
|
264
|
+
export let toList = map => {
|
|
268
265
|
reduce((list, key, value) => [(key, value), ...list], [], map)
|
|
269
266
|
}
|
|
270
267
|
|
|
271
|
-
export let fromList =
|
|
272
|
-
let map = make()
|
|
273
|
-
List.forEach(
|
|
274
|
-
let (key, value) = pair
|
|
275
|
-
set(key, value, map)
|
|
276
|
-
}, list)
|
|
268
|
+
export let fromList = list => {
|
|
269
|
+
let map = make()
|
|
270
|
+
List.forEach(pair => {
|
|
271
|
+
let (key, value) = pair
|
|
272
|
+
set(key, value, map)
|
|
273
|
+
}, list)
|
|
277
274
|
map
|
|
278
275
|
}
|
|
279
276
|
|
|
280
|
-
let setInArray =
|
|
277
|
+
let setInArray = array => {
|
|
281
278
|
@disableGC
|
|
282
279
|
let rec iter = (i, key, value) => {
|
|
283
280
|
array[i] = (key, value)
|
|
@@ -289,7 +286,7 @@ let setInArray = (array) => {
|
|
|
289
286
|
}
|
|
290
287
|
|
|
291
288
|
@disableGC
|
|
292
|
-
export let rec toArray =
|
|
289
|
+
export let rec toArray = map => {
|
|
293
290
|
let length = WasmI32.shrS(WasmI32.fromGrain(map.size), 1n)
|
|
294
291
|
// TODO(#783): Removing parens around Array<a> causes a parse error
|
|
295
292
|
let array = WasmI32.toGrain(allocateArray(length)): (Array<a>)
|
|
@@ -306,25 +303,24 @@ export let rec toArray = (map) => {
|
|
|
306
303
|
array
|
|
307
304
|
}
|
|
308
305
|
|
|
309
|
-
export let fromArray =
|
|
310
|
-
let map = make()
|
|
311
|
-
Array.forEach(
|
|
312
|
-
let (key, value) = pair
|
|
313
|
-
set(key, value, map)
|
|
314
|
-
}, array)
|
|
306
|
+
export let fromArray = array => {
|
|
307
|
+
let map = make()
|
|
308
|
+
Array.forEach(pair => {
|
|
309
|
+
let (key, value) = pair
|
|
310
|
+
set(key, value, map)
|
|
311
|
+
}, array)
|
|
315
312
|
map
|
|
316
313
|
}
|
|
317
314
|
|
|
318
315
|
export let filter = (predicate, map) => {
|
|
319
|
-
let keysToRemove = reduce((list, key, value) =>
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
}, keysToRemove);
|
|
316
|
+
let keysToRemove = reduce((list, key, value) => if (!predicate(key, value)) {
|
|
317
|
+
[key, ...list]
|
|
318
|
+
} else {
|
|
319
|
+
list
|
|
320
|
+
}, [], map)
|
|
321
|
+
List.forEach(key => {
|
|
322
|
+
remove(key, map)
|
|
323
|
+
}, keysToRemove)
|
|
328
324
|
}
|
|
329
325
|
|
|
330
326
|
export let reject = (predicate, map) => {
|
|
@@ -333,6 +329,6 @@ export let reject = (predicate, map) => {
|
|
|
333
329
|
|
|
334
330
|
// TODO: Should return a Record type instead of a Tuple
|
|
335
331
|
// Waiting on https://github.com/grain-lang/grain/issues/190
|
|
336
|
-
export let getInternalStats =
|
|
332
|
+
export let getInternalStats = map => {
|
|
337
333
|
(map.size, Array.length(map.buckets))
|
|
338
334
|
}
|
package/number.gr
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
coerceNumberToWasmF64,
|
|
14
14
|
reducedInteger,
|
|
15
15
|
isFloat,
|
|
16
|
-
isBoxedNumber
|
|
16
|
+
isBoxedNumber,
|
|
17
17
|
} from "runtime/numbers"
|
|
18
18
|
import { parseInt } from "runtime/stringUtils"
|
|
19
19
|
import { newFloat64, newInt64 } from "runtime/dataStructures"
|
|
@@ -77,15 +77,33 @@ export let rec sqrt = (x: Number) => {
|
|
|
77
77
|
let x = WasmI32.fromGrain(x)
|
|
78
78
|
let sqrtd = WasmF64.sqrt(xval)
|
|
79
79
|
let ret = if (!isFloat(x) && WasmF64.eq(sqrtd, WasmF64.trunc(sqrtd))) {
|
|
80
|
-
WasmI32.toGrain(reducedInteger(WasmI64.truncF64S(sqrtd))):
|
|
80
|
+
WasmI32.toGrain(reducedInteger(WasmI64.truncF64S(sqrtd))): Number
|
|
81
81
|
} else {
|
|
82
|
-
WasmI32.toGrain(newFloat64(sqrtd)):
|
|
82
|
+
WasmI32.toGrain(newFloat64(sqrtd)): Number
|
|
83
83
|
}
|
|
84
84
|
Memory.decRef(WasmI32.fromGrain(x))
|
|
85
85
|
Memory.decRef(WasmI32.fromGrain(sqrt))
|
|
86
86
|
ret
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
/**
|
|
90
|
+
* Determine the positivity or negativity of a Number.
|
|
91
|
+
*
|
|
92
|
+
* @param x: The number to inspect
|
|
93
|
+
* @returns `-1` if the number is negative, `1` if positive, or `0` otherwise; signedness of `-0.0` is preserved
|
|
94
|
+
*
|
|
95
|
+
* @example Number.sign(-10000) == -1
|
|
96
|
+
* @example Number.sign(222222) == 1
|
|
97
|
+
* @example Number.sign(0) == 0
|
|
98
|
+
*/
|
|
99
|
+
export let sign = x => {
|
|
100
|
+
match (x) {
|
|
101
|
+
x when x < 0 => -1,
|
|
102
|
+
x when x > 0 => 1,
|
|
103
|
+
_ => 0 * x,
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
89
107
|
/**
|
|
90
108
|
* Returns the smaller of its operands.
|
|
91
109
|
*
|
|
@@ -120,7 +138,7 @@ export let max = (x: Number, y: Number) => if (x > y) x else y
|
|
|
120
138
|
export let rec ceil = (x: Number) => {
|
|
121
139
|
let xval = coerceNumberToWasmF64(x)
|
|
122
140
|
let ceiling = WasmI64.truncF64S(WasmF64.ceil(xval))
|
|
123
|
-
let ret = WasmI32.toGrain(reducedInteger(ceiling)):
|
|
141
|
+
let ret = WasmI32.toGrain(reducedInteger(ceiling)): Number
|
|
124
142
|
Memory.decRef(WasmI32.fromGrain(x))
|
|
125
143
|
Memory.decRef(WasmI32.fromGrain(ceil))
|
|
126
144
|
ret
|
|
@@ -138,7 +156,7 @@ export let rec ceil = (x: Number) => {
|
|
|
138
156
|
export let rec floor = (x: Number) => {
|
|
139
157
|
let xval = coerceNumberToWasmF64(x)
|
|
140
158
|
let floored = WasmI64.truncF64S(WasmF64.floor(xval))
|
|
141
|
-
let ret = WasmI32.toGrain(reducedInteger(floored)):
|
|
159
|
+
let ret = WasmI32.toGrain(reducedInteger(floored)): Number
|
|
142
160
|
Memory.decRef(WasmI32.fromGrain(x))
|
|
143
161
|
Memory.decRef(WasmI32.fromGrain(floor))
|
|
144
162
|
ret
|
|
@@ -156,7 +174,7 @@ export let rec floor = (x: Number) => {
|
|
|
156
174
|
export let rec trunc = (x: Number) => {
|
|
157
175
|
let xval = coerceNumberToWasmF64(x)
|
|
158
176
|
let trunced = WasmI64.truncF64S(xval)
|
|
159
|
-
let ret = WasmI32.toGrain(reducedInteger(trunced)):
|
|
177
|
+
let ret = WasmI32.toGrain(reducedInteger(trunced)): Number
|
|
160
178
|
Memory.decRef(WasmI32.fromGrain(x))
|
|
161
179
|
Memory.decRef(WasmI32.fromGrain(trunc))
|
|
162
180
|
ret
|
|
@@ -174,7 +192,7 @@ export let rec trunc = (x: Number) => {
|
|
|
174
192
|
export let rec round = (x: Number) => {
|
|
175
193
|
let xval = coerceNumberToWasmF64(x)
|
|
176
194
|
let rounded = WasmI64.truncF64S(WasmF64.nearest(xval))
|
|
177
|
-
let ret = WasmI32.toGrain(reducedInteger(rounded)):
|
|
195
|
+
let ret = WasmI32.toGrain(reducedInteger(rounded)): Number
|
|
178
196
|
Memory.decRef(WasmI32.fromGrain(x))
|
|
179
197
|
Memory.decRef(WasmI32.fromGrain(round))
|
|
180
198
|
ret
|
package/number.md
CHANGED
|
@@ -142,6 +142,40 @@ Returns:
|
|
|
142
142
|
|----|-----------|
|
|
143
143
|
|`Number`|The square root of the operand|
|
|
144
144
|
|
|
145
|
+
### Number.**sign**
|
|
146
|
+
|
|
147
|
+
```grain
|
|
148
|
+
sign : Number -> Number
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Determine the positivity or negativity of a Number.
|
|
152
|
+
|
|
153
|
+
Parameters:
|
|
154
|
+
|
|
155
|
+
|param|type|description|
|
|
156
|
+
|-----|----|-----------|
|
|
157
|
+
|`x`|`Number`|The number to inspect|
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
|
|
161
|
+
|type|description|
|
|
162
|
+
|----|-----------|
|
|
163
|
+
|`Number`|`-1` if the number is negative, `1` if positive, or `0` otherwise; signedness of `-0.0` is preserved|
|
|
164
|
+
|
|
165
|
+
Examples:
|
|
166
|
+
|
|
167
|
+
```grain
|
|
168
|
+
Number.sign(-10000) == -1
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
```grain
|
|
172
|
+
Number.sign(222222) == 1
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
```grain
|
|
176
|
+
Number.sign(0) == 0
|
|
177
|
+
```
|
|
178
|
+
|
|
145
179
|
### Number.**min**
|
|
146
180
|
|
|
147
181
|
<details disabled>
|