@grain/stdlib 0.5.0 → 0.5.3

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/string.gr CHANGED
@@ -11,6 +11,7 @@ import Memory from "runtime/unsafe/memory"
11
11
  import Exception from "runtime/exception"
12
12
  import Conv from "runtime/unsafe/conv"
13
13
  import {
14
+ untagSimpleNumber,
14
15
  tagSimpleNumber,
15
16
  tagChar,
16
17
  untagChar,
@@ -100,7 +101,7 @@ export let byteLength = (string: String) => {
100
101
  }
101
102
 
102
103
  /**
103
- * Finds the position of a substring in the input string.
104
+ * Finds the first position of a substring in the input string.
104
105
  *
105
106
  * @param search: The substring to find
106
107
  * @param string: The string to inspect
@@ -161,6 +162,65 @@ export let indexOf = (search: String, string: String) => {
161
162
  }
162
163
  }
163
164
 
165
+ /**
166
+ * Finds the last position of a substring in the input string.
167
+ *
168
+ * @param search: The substring to find
169
+ * @param string: The string to inspect
170
+ * @returns `Some(position)` containing the starting position of the substring if found or `None` otherwise
171
+ *
172
+ * @example String.lastIndexOf("world", "Hello world world") == Some(12)
173
+ *
174
+ * @since v0.5.3
175
+ */
176
+ @unsafe
177
+ export let lastIndexOf = (search: String, string: String) => {
178
+ // The last possible index in the string given the length of the search
179
+ let lastIndex = length(string) - length(search)
180
+
181
+ let (>) = WasmI32.gtU
182
+ let (>=) = WasmI32.geU
183
+ let (==) = WasmI32.eq
184
+ let (!=) = WasmI32.ne
185
+ let (+) = WasmI32.add
186
+ let (-) = WasmI32.sub
187
+ let (&) = WasmI32.and
188
+
189
+ let search = WasmI32.fromGrain(search)
190
+ let string = WasmI32.fromGrain(string)
191
+ let searchSize = WasmI32.load(search, 4n)
192
+ let stringSize = WasmI32.load(string, 4n)
193
+ if (searchSize > stringSize) {
194
+ None
195
+ } else {
196
+ let mut matchIndex = -1n
197
+ let mut stringIndex = untagSimpleNumber(lastIndex)
198
+ let searchPtr = search + 8n
199
+ let stringStartPtr = string + 8n
200
+ for (
201
+ let mut stringPtr = stringStartPtr + stringSize - searchSize;
202
+ stringPtr >= stringStartPtr;
203
+ stringPtr -= 1n
204
+ ) {
205
+ let byte = WasmI32.load8U(stringPtr, 0n)
206
+ if ((byte & 0xC0n) == 0x80n) {
207
+ // We're not at the start of a codepoint, so move on
208
+ continue
209
+ }
210
+ if (Memory.compare(stringPtr, searchPtr, searchSize) == 0n) {
211
+ matchIndex = stringIndex
212
+ break
213
+ }
214
+ stringIndex -= 1n
215
+ }
216
+ if (matchIndex == -1n) {
217
+ None
218
+ } else {
219
+ Some(tagSimpleNumber(matchIndex))
220
+ }
221
+ }
222
+ }
223
+
164
224
  @disableGC
165
225
  let getCodePoint = (ptr: WasmI32) => {
166
226
  // Algorithm from https://encoding.spec.whatwg.org/#utf-8-decoder
@@ -221,19 +281,9 @@ let getCodePoint = (ptr: WasmI32) => {
221
281
  }
222
282
  result
223
283
  }
224
- /**
225
- * Get the character at the position in the input string.
226
- *
227
- * @param position: The position to check
228
- * @param string: The string to search
229
- * @returns The character at the provided position
230
- *
231
- * @example String.charAt(5, "Hello world") == ' '
232
- *
233
- * @since v0.4.0
234
- */
284
+
235
285
  @unsafe
236
- export let charAt = (position, string: String) => {
286
+ let charAtHelp = (position, string: String) => {
237
287
  if (length(string) <= position || position < 0) {
238
288
  fail "Invalid offset: " ++ toString(position)
239
289
  }
@@ -249,10 +299,10 @@ export let charAt = (position, string: String) => {
249
299
  let mut ptr = string + 8n
250
300
  let end = ptr + size
251
301
  let mut counter = 0n
252
- let mut result = WasmI32.toGrain(0n): Char
302
+ let mut result = 0n
253
303
  while (ptr < end) {
254
304
  if (counter == position) {
255
- result = tagChar(getCodePoint(ptr))
305
+ result = getCodePoint(ptr)
256
306
  break
257
307
  }
258
308
  let byte = WasmI32.load8U(ptr, 0n)
@@ -274,6 +324,38 @@ export let charAt = (position, string: String) => {
274
324
  result
275
325
  }
276
326
 
327
+ /**
328
+ * Get the Unicode code point at the position in the input string.
329
+ *
330
+ * @param position: The position to check
331
+ * @param string: The string to search
332
+ * @returns The character code at the provided position
333
+ *
334
+ * @example String.charCodeAt(5, "Hello world") == 32
335
+ *
336
+ * @since v0.5.3
337
+ */
338
+ @unsafe
339
+ export let charCodeAt = (position, string: String) => {
340
+ tagSimpleNumber(charAtHelp(position, string))
341
+ }
342
+
343
+ /**
344
+ * Get the character at the position in the input string.
345
+ *
346
+ * @param position: The position to check
347
+ * @param string: The string to search
348
+ * @returns The character at the provided position
349
+ *
350
+ * @example String.charAt(5, "Hello world") == ' '
351
+ *
352
+ * @since v0.4.0
353
+ */
354
+ @unsafe
355
+ export let charAt = (position, string: String) => {
356
+ tagChar(charAtHelp(position, string))
357
+ }
358
+
277
359
  @unsafe
278
360
  let explodeHelp = (s: String, chars) => {
279
361
  let (>>>) = WasmI32.shrU
package/string.md CHANGED
@@ -148,7 +148,7 @@ No other changes yet.
148
148
  indexOf : (String, String) -> Option<Number>
149
149
  ```
150
150
 
151
- Finds the position of a substring in the input string.
151
+ Finds the first position of a substring in the input string.
152
152
 
153
153
  Parameters:
154
154
 
@@ -169,6 +169,70 @@ Examples:
169
169
  String.indexOf("world", "Hello world") == Some(6)
170
170
  ```
171
171
 
172
+ ### String.**lastIndexOf**
173
+
174
+ <details disabled>
175
+ <summary tabindex="-1">Added in <code>0.5.3</code></summary>
176
+ No other changes yet.
177
+ </details>
178
+
179
+ ```grain
180
+ lastIndexOf : (String, String) -> Option<Number>
181
+ ```
182
+
183
+ Finds the last position of a substring in the input string.
184
+
185
+ Parameters:
186
+
187
+ |param|type|description|
188
+ |-----|----|-----------|
189
+ |`search`|`String`|The substring to find|
190
+ |`string`|`String`|The string to inspect|
191
+
192
+ Returns:
193
+
194
+ |type|description|
195
+ |----|-----------|
196
+ |`Option<Number>`|`Some(position)` containing the starting position of the substring if found or `None` otherwise|
197
+
198
+ Examples:
199
+
200
+ ```grain
201
+ String.lastIndexOf("world", "Hello world world") == Some(12)
202
+ ```
203
+
204
+ ### String.**charCodeAt**
205
+
206
+ <details disabled>
207
+ <summary tabindex="-1">Added in <code>0.5.3</code></summary>
208
+ No other changes yet.
209
+ </details>
210
+
211
+ ```grain
212
+ charCodeAt : (Number, String) -> Number
213
+ ```
214
+
215
+ Get the Unicode code point at the position in the input string.
216
+
217
+ Parameters:
218
+
219
+ |param|type|description|
220
+ |-----|----|-----------|
221
+ |`position`|`Number`|The position to check|
222
+ |`string`|`String`|The string to search|
223
+
224
+ Returns:
225
+
226
+ |type|description|
227
+ |----|-----------|
228
+ |`Number`|The character code at the provided position|
229
+
230
+ Examples:
231
+
232
+ ```grain
233
+ String.charCodeAt(5, "Hello world") == 32
234
+ ```
235
+
172
236
  ### String.**charAt**
173
237
 
174
238
  <details disabled>
package/sys/file.gr CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @module Sys/File: Utilities for accessing the filesystem & working with files.
2
+ * @module File: Utilities for accessing the filesystem & working with files.
3
3
  *
4
4
  * Many of the functions in this module are not intended to be used directly, but rather for other libraries to be built on top of them.
5
5
  *
@@ -36,7 +36,7 @@ import {
36
36
  import List from "list"
37
37
 
38
38
  /**
39
- * @section Types: Type declarations included in the Sys/File module.
39
+ * @section Types: Type declarations included in the File module.
40
40
  */
41
41
 
42
42
  /**
@@ -421,7 +421,7 @@ export record DirectoryEntry {
421
421
  }
422
422
 
423
423
  /**
424
- * @section Values: Functions and constants included in the Sys/File module.
424
+ * @section Values: Functions and constants included in the File module.
425
425
  */
426
426
 
427
427
  /**
package/sys/file.md CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- title: Sys/File
2
+ title: File
3
3
  ---
4
4
 
5
5
  Utilities for accessing the filesystem & working with files.
@@ -12,7 +12,7 @@ import File from "sys/file"
12
12
 
13
13
  ## Types
14
14
 
15
- Type declarations included in the Sys/File module.
15
+ Type declarations included in the File module.
16
16
 
17
17
  ### File.**FileDescriptor**
18
18
 
@@ -173,7 +173,7 @@ An entry in a directory.
173
173
 
174
174
  ## Values
175
175
 
176
- Functions and constants included in the Sys/File module.
176
+ Functions and constants included in the File module.
177
177
 
178
178
  ### File.**stdin**
179
179
 
package/sys/process.gr CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @module Sys/Process: Utilities for accessing functionality and information about the Grain program's process.
2
+ * @module Process: Utilities for accessing functionality and information about the Grain program's process.
3
3
  *
4
4
  * This includes things like accessing environment variables and sending signals.
5
5
  *
@@ -25,7 +25,7 @@ import {
25
25
  } from "runtime/dataStructures"
26
26
 
27
27
  /**
28
- * @section Types: Type declarations included in the Sys/Process module.
28
+ * @section Types: Type declarations included in the Process module.
29
29
  */
30
30
 
31
31
  /**
@@ -91,7 +91,7 @@ export enum Signal {
91
91
  }
92
92
 
93
93
  /**
94
- * @section Values: Functions and constants included in the Sys/Process module.
94
+ * @section Values: Functions and constants included in the Process module.
95
95
  */
96
96
 
97
97
  /**
package/sys/process.md CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- title: Sys/Process
2
+ title: Process
3
3
  ---
4
4
 
5
5
  Utilities for accessing functionality and information about the Grain program's process.
@@ -12,7 +12,7 @@ import Process from "sys/process"
12
12
 
13
13
  ## Types
14
14
 
15
- Type declarations included in the Sys/Process module.
15
+ Type declarations included in the Process module.
16
16
 
17
17
  ### Process.**Signal**
18
18
 
@@ -55,7 +55,7 @@ Signals that can be sent to the host system.
55
55
 
56
56
  ## Values
57
57
 
58
- Functions and constants included in the Sys/Process module.
58
+ Functions and constants included in the Process module.
59
59
 
60
60
  ### Process.**argv**
61
61
 
package/sys/random.gr CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @module Sys/Random: System access to random values.
2
+ * @module Random: System access to random values.
3
3
  *
4
4
  * @example import Random from "sys/random"
5
5
  */
@@ -11,7 +11,7 @@ import Wasi from "runtime/wasi"
11
11
  import { tagSimpleNumber, newInt32, newInt64 } from "runtime/dataStructures"
12
12
 
13
13
  /**
14
- * @section Values: Functions and constants included in the Sys/Random module.
14
+ * @section Values: Functions and constants included in the Random module.
15
15
  */
16
16
 
17
17
  /**
package/sys/random.md CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- title: Sys/Random
2
+ title: Random
3
3
  ---
4
4
 
5
5
  System access to random values.
@@ -10,12 +10,12 @@ import Random from "sys/random"
10
10
 
11
11
  ## Values
12
12
 
13
- Functions and constants included in the Sys/Random module.
13
+ Functions and constants included in the Random module.
14
14
 
15
15
  ### Random.**randomInt32**
16
16
 
17
17
  <details disabled>
18
- <summary tabindex="-1">Added in <code>next</code></summary>
18
+ <summary tabindex="-1">Added in <code>0.5.0</code></summary>
19
19
  No other changes yet.
20
20
  </details>
21
21
 
@@ -34,7 +34,7 @@ Returns:
34
34
  ### Random.**randomInt64**
35
35
 
36
36
  <details disabled>
37
- <summary tabindex="-1">Added in <code>next</code></summary>
37
+ <summary tabindex="-1">Added in <code>0.5.0</code></summary>
38
38
  No other changes yet.
39
39
  </details>
40
40
 
package/sys/time.gr CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @module Sys/Time: Access to system clocks.
2
+ * @module Time: Access to system clocks.
3
3
  *
4
4
  * @example import Time from "sys/time"
5
5
  */
@@ -15,7 +15,7 @@ import Errors from "runtime/unsafe/errors"
15
15
  import { allocateInt64, tagSimpleNumber } from "runtime/dataStructures"
16
16
 
17
17
  /**
18
- * @section Values: Functions and constants included in the Sys/Time module.
18
+ * @section Values: Functions and constants included in the Time module.
19
19
  */
20
20
 
21
21
  @unsafe
package/sys/time.md CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- title: Sys/Time
2
+ title: Time
3
3
  ---
4
4
 
5
5
  Access to system clocks.
@@ -10,7 +10,7 @@ import Time from "sys/time"
10
10
 
11
11
  ## Values
12
12
 
13
- Functions and constants included in the Sys/Time module.
13
+ Functions and constants included in the Time module.
14
14
 
15
15
  ### Time.**realTime**
16
16