@grain/stdlib 0.4.4 → 0.5.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 +87 -0
- package/LICENSE +1 -1
- package/array.gr +92 -73
- package/array.md +18 -18
- package/bigint.gr +497 -0
- package/bigint.md +811 -0
- package/buffer.gr +56 -217
- package/buffer.md +24 -17
- package/bytes.gr +103 -205
- package/bytes.md +19 -0
- package/char.gr +152 -166
- package/char.md +200 -0
- package/exception.md +6 -0
- package/float32.gr +159 -82
- package/float32.md +315 -0
- package/float64.gr +163 -82
- package/float64.md +315 -0
- package/hash.gr +53 -49
- package/int32.gr +479 -230
- package/int32.md +937 -0
- package/int64.gr +479 -230
- package/int64.md +937 -0
- package/list.gr +530 -116
- package/list.md +1141 -0
- package/map.gr +302 -121
- package/map.md +525 -0
- package/number.gr +51 -57
- package/number.md +37 -3
- package/option.gr +25 -25
- package/option.md +1 -1
- package/package.json +3 -3
- package/pervasives.gr +504 -52
- package/pervasives.md +1116 -0
- package/queue.gr +8 -1
- package/queue.md +10 -0
- package/random.gr +196 -0
- package/random.md +179 -0
- package/range.gr +26 -26
- package/regex.gr +1833 -842
- package/regex.md +11 -11
- package/result.md +1 -1
- package/runtime/bigint.gr +2045 -0
- package/runtime/bigint.md +326 -0
- package/runtime/dataStructures.gr +99 -279
- package/runtime/dataStructures.md +391 -0
- package/runtime/debug.gr +0 -1
- package/runtime/debug.md +6 -0
- package/runtime/equal.gr +40 -37
- package/runtime/equal.md +6 -0
- package/runtime/exception.gr +28 -15
- package/runtime/exception.md +30 -0
- package/runtime/gc.gr +50 -20
- package/runtime/gc.md +36 -0
- package/runtime/malloc.gr +32 -22
- package/runtime/malloc.md +55 -0
- package/runtime/numberUtils.gr +297 -142
- package/runtime/numberUtils.md +54 -0
- package/runtime/numbers.gr +1204 -453
- package/runtime/numbers.md +300 -0
- package/runtime/string.gr +193 -228
- package/runtime/string.md +24 -0
- package/runtime/stringUtils.gr +62 -38
- package/runtime/stringUtils.md +6 -0
- package/runtime/unsafe/constants.gr +17 -0
- package/runtime/unsafe/constants.md +72 -0
- package/runtime/unsafe/conv.gr +10 -10
- package/runtime/unsafe/conv.md +71 -0
- package/runtime/unsafe/errors.md +204 -0
- package/runtime/unsafe/memory.gr +14 -3
- package/runtime/unsafe/memory.md +54 -0
- package/runtime/unsafe/printWasm.gr +4 -4
- package/runtime/unsafe/printWasm.md +24 -0
- package/runtime/unsafe/tags.gr +11 -10
- package/runtime/unsafe/tags.md +120 -0
- package/runtime/unsafe/wasmf32.gr +9 -2
- package/runtime/unsafe/wasmf32.md +168 -0
- package/runtime/unsafe/wasmf64.gr +9 -2
- package/runtime/unsafe/wasmf64.md +168 -0
- package/runtime/unsafe/wasmi32.gr +65 -47
- package/runtime/unsafe/wasmi32.md +282 -0
- package/runtime/unsafe/wasmi64.gr +78 -50
- package/runtime/unsafe/wasmi64.md +300 -0
- package/runtime/utils/printing.gr +62 -0
- package/runtime/utils/printing.md +18 -0
- package/runtime/wasi.gr +200 -46
- package/runtime/wasi.md +839 -0
- package/set.gr +125 -121
- package/set.md +24 -21
- package/stack.gr +29 -29
- package/stack.md +4 -6
- package/string.gr +434 -415
- package/string.md +3 -3
- package/sys/file.gr +477 -482
- package/sys/process.gr +33 -47
- package/sys/random.gr +48 -20
- package/sys/random.md +38 -0
- package/sys/time.gr +12 -28
package/hash.gr
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/* grainc-flags --no-gc */
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* @module Hash: Utilities for hashing any value.
|
|
5
3
|
* @example import Hash from "hash"
|
|
@@ -25,47 +23,63 @@ import WasmI32, {
|
|
|
25
23
|
eq as (==),
|
|
26
24
|
ne as (!=),
|
|
27
25
|
gtU as (>),
|
|
28
|
-
ltU as (<)
|
|
26
|
+
ltU as (<),
|
|
29
27
|
} from "runtime/unsafe/wasmi32"
|
|
28
|
+
import WasmI64 from "runtime/unsafe/wasmi64"
|
|
30
29
|
import Tags from "runtime/unsafe/tags"
|
|
31
|
-
import Memory from "runtime/unsafe/memory"
|
|
32
30
|
|
|
33
31
|
import { tagSimpleNumber } from "runtime/dataStructures"
|
|
34
32
|
import { coerceNumberToWasmI32 } from "runtime/numbers"
|
|
33
|
+
import BI from "runtime/bigint"
|
|
35
34
|
|
|
36
35
|
import Random from "sys/random"
|
|
37
36
|
import Result from "result"
|
|
38
37
|
|
|
38
|
+
@unsafe
|
|
39
39
|
let seed = {
|
|
40
|
-
Memory.incRef(WasmI32.fromGrain(Random.random))
|
|
41
|
-
Memory.incRef(WasmI32.fromGrain(Result.unwrap))
|
|
42
40
|
let random = Random.random()
|
|
43
|
-
Memory.incRef(WasmI32.fromGrain(random))
|
|
44
41
|
coerceNumberToWasmI32(Result.unwrap(random))
|
|
45
42
|
}
|
|
46
43
|
|
|
44
|
+
@unsafe
|
|
47
45
|
let _MAX_HASH_DEPTH = 31n
|
|
48
46
|
|
|
47
|
+
@unsafe
|
|
49
48
|
let c1 = 0xcc9e2d51n
|
|
49
|
+
@unsafe
|
|
50
50
|
let c2 = 0x1b873593n
|
|
51
|
+
@unsafe
|
|
51
52
|
let r1 = 15n
|
|
53
|
+
@unsafe
|
|
52
54
|
let r2 = 13n
|
|
55
|
+
@unsafe
|
|
53
56
|
let m = 5n
|
|
57
|
+
@unsafe
|
|
54
58
|
let n = 0xe6546b64n
|
|
55
59
|
|
|
60
|
+
@unsafe
|
|
56
61
|
let mut h = seed
|
|
57
62
|
|
|
58
|
-
|
|
63
|
+
@unsafe
|
|
64
|
+
let hash32 = k => {
|
|
59
65
|
let mut k = k * c1
|
|
60
66
|
k = WasmI32.rotl(k, r1)
|
|
61
67
|
k *= c2
|
|
62
68
|
|
|
63
69
|
h = h ^ k
|
|
64
70
|
h = WasmI32.rotl(h, r2)
|
|
65
|
-
h =
|
|
71
|
+
h = h * m + n
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@unsafe
|
|
75
|
+
let hash64 = k => {
|
|
76
|
+
// convenience function for hashing 64-bit values
|
|
77
|
+
hash32(WasmI32.wrapI64(k))
|
|
78
|
+
hash32(WasmI32.wrapI64(WasmI64.shrU(k, 32N)))
|
|
66
79
|
}
|
|
67
80
|
|
|
68
|
-
|
|
81
|
+
@unsafe
|
|
82
|
+
let hashRemaining = r => {
|
|
69
83
|
// Note: wasm is little-endian so no swap is necessary
|
|
70
84
|
|
|
71
85
|
let mut r = r * c1
|
|
@@ -75,25 +89,31 @@ let hashRemaining = (r) => {
|
|
|
75
89
|
h = h ^ r
|
|
76
90
|
}
|
|
77
91
|
|
|
78
|
-
|
|
92
|
+
@unsafe
|
|
93
|
+
let finalize = len => {
|
|
79
94
|
h = h ^ len
|
|
80
95
|
|
|
81
|
-
h = h ^
|
|
96
|
+
h = h ^ h >>> 16n
|
|
82
97
|
h *= 0x85ebca6bn
|
|
83
|
-
h = h ^
|
|
98
|
+
h = h ^ h >>> 13n
|
|
84
99
|
h *= 0xc2b2ae35n
|
|
85
|
-
h = h ^
|
|
100
|
+
h = h ^ h >>> 16n
|
|
86
101
|
}
|
|
87
102
|
|
|
103
|
+
@unsafe
|
|
88
104
|
let rec hashOne = (val, depth) => {
|
|
89
105
|
if (depth > _MAX_HASH_DEPTH) {
|
|
90
106
|
void
|
|
91
107
|
} else if ((val & Tags._GRAIN_NUMBER_TAG_MASK) != 0n) {
|
|
92
108
|
hash32(val)
|
|
93
|
-
} else if (
|
|
109
|
+
} else if (
|
|
110
|
+
(val & Tags._GRAIN_GENERIC_TAG_MASK) == Tags._GRAIN_GENERIC_HEAP_TAG_TYPE
|
|
111
|
+
) {
|
|
94
112
|
let heapPtr = val
|
|
95
113
|
match (WasmI32.load(heapPtr, 0n)) {
|
|
96
|
-
t when
|
|
114
|
+
t when (
|
|
115
|
+
t == Tags._GRAIN_STRING_HEAP_TAG || t == Tags._GRAIN_BYTES_HEAP_TAG
|
|
116
|
+
) => {
|
|
97
117
|
let length = WasmI32.load(heapPtr, 4n)
|
|
98
118
|
let extra = length % 4n
|
|
99
119
|
let l = length - extra
|
|
@@ -108,22 +128,6 @@ let rec hashOne = (val, depth) => {
|
|
|
108
128
|
if (rem != 0n) hashRemaining(rem)
|
|
109
129
|
finalize(length)
|
|
110
130
|
},
|
|
111
|
-
t when t == Tags._GRAIN_CHAR_HEAP_TAG => {
|
|
112
|
-
let word = WasmI32.load(heapPtr, 4n)
|
|
113
|
-
// little-endian byte order
|
|
114
|
-
let byte = word & 0xFFn
|
|
115
|
-
let mut shift = 0n
|
|
116
|
-
if ((byte & 0x80n) == 0x00n) {
|
|
117
|
-
shift = 24n
|
|
118
|
-
} else if ((byte & 0xF0n) == 0xF0n) {
|
|
119
|
-
shift = 0n
|
|
120
|
-
} else if ((byte & 0xE0n) == 0xE0n) {
|
|
121
|
-
shift = 8n
|
|
122
|
-
} else {
|
|
123
|
-
shift = 16n
|
|
124
|
-
}
|
|
125
|
-
hash32(word << shift)
|
|
126
|
-
},
|
|
127
131
|
t when t == Tags._GRAIN_ADT_HEAP_TAG => {
|
|
128
132
|
// moduleId
|
|
129
133
|
hash32(WasmI32.load(heapPtr, 4n))
|
|
@@ -185,6 +189,15 @@ let rec hashOne = (val, depth) => {
|
|
|
185
189
|
hash32(WasmI32.load(heapPtr, 8n))
|
|
186
190
|
hash32(WasmI32.load(heapPtr, 12n))
|
|
187
191
|
},
|
|
192
|
+
t when t == Tags._GRAIN_BIGINT_BOXED_NUM_TAG => {
|
|
193
|
+
// TODO(#1187): should include fixint size once implemented
|
|
194
|
+
let size = BI.getSize(heapPtr)
|
|
195
|
+
hash32(size)
|
|
196
|
+
hash32(BI.getFlags(heapPtr))
|
|
197
|
+
for (let mut i = 0n; i < size; i += 1n) {
|
|
198
|
+
hash64(BI.getLimb(heapPtr, i))
|
|
199
|
+
}
|
|
200
|
+
},
|
|
188
201
|
t when t == Tags._GRAIN_FLOAT32_BOXED_NUM_TAG => {
|
|
189
202
|
hash32(WasmI32.load(heapPtr, 8n))
|
|
190
203
|
},
|
|
@@ -193,25 +206,20 @@ let rec hashOne = (val, depth) => {
|
|
|
193
206
|
hash32(WasmI32.load(heapPtr, 12n))
|
|
194
207
|
},
|
|
195
208
|
t when t == Tags._GRAIN_RATIONAL_BOXED_NUM_TAG => {
|
|
196
|
-
|
|
197
|
-
|
|
209
|
+
hashOne(WasmI32.load(heapPtr, 8n), depth + 1n)
|
|
210
|
+
hashOne(WasmI32.load(heapPtr, 12n), depth + 1n)
|
|
198
211
|
},
|
|
199
212
|
_ => {
|
|
200
213
|
hash32(heapPtr)
|
|
201
|
-
}
|
|
214
|
+
},
|
|
202
215
|
}
|
|
203
216
|
},
|
|
204
217
|
_ => {
|
|
205
218
|
hash32(heapPtr)
|
|
206
|
-
}
|
|
219
|
+
},
|
|
207
220
|
}
|
|
208
|
-
} else if (val == WasmI32.fromGrain(true)) {
|
|
209
|
-
hash32(val)
|
|
210
|
-
} else if (val == WasmI32.fromGrain(false)) {
|
|
211
|
-
hash32(val)
|
|
212
|
-
} else if (val == WasmI32.fromGrain(void)) {
|
|
213
|
-
hash32(val)
|
|
214
221
|
} else {
|
|
222
|
+
// Handle non-heap values: booleans, chars, void, etc.
|
|
215
223
|
hash32(val)
|
|
216
224
|
}
|
|
217
225
|
}
|
|
@@ -227,7 +235,8 @@ let rec hashOne = (val, depth) => {
|
|
|
227
235
|
*
|
|
228
236
|
* @since v0.1.0
|
|
229
237
|
*/
|
|
230
|
-
|
|
238
|
+
@unsafe
|
|
239
|
+
export let hash = anything => {
|
|
231
240
|
h = seed
|
|
232
241
|
|
|
233
242
|
hashOne(WasmI32.fromGrain(anything), 0n)
|
|
@@ -235,10 +244,5 @@ export let rec hash = (anything) => {
|
|
|
235
244
|
|
|
236
245
|
// Tag the number on the way out.
|
|
237
246
|
// Since Grain has proper modulus, negative numbers are okay.
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
Memory.decRef(WasmI32.fromGrain(hash))
|
|
241
|
-
Memory.decRef(WasmI32.fromGrain(anything))
|
|
242
|
-
|
|
243
|
-
result
|
|
247
|
+
tagSimpleNumber(h)
|
|
244
248
|
}
|