@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.
Files changed (97) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/LICENSE +1 -1
  3. package/array.gr +92 -73
  4. package/array.md +18 -18
  5. package/bigint.gr +497 -0
  6. package/bigint.md +811 -0
  7. package/buffer.gr +56 -217
  8. package/buffer.md +24 -17
  9. package/bytes.gr +103 -205
  10. package/bytes.md +19 -0
  11. package/char.gr +152 -166
  12. package/char.md +200 -0
  13. package/exception.md +6 -0
  14. package/float32.gr +159 -82
  15. package/float32.md +315 -0
  16. package/float64.gr +163 -82
  17. package/float64.md +315 -0
  18. package/hash.gr +53 -49
  19. package/int32.gr +479 -230
  20. package/int32.md +937 -0
  21. package/int64.gr +479 -230
  22. package/int64.md +937 -0
  23. package/list.gr +530 -116
  24. package/list.md +1141 -0
  25. package/map.gr +302 -121
  26. package/map.md +525 -0
  27. package/number.gr +51 -57
  28. package/number.md +37 -3
  29. package/option.gr +25 -25
  30. package/option.md +1 -1
  31. package/package.json +3 -3
  32. package/pervasives.gr +504 -52
  33. package/pervasives.md +1116 -0
  34. package/queue.gr +8 -1
  35. package/queue.md +10 -0
  36. package/random.gr +196 -0
  37. package/random.md +179 -0
  38. package/range.gr +26 -26
  39. package/regex.gr +1833 -842
  40. package/regex.md +11 -11
  41. package/result.md +1 -1
  42. package/runtime/bigint.gr +2045 -0
  43. package/runtime/bigint.md +326 -0
  44. package/runtime/dataStructures.gr +99 -279
  45. package/runtime/dataStructures.md +391 -0
  46. package/runtime/debug.gr +0 -1
  47. package/runtime/debug.md +6 -0
  48. package/runtime/equal.gr +40 -37
  49. package/runtime/equal.md +6 -0
  50. package/runtime/exception.gr +28 -15
  51. package/runtime/exception.md +30 -0
  52. package/runtime/gc.gr +50 -20
  53. package/runtime/gc.md +36 -0
  54. package/runtime/malloc.gr +32 -22
  55. package/runtime/malloc.md +55 -0
  56. package/runtime/numberUtils.gr +297 -142
  57. package/runtime/numberUtils.md +54 -0
  58. package/runtime/numbers.gr +1204 -453
  59. package/runtime/numbers.md +300 -0
  60. package/runtime/string.gr +193 -228
  61. package/runtime/string.md +24 -0
  62. package/runtime/stringUtils.gr +62 -38
  63. package/runtime/stringUtils.md +6 -0
  64. package/runtime/unsafe/constants.gr +17 -0
  65. package/runtime/unsafe/constants.md +72 -0
  66. package/runtime/unsafe/conv.gr +10 -10
  67. package/runtime/unsafe/conv.md +71 -0
  68. package/runtime/unsafe/errors.md +204 -0
  69. package/runtime/unsafe/memory.gr +14 -3
  70. package/runtime/unsafe/memory.md +54 -0
  71. package/runtime/unsafe/printWasm.gr +4 -4
  72. package/runtime/unsafe/printWasm.md +24 -0
  73. package/runtime/unsafe/tags.gr +11 -10
  74. package/runtime/unsafe/tags.md +120 -0
  75. package/runtime/unsafe/wasmf32.gr +9 -2
  76. package/runtime/unsafe/wasmf32.md +168 -0
  77. package/runtime/unsafe/wasmf64.gr +9 -2
  78. package/runtime/unsafe/wasmf64.md +168 -0
  79. package/runtime/unsafe/wasmi32.gr +65 -47
  80. package/runtime/unsafe/wasmi32.md +282 -0
  81. package/runtime/unsafe/wasmi64.gr +78 -50
  82. package/runtime/unsafe/wasmi64.md +300 -0
  83. package/runtime/utils/printing.gr +62 -0
  84. package/runtime/utils/printing.md +18 -0
  85. package/runtime/wasi.gr +200 -46
  86. package/runtime/wasi.md +839 -0
  87. package/set.gr +125 -121
  88. package/set.md +24 -21
  89. package/stack.gr +29 -29
  90. package/stack.md +4 -6
  91. package/string.gr +434 -415
  92. package/string.md +3 -3
  93. package/sys/file.gr +477 -482
  94. package/sys/process.gr +33 -47
  95. package/sys/random.gr +48 -20
  96. package/sys/random.md +38 -0
  97. 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
- let hash32 = (k) => {
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 = (h * m) + n
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
- let hashRemaining = (r) => {
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
- let finalize = (len) => {
92
+ @unsafe
93
+ let finalize = len => {
79
94
  h = h ^ len
80
95
 
81
- h = h ^ (h >>> 16n)
96
+ h = h ^ h >>> 16n
82
97
  h *= 0x85ebca6bn
83
- h = h ^ (h >>> 13n)
98
+ h = h ^ h >>> 13n
84
99
  h *= 0xc2b2ae35n
85
- h = h ^ (h >>> 16n)
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 ((val & Tags._GRAIN_GENERIC_TAG_MASK) == Tags._GRAIN_GENERIC_HEAP_TAG_TYPE) {
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 t == Tags._GRAIN_STRING_HEAP_TAG || t == Tags._GRAIN_BYTES_HEAP_TAG => {
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
- hash32(WasmI32.load(heapPtr, 8n))
197
- hash32(WasmI32.load(heapPtr, 12n))
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
- export let rec hash = (anything) => {
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
- let result = tagSimpleNumber(h)
239
-
240
- Memory.decRef(WasmI32.fromGrain(hash))
241
- Memory.decRef(WasmI32.fromGrain(anything))
242
-
243
- result
247
+ tagSimpleNumber(h)
244
248
  }