@grain/stdlib 0.5.13 → 0.6.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 (155) hide show
  1. package/CHANGELOG.md +193 -0
  2. package/LICENSE +1 -1
  3. package/README.md +25 -2
  4. package/array.gr +1512 -199
  5. package/array.md +2032 -94
  6. package/bigint.gr +239 -140
  7. package/bigint.md +450 -106
  8. package/buffer.gr +595 -102
  9. package/buffer.md +903 -145
  10. package/bytes.gr +401 -110
  11. package/bytes.md +551 -63
  12. package/char.gr +228 -49
  13. package/char.md +373 -7
  14. package/exception.gr +26 -12
  15. package/exception.md +29 -5
  16. package/float32.gr +130 -109
  17. package/float32.md +185 -57
  18. package/float64.gr +112 -99
  19. package/float64.md +185 -57
  20. package/hash.gr +47 -37
  21. package/hash.md +21 -3
  22. package/int16.gr +430 -0
  23. package/int16.md +618 -0
  24. package/int32.gr +200 -269
  25. package/int32.md +254 -289
  26. package/int64.gr +142 -225
  27. package/int64.md +254 -289
  28. package/int8.gr +511 -0
  29. package/int8.md +786 -0
  30. package/json.gr +2084 -0
  31. package/json.md +608 -0
  32. package/list.gr +120 -68
  33. package/list.md +125 -80
  34. package/map.gr +560 -57
  35. package/map.md +672 -56
  36. package/marshal.gr +239 -227
  37. package/marshal.md +36 -4
  38. package/number.gr +626 -676
  39. package/number.md +738 -153
  40. package/option.gr +33 -35
  41. package/option.md +58 -42
  42. package/package.json +2 -2
  43. package/path.gr +148 -187
  44. package/path.md +47 -96
  45. package/pervasives.gr +75 -416
  46. package/pervasives.md +85 -180
  47. package/priorityqueue.gr +433 -74
  48. package/priorityqueue.md +422 -54
  49. package/queue.gr +362 -80
  50. package/queue.md +433 -38
  51. package/random.gr +67 -75
  52. package/random.md +68 -40
  53. package/range.gr +135 -63
  54. package/range.md +198 -43
  55. package/rational.gr +284 -0
  56. package/rational.md +545 -0
  57. package/regex.gr +933 -1066
  58. package/regex.md +59 -60
  59. package/result.gr +23 -25
  60. package/result.md +54 -39
  61. package/runtime/atof/common.gr +78 -82
  62. package/runtime/atof/common.md +22 -10
  63. package/runtime/atof/decimal.gr +102 -127
  64. package/runtime/atof/decimal.md +28 -7
  65. package/runtime/atof/lemire.gr +56 -71
  66. package/runtime/atof/lemire.md +9 -1
  67. package/runtime/atof/parse.gr +83 -110
  68. package/runtime/atof/parse.md +12 -2
  69. package/runtime/atof/slow.gr +28 -35
  70. package/runtime/atof/slow.md +9 -1
  71. package/runtime/atof/table.gr +19 -18
  72. package/runtime/atof/table.md +10 -2
  73. package/runtime/atoi/parse.gr +153 -136
  74. package/runtime/atoi/parse.md +50 -1
  75. package/runtime/bigint.gr +410 -517
  76. package/runtime/bigint.md +71 -57
  77. package/runtime/compare.gr +176 -85
  78. package/runtime/compare.md +31 -1
  79. package/runtime/dataStructures.gr +144 -32
  80. package/runtime/dataStructures.md +267 -31
  81. package/runtime/debugPrint.gr +34 -15
  82. package/runtime/debugPrint.md +37 -5
  83. package/runtime/equal.gr +53 -52
  84. package/runtime/equal.md +30 -1
  85. package/runtime/exception.gr +38 -47
  86. package/runtime/exception.md +10 -8
  87. package/runtime/gc.gr +23 -152
  88. package/runtime/gc.md +13 -17
  89. package/runtime/malloc.gr +31 -31
  90. package/runtime/malloc.md +11 -3
  91. package/runtime/numberUtils.gr +191 -172
  92. package/runtime/numberUtils.md +17 -9
  93. package/runtime/numbers.gr +1695 -1021
  94. package/runtime/numbers.md +1098 -134
  95. package/runtime/string.gr +540 -242
  96. package/runtime/string.md +76 -6
  97. package/runtime/unsafe/constants.gr +30 -13
  98. package/runtime/unsafe/constants.md +80 -0
  99. package/runtime/unsafe/conv.gr +55 -28
  100. package/runtime/unsafe/conv.md +41 -9
  101. package/runtime/unsafe/memory.gr +10 -30
  102. package/runtime/unsafe/memory.md +15 -19
  103. package/runtime/unsafe/tags.gr +37 -21
  104. package/runtime/unsafe/tags.md +88 -8
  105. package/runtime/unsafe/wasmf32.gr +30 -36
  106. package/runtime/unsafe/wasmf32.md +64 -56
  107. package/runtime/unsafe/wasmf64.gr +30 -36
  108. package/runtime/unsafe/wasmf64.md +64 -56
  109. package/runtime/unsafe/wasmi32.gr +49 -66
  110. package/runtime/unsafe/wasmi32.md +102 -94
  111. package/runtime/unsafe/wasmi64.gr +52 -79
  112. package/runtime/unsafe/wasmi64.md +108 -100
  113. package/runtime/utils/printing.gr +13 -15
  114. package/runtime/utils/printing.md +11 -3
  115. package/runtime/wasi.gr +294 -295
  116. package/runtime/wasi.md +62 -42
  117. package/set.gr +574 -64
  118. package/set.md +634 -54
  119. package/stack.gr +181 -64
  120. package/stack.md +271 -42
  121. package/string.gr +453 -533
  122. package/string.md +241 -151
  123. package/uint16.gr +369 -0
  124. package/uint16.md +585 -0
  125. package/uint32.gr +470 -0
  126. package/uint32.md +737 -0
  127. package/uint64.gr +471 -0
  128. package/uint64.md +737 -0
  129. package/uint8.gr +369 -0
  130. package/uint8.md +585 -0
  131. package/uri.gr +1093 -0
  132. package/uri.md +477 -0
  133. package/{sys → wasi}/file.gr +914 -500
  134. package/{sys → wasi}/file.md +454 -50
  135. package/wasi/process.gr +292 -0
  136. package/{sys → wasi}/process.md +164 -6
  137. package/wasi/random.gr +77 -0
  138. package/wasi/random.md +80 -0
  139. package/{sys → wasi}/time.gr +15 -22
  140. package/{sys → wasi}/time.md +5 -5
  141. package/immutablearray.gr +0 -929
  142. package/immutablearray.md +0 -1038
  143. package/immutablemap.gr +0 -493
  144. package/immutablemap.md +0 -479
  145. package/immutablepriorityqueue.gr +0 -360
  146. package/immutablepriorityqueue.md +0 -291
  147. package/immutableset.gr +0 -498
  148. package/immutableset.md +0 -449
  149. package/runtime/debug.gr +0 -2
  150. package/runtime/debug.md +0 -6
  151. package/runtime/unsafe/errors.gr +0 -36
  152. package/runtime/unsafe/errors.md +0 -204
  153. package/sys/process.gr +0 -254
  154. package/sys/random.gr +0 -79
  155. package/sys/random.md +0 -66
@@ -1,5 +1,3 @@
1
- /* grainc-flags --no-pervasives */
2
-
3
1
  // This module was based on Rust's dec2flt
4
2
  // https://github.com/rust-lang/rust/blob/1cbc45942d5c0f6eb5d94e3b10762ba541958035/library/core/src/num/dec2flt/decimal.rs
5
3
  // Rust's MIT license is provided below:
@@ -13,11 +11,11 @@
13
11
  * the Software, and to permit persons to whom the Software
14
12
  * is furnished to do so, subject to the following
15
13
  * conditions:
16
- *
14
+ *
17
15
  * The above copyright notice and this permission notice
18
16
  * shall be included in all copies or substantial portions
19
17
  * of the Software.
20
- *
18
+ *
21
19
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
22
20
  * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
23
21
  * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
@@ -28,13 +26,17 @@
28
26
  * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29
27
  * DEALINGS IN THE SOFTWARE.
30
28
  */
29
+ @noPervasives
30
+ module Decimal
31
31
 
32
- import WasmI32 from "runtime/unsafe/wasmi32"
33
- import WasmI64 from "runtime/unsafe/wasmi64"
34
- import Memory from "runtime/unsafe/memory"
35
- import { newInt32, allocateBytes } from "runtime/dataStructures"
32
+ from "runtime/unsafe/wasmi32" include WasmI32
33
+ from "runtime/unsafe/wasmi64" include WasmI64
34
+ from "runtime/unsafe/memory" include Memory
35
+ from "runtime/dataStructures" include DataStructures
36
+ use DataStructures.{ newInt32, allocateBytes }
36
37
 
37
- import {
38
+ from "runtime/atof/common" include Common
39
+ use Common.{
38
40
  _CHAR_CODE_UNDERSCORE,
39
41
  _CHAR_CODE_PLUS,
40
42
  _CHAR_CODE_MINUS,
@@ -43,20 +45,28 @@ import {
43
45
  _CHAR_CODE_e,
44
46
  _CHAR_CODE_DOT,
45
47
  is8Digits,
46
- } from "./common"
48
+ }
47
49
 
48
- primitive (&&): (Bool, Bool) -> Bool = "@and"
49
- primitive (||): (Bool, Bool) -> Bool = "@or"
50
- primitive (!): Bool -> Bool = "@not"
50
+ primitive (&&) = "@and"
51
+ primitive (||) = "@or"
52
+ primitive (!) = "@not"
51
53
 
52
- export record Decimal {
53
- // The number of significant digits in the decimal.
54
+ provide record Decimal {
55
+ /**
56
+ * The number of significant digits in the decimal.
57
+ */
54
58
  mut numDigits: Int32,
55
- // The offset of the decimal point in the significant digits.
59
+ /**
60
+ * The offset of the decimal point in the significant digits.
61
+ */
56
62
  mut decimalPoint: Int32,
57
- // If the number of significant digits stored in the decimal is truncated.
63
+ /**
64
+ * If the number of significant digits stored in the decimal is truncated.
65
+ */
58
66
  mut truncated: Bool,
59
- // Buffer of the raw digits, in the range [0, 9].
67
+ /**
68
+ * Buffer of the raw digits, in the range [0, 9].
69
+ */
60
70
  digits: Bytes,
61
71
  }
62
72
 
@@ -93,35 +103,33 @@ let _MAX_DIGITS = 768n
93
103
  @unsafe
94
104
  let _MAX_DIGITS_WITHOUT_OVERFLOW = 19n
95
105
  @unsafe
96
- export let _DECIMAL_POINT_RANGE = 2047n
106
+ provide let _DECIMAL_POINT_RANGE = 2047n
97
107
 
98
108
  @unsafe
99
109
  let new = () => {
110
+ use WasmI32.{ (+) }
100
111
  let digits = allocateBytes(_MAX_DIGITS)
101
- Memory.fill(WasmI32.add(digits, 8n), 0n, _MAX_DIGITS)
112
+ Memory.fill(digits + 8n, 0n, _MAX_DIGITS)
102
113
  let digits = WasmI32.toGrain(digits)
103
114
  { numDigits: 0l, decimalPoint: 0l, truncated: false, digits }
104
115
  }
105
116
 
106
117
  // Append a digit to the buffer.
107
118
  @unsafe
108
- export let tryAddDigit = (d, digit) => {
109
- let (+) = WasmI32.add
110
- let numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 8n)
119
+ provide let tryAddDigit = (d, digit) => {
120
+ use WasmI32.{ (+) }
121
+ let numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 4n)
111
122
  if (WasmI32.ltU(numDigits, _MAX_DIGITS)) {
112
123
  let digits = WasmI32.fromGrain(d.digits)
113
124
  WasmI32.store8(digits + numDigits, digit, 8n)
114
125
  }
115
- d.numDigits = WasmI32.toGrain(newInt32(WasmI32.add(numDigits, 1n)))
126
+ d.numDigits = WasmI32.toGrain(newInt32(numDigits + 1n))
116
127
  }
117
128
 
118
129
  // Trim trailing zeros from the buffer.
119
130
  @unsafe
120
131
  let trim = d => {
121
- let (!=) = WasmI32.ne
122
- let (==) = WasmI32.eq
123
- let (+) = WasmI32.add
124
- let (-) = WasmI32.sub
132
+ use WasmI32.{ (+), (-), (==), (!=) }
125
133
  // Calls to `trim` in this module are fine because:
126
134
  //
127
135
  // 1. `parseDecimal` sets `numDigits` to a max of `_MAX_DIGITS`.
@@ -130,7 +138,7 @@ let trim = d => {
130
138
  //
131
139
  // Trim is only called in `rightShift` and `leftShift`.
132
140
  let digits = WasmI32.fromGrain(d.digits)
133
- let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 8n)
141
+ let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 4n)
134
142
  while (
135
143
  numDigits != 0n &&
136
144
  WasmI32.eqz(WasmI32.load8U(digits + (numDigits - 1n), 8n))
@@ -141,18 +149,12 @@ let trim = d => {
141
149
  }
142
150
 
143
151
  @unsafe
144
- export let round = d => {
145
- let (!=) = WasmI32.ne
146
- let (==) = WasmI32.eq
147
- let (+) = WasmI32.add
148
- let (-) = WasmI32.sub
149
- let (>) = WasmI32.gtS
150
- let (>=) = WasmI32.geS
151
- let (<) = WasmI32.ltS
152
- let (&) = WasmI32.and
152
+ provide let round = d => {
153
+ use WasmI32.{ (+), (-), (&), (<), (>), (>=), (==), (!=) }
154
+ use WasmI64.{ (+) as addWasmI64, (*) }
153
155
  let digits = WasmI32.fromGrain(d.digits)
154
- let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 8n)
155
- let mut decimalPoint = WasmI32.load(WasmI32.fromGrain(d.decimalPoint), 8n)
156
+ let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 4n)
157
+ let mut decimalPoint = WasmI32.load(WasmI32.fromGrain(d.decimalPoint), 4n)
156
158
  if (numDigits == 0n || decimalPoint < 0n) {
157
159
  0N
158
160
  } else if (decimalPoint > 18n) {
@@ -161,9 +163,9 @@ export let round = d => {
161
163
  let dp = decimalPoint
162
164
  let mut n = 0_N
163
165
  for (let mut i = 0n; i < dp; i += 1n) {
164
- n = WasmI64.mul(n, 10N)
166
+ n *= 10N
165
167
  if (i < numDigits) {
166
- n = WasmI64.add(n, WasmI64.extendI32U(WasmI32.load8U(digits + i, 8n)))
168
+ n = addWasmI64(n, WasmI64.extendI32U(WasmI32.load8U(digits + i, 8n)))
167
169
  }
168
170
  }
169
171
  let mut roundUp = false
@@ -176,7 +178,7 @@ export let round = d => {
176
178
  }
177
179
  }
178
180
  if (roundUp) {
179
- n = WasmI64.add(n, 1N)
181
+ n = addWasmI64(n, 1N)
180
182
  }
181
183
  n
182
184
  }
@@ -186,8 +188,8 @@ export let round = d => {
186
188
  let mut _TABLE = -1n
187
189
 
188
190
  @unsafe
189
- export let get_TABLE = () => {
190
- let (==) = WasmI32.eq
191
+ provide let get_TABLE = () => {
192
+ use WasmI32.{ (==) }
191
193
  if (_TABLE == -1n) {
192
194
  _TABLE = Memory.malloc(130n)
193
195
  WasmI32.store16(_TABLE, 0x0000n, 0n)
@@ -263,8 +265,8 @@ export let get_TABLE = () => {
263
265
  let mut _TABLE_POW5 = -1n
264
266
 
265
267
  @unsafe
266
- export let get_TABLE_POW5 = () => {
267
- let (==) = WasmI32.eq
268
+ provide let get_TABLE_POW5 = () => {
269
+ use WasmI32.{ (==) }
268
270
  // formatter-ignore
269
271
  if (_TABLE_POW5 == -1n) {
270
272
  _TABLE_POW5 = Memory.malloc(0x051Cn)
@@ -318,25 +320,18 @@ export let get_TABLE_POW5 = () => {
318
320
 
319
321
  @unsafe
320
322
  let numberOfDigitsDecimalLeftShift = (d, shift) => {
321
- let (+) = WasmI32.add
322
- let (-) = WasmI32.sub
323
- let (&) = WasmI32.and
324
- let (<) = WasmI32.ltU
325
- let (>=) = WasmI32.geU
326
- let (>>) = WasmI32.shrU
327
- let (<<) = WasmI32.shl
328
- let (==) = WasmI32.eq
323
+ use WasmI32.{ (+), (-), (&), ltU as (<), geU as (>=), (==), (>>>), (<<) }
329
324
 
330
325
  let table = get_TABLE()
331
326
  let tablePow5 = get_TABLE_POW5()
332
327
 
333
328
  let digits = WasmI32.fromGrain(d.digits)
334
- let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 8n)
329
+ let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 4n)
335
330
 
336
331
  let shift = (shift & 63n) << 1n
337
332
  let x_a = WasmI32.load16U(table + shift, 0n)
338
333
  let x_b = WasmI32.load16U(table + shift, 2n)
339
- let mut numNewDigits = x_a >> 11n
334
+ let mut numNewDigits = x_a >>> 11n
340
335
  let pow5_a = 0x7FFn & x_a
341
336
  let pow5_b = 0x7FFn & x_b
342
337
  let offset = pow5_a
@@ -360,23 +355,21 @@ let numberOfDigitsDecimalLeftShift = (d, shift) => {
360
355
 
361
356
  // Computes decimal * 2^shift.
362
357
  @unsafe
363
- export let leftShift = (d, shift) => {
364
- let (+) = WasmI32.add
365
- let (-) = WasmI32.sub
366
- let (&) = WasmI32.and
367
- let (<) = WasmI32.ltS
368
- let (>) = WasmI32.gtS
369
- let (>=) = WasmI32.geS
370
- let (==) = WasmI32.eq
371
- let (!=) = WasmI32.ne
358
+ provide let leftShift = (d, shift) => {
359
+ use WasmI32.{ (+), (-), (&), (<), (>=), (==), (!=) }
372
360
 
373
- let (*) = WasmI64.mul
374
- let (/) = WasmI64.divU
375
- let (<<) = WasmI64.shl
361
+ use WasmI64.{
362
+ (+) as addWasmI64,
363
+ (-) as subWasmI64,
364
+ (*),
365
+ divU as (/),
366
+ (<<),
367
+ (>),
368
+ }
376
369
 
377
370
  let digits = WasmI32.fromGrain(d.digits)
378
- let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 8n)
379
- let mut decimalPoint = WasmI32.load(WasmI32.fromGrain(d.decimalPoint), 8n)
371
+ let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 4n)
372
+ let mut decimalPoint = WasmI32.load(WasmI32.fromGrain(d.decimalPoint), 4n)
380
373
 
381
374
  if (numDigits != 0n) {
382
375
  let numNewDigits = numberOfDigitsDecimalLeftShift(d, shift)
@@ -386,32 +379,33 @@ export let leftShift = (d, shift) => {
386
379
  while (readIndex != 0n) {
387
380
  readIndex -= 1n
388
381
  writeIndex -= 1n
389
- n = WasmI64.add(
382
+ n = addWasmI64(
390
383
  n,
391
384
  WasmI64.extendI32U(WasmI32.load8U(digits + readIndex, 8n)) <<
392
- WasmI64.extendI32U(shift)
385
+ WasmI64.extendI32U(shift)
393
386
  )
394
387
  let quotient = n / 10N
395
- let remainder = WasmI64.sub(n, 10N * quotient)
388
+ let remainder = subWasmI64(n, 10N * quotient)
396
389
  if (writeIndex < _MAX_DIGITS) {
397
390
  WasmI32.store8(digits + writeIndex, WasmI32.wrapI64(remainder), 8n)
398
- } else if (WasmI64.gtS(remainder, 0N)) {
391
+ } else if (remainder > 0N) {
399
392
  d.truncated = true
400
393
  }
401
394
  n = quotient
402
395
  }
403
- while (WasmI64.gtS(n, 0N)) {
396
+ while (n > 0N) {
404
397
  writeIndex -= 1n
405
398
  let quotient = n / 10N
406
- let remainder = WasmI64.sub(n, 10N * quotient)
399
+ let remainder = subWasmI64(n, 10N * quotient)
407
400
  if (writeIndex < _MAX_DIGITS) {
408
401
  WasmI32.store8(digits + writeIndex, WasmI32.wrapI64(remainder), 8n)
409
- } else if (WasmI64.gtS(remainder, 0N)) {
402
+ } else if (remainder > 0N) {
410
403
  d.truncated = true
411
404
  }
412
405
  n = quotient
413
406
  }
414
407
  numDigits += numNewDigits
408
+ use WasmI32.{ (>) }
415
409
  if (numDigits > _MAX_DIGITS) {
416
410
  numDigits = _MAX_DIGITS
417
411
  }
@@ -425,31 +419,22 @@ export let leftShift = (d, shift) => {
425
419
 
426
420
  // Computes decimal * 2^-shift.
427
421
  @unsafe
428
- export let rightShift = (d, shift) => {
429
- let (+) = WasmI32.add
430
- let (-) = WasmI32.sub
431
- let (&) = WasmI32.and
432
- let (<) = WasmI32.ltS
433
- let (>) = WasmI32.gtS
434
- let (>=) = WasmI32.geS
435
- let (==) = WasmI32.eq
436
- let (!=) = WasmI32.ne
422
+ provide let rightShift = (d, shift) => {
423
+ use WasmI32.{ (+), (-), (&), (<), (>), (>=), (==), (!=) }
437
424
 
438
- let (<<) = WasmI64.shl
439
- let (>>) = WasmI64.shrU
440
- let (*) = WasmI64.mul
425
+ use WasmI64.{ (+) as addWasmI64, (-) as subWasmI64, (*), (&), (<<), (>>>) }
441
426
 
442
427
  let digits = WasmI32.fromGrain(d.digits)
443
- let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 8n)
444
- let mut decimalPoint = WasmI32.load(WasmI32.fromGrain(d.decimalPoint), 8n)
428
+ let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 4n)
429
+ let mut decimalPoint = WasmI32.load(WasmI32.fromGrain(d.decimalPoint), 4n)
445
430
 
446
431
  let mut readIndex = 0n
447
432
  let mut writeIndex = 0n
448
433
  let mut n = 0N
449
434
  let mut done = false
450
- while (WasmI64.eqz(n >> WasmI64.extendI32U(shift))) {
435
+ while (WasmI64.eqz(n >>> WasmI64.extendI32U(shift))) {
451
436
  if (readIndex < numDigits) {
452
- n = WasmI64.add(
437
+ n = addWasmI64(
453
438
  10N * n,
454
439
  WasmI64.extendI32U(WasmI32.load8U(digits + readIndex, 8n))
455
440
  )
@@ -458,7 +443,7 @@ export let rightShift = (d, shift) => {
458
443
  done = true
459
444
  break
460
445
  } else {
461
- while (WasmI64.eqz(n >> WasmI64.extendI32U(shift))) {
446
+ while (WasmI64.eqz(n >>> WasmI64.extendI32U(shift))) {
462
447
  n *= 10N
463
448
  readIndex += 1n
464
449
  }
@@ -475,11 +460,11 @@ export let rightShift = (d, shift) => {
475
460
  d.numDigits = WasmI32.toGrain(newInt32(numDigits))
476
461
  d.decimalPoint = WasmI32.toGrain(newInt32(decimalPoint))
477
462
  } else {
478
- let mask = WasmI64.sub(1N << WasmI64.extendI32U(shift), 1N)
463
+ let mask = subWasmI64(1N << WasmI64.extendI32U(shift), 1N)
479
464
  while (readIndex < numDigits) {
480
- let newDigit = n >> WasmI64.extendI32U(shift)
481
- n = WasmI64.add(
482
- 10N * WasmI64.and(n, mask),
465
+ let newDigit = n >>> WasmI64.extendI32U(shift)
466
+ n = addWasmI64(
467
+ 10N * (n & mask),
483
468
  WasmI64.extendI32U(WasmI32.load8U(digits + readIndex, 8n))
484
469
  )
485
470
  readIndex += 1n
@@ -487,12 +472,13 @@ export let rightShift = (d, shift) => {
487
472
  writeIndex += 1n
488
473
  }
489
474
  while (WasmI64.gtU(n, 0N)) {
490
- let newDigit = n >> WasmI64.extendI32U(shift)
491
- n = 10N * WasmI64.and(n, mask)
475
+ use WasmI64.{ (>) }
476
+ let newDigit = n >>> WasmI64.extendI32U(shift)
477
+ n = 10N * (n & mask)
492
478
  if (writeIndex < _MAX_DIGITS) {
493
479
  WasmI32.store8(digits + writeIndex, WasmI32.wrapI64(newDigit), 8n)
494
480
  writeIndex += 1n
495
- } else if (WasmI64.gtS(newDigit, 0N)) {
481
+ } else if (newDigit > 0N) {
496
482
  d.truncated = true
497
483
  }
498
484
  }
@@ -507,16 +493,8 @@ export let rightShift = (d, shift) => {
507
493
 
508
494
  // Parse a big integer representation of the float as a decimal.
509
495
  @unsafe
510
- export let parseDecimal = (s: String) => {
511
- let (+) = WasmI32.add
512
- let (*) = WasmI32.mul
513
- let (-) = WasmI32.sub
514
- let (&) = WasmI32.and
515
- let (<) = WasmI32.ltS
516
- let (>) = WasmI32.gtS
517
- let (>=) = WasmI32.geS
518
- let (==) = WasmI32.eq
519
- let (!=) = WasmI32.ne
496
+ provide let parseDecimal = (s: String) => {
497
+ use WasmI32.{ (+), (-), (*), (&), (<), (>), (>=), (==), (!=) }
520
498
 
521
499
  let d = new()
522
500
  let s = WasmI32.fromGrain(s)
@@ -552,7 +530,7 @@ export let parseDecimal = (s: String) => {
552
530
  let c = WasmI32.load8U(s + i, 8n)
553
531
  if (c == _CHAR_CODE_DOT) {
554
532
  i += 1n
555
- let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 8n)
533
+ let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 4n)
556
534
  let numDigitsBeforeDecimal = numDigits
557
535
  // Skip leading zeros.
558
536
  if (numDigits == 0n) {
@@ -566,15 +544,12 @@ export let parseDecimal = (s: String) => {
566
544
  }
567
545
  }
568
546
  while (len - i >= 8n && numDigits + 8n < _MAX_DIGITS) {
547
+ use WasmI64.{ (-) }
569
548
  let v = WasmI64.load(s + i, 0n)
570
549
  if (!is8Digits(v)) {
571
550
  break
572
551
  }
573
- WasmI64.store(
574
- digits + numDigits,
575
- WasmI64.sub(v, 0x3030_3030_3030_3030N),
576
- 8n
577
- )
552
+ WasmI64.store(digits + numDigits, v - 0x3030_3030_3030_3030N, 8n)
578
553
  numDigits += 8n
579
554
  i += 8n
580
555
  }
@@ -591,12 +566,12 @@ export let parseDecimal = (s: String) => {
591
566
  break
592
567
  }
593
568
  }
594
- numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 8n)
569
+ numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 4n)
595
570
  d.decimalPoint = WasmI32.toGrain(
596
571
  newInt32(numDigitsBeforeDecimal - numDigits)
597
572
  )
598
573
  }
599
- let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 8n)
574
+ let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 4n)
600
575
  if (numDigits != 0n) {
601
576
  // Ignore the trailing zeros if there are any
602
577
  let mut nTrailingZeros = 0n
@@ -610,7 +585,7 @@ export let parseDecimal = (s: String) => {
610
585
  break
611
586
  }
612
587
  }
613
- let mut decimalPoint = WasmI32.load(WasmI32.fromGrain(d.decimalPoint), 8n)
588
+ let mut decimalPoint = WasmI32.load(WasmI32.fromGrain(d.decimalPoint), 4n)
614
589
  decimalPoint += nTrailingZeros
615
590
  numDigits -= nTrailingZeros
616
591
  decimalPoint += numDigits
@@ -647,15 +622,15 @@ export let parseDecimal = (s: String) => {
647
622
  break
648
623
  }
649
624
  }
650
- let mut decimalPoint = WasmI32.load(WasmI32.fromGrain(d.decimalPoint), 8n)
625
+ let mut decimalPoint = WasmI32.load(WasmI32.fromGrain(d.decimalPoint), 4n)
651
626
  decimalPoint += if (negExp) {
652
- 0n - expNum
653
- } else {
654
- expNum
655
- }
627
+ 0n - expNum
628
+ } else {
629
+ expNum
630
+ }
656
631
  d.decimalPoint = WasmI32.toGrain(newInt32(decimalPoint))
657
632
  }
658
- let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 8n)
633
+ let mut numDigits = WasmI32.load(WasmI32.fromGrain(d.numDigits), 4n)
659
634
  for (let mut i = numDigits; i < _MAX_DIGITS_WITHOUT_OVERFLOW; i += 1n) {
660
635
  WasmI32.store8(digits + i, 0n, 8n)
661
636
  }
@@ -1,3 +1,11 @@
1
+ ---
2
+ title: Decimal
3
+ ---
4
+
5
+ ## Types
6
+
7
+ Type declarations included in the Decimal module.
8
+
1
9
  ### Decimal.**Decimal**
2
10
 
3
11
  ```grain
@@ -9,6 +17,19 @@ record Decimal {
9
17
  }
10
18
  ```
11
19
 
20
+ Fields:
21
+
22
+ |name|type|description|
23
+ |----|----|-----------|
24
+ |`numDigits`|`Int32`|The number of significant digits in the decimal.|
25
+ |`decimalPoint`|`Int32`|The offset of the decimal point in the significant digits.|
26
+ |`truncated`|`Bool`|If the number of significant digits stored in the decimal is truncated.|
27
+ |`digits`|`Bytes`|Buffer of the raw digits, in the range [0, 9].|
28
+
29
+ ## Values
30
+
31
+ Functions and constants included in the Decimal module.
32
+
12
33
  ### Decimal.**_DECIMAL_POINT_RANGE**
13
34
 
14
35
  ```grain
@@ -18,42 +39,42 @@ _DECIMAL_POINT_RANGE : WasmI32
18
39
  ### Decimal.**tryAddDigit**
19
40
 
20
41
  ```grain
21
- tryAddDigit : (Decimal, WasmI32) -> Void
42
+ tryAddDigit : (d: Decimal, digit: WasmI32) => Void
22
43
  ```
23
44
 
24
45
  ### Decimal.**round**
25
46
 
26
47
  ```grain
27
- round : Decimal -> WasmI64
48
+ round : (d: Decimal) => WasmI64
28
49
  ```
29
50
 
30
51
  ### Decimal.**get_TABLE**
31
52
 
32
53
  ```grain
33
- get_TABLE : () -> WasmI32
54
+ get_TABLE : () => WasmI32
34
55
  ```
35
56
 
36
57
  ### Decimal.**get_TABLE_POW5**
37
58
 
38
59
  ```grain
39
- get_TABLE_POW5 : () -> WasmI32
60
+ get_TABLE_POW5 : () => WasmI32
40
61
  ```
41
62
 
42
63
  ### Decimal.**leftShift**
43
64
 
44
65
  ```grain
45
- leftShift : (Decimal, WasmI32) -> Void
66
+ leftShift : (d: Decimal, shift: WasmI32) => Void
46
67
  ```
47
68
 
48
69
  ### Decimal.**rightShift**
49
70
 
50
71
  ```grain
51
- rightShift : (Decimal, WasmI32) -> Void
72
+ rightShift : (d: Decimal, shift: WasmI32) => Void
52
73
  ```
53
74
 
54
75
  ### Decimal.**parseDecimal**
55
76
 
56
77
  ```grain
57
- parseDecimal : String -> Decimal
78
+ parseDecimal : (s: String) => Decimal
58
79
  ```
59
80