Skip to content

Commit

Permalink
feat(stdlib): Add String.repeat to String module (#2140)
Browse files Browse the repository at this point in the history
Co-authored-by: Oscar Spencer <oscar.spen@gmail.com>
  • Loading branch information
spotandjake and ospencer authored Aug 31, 2024
1 parent b0fb040 commit 6c33d08
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 0 deletions.
8 changes: 8 additions & 0 deletions compiler/test/stdlib/string.test.gr
Original file line number Diff line number Diff line change
Expand Up @@ -551,3 +551,11 @@ assert String.toAsciiLowercase("aBc🌾12Y") == "abc🌾12y"

// toAsciiUppercase
assert String.toAsciiUppercase("aBc🌾12Y") == "ABC🌾12Y"

// String.repeat
assert String.repeat(1, "=.") == "=."
assert String.repeat(10, "=") == "=========="
assert String.repeat(10, "=.") == "=.=.=.=.=.=.=.=.=.=."
assert String.repeat(0, "=.") == ""
assert String.repeat(0, "") == ""
assert String.repeat(5, "") == ""
37 changes: 37 additions & 0 deletions stdlib/string.gr
Original file line number Diff line number Diff line change
Expand Up @@ -2328,3 +2328,40 @@ provide let toAsciiUppercase = string => {
}
implode(chars)
}

/**
* Produces a new string by repeating a substring a given number of times.
*
* @param count: The number of times to repeat the string
* @param string: The string to repeat
* @returns A string containing the repeated input string
*
* @throws InvalidArgument(String): When the `count` is not an integer
* @throws InvalidArgument(String): When the `count` is negative
*
* @example assert String.repeat(5, "=") == "====="
* @example assert String.repeat(0, ".") == ""
*
* @since v0.6.7
*/
@unsafe
provide let repeat = (count, string: String) => {
use WasmI32.{ (+), (*), (<), (&), (!=) }
if ((WasmI32.fromGrain(count) & 1n) != 1n) {
throw InvalidArgument("Invalid count value")
}
let rawCount = untagSimpleNumber(count)
if (rawCount < 0n) {
throw InvalidArgument("Invalid count must be a positive integer or zero")
}
let stringPtr = WasmI32.fromGrain(string)
let byteLength = WasmI32.load(stringPtr, 4n)
let stringPtr = stringPtr + 8n
let newStringPtr = allocateString(byteLength * rawCount)
let strContentPtr = newStringPtr + 8n
for (let mut i = 0n; i < rawCount; i += 1n) {
Memory.copy(strContentPtr + byteLength * i, stringPtr, byteLength)
}
ignore(string)
return WasmI32.toGrain(newStringPtr): String
}
43 changes: 43 additions & 0 deletions stdlib/string.md
Original file line number Diff line number Diff line change
Expand Up @@ -1174,3 +1174,46 @@ Examples:
assert String.toAsciiUppercase("aBc123") == "ABC123"
```

### String.**repeat**

<details disabled>
<summary tabindex="-1">Added in <code>next</code></summary>
No other changes yet.
</details>

```grain
repeat : (count: Number, string: String) => String
```

Produces a new string by repeating a substring a given number of times.

Parameters:

|param|type|description|
|-----|----|-----------|
|`count`|`Number`|The number of times to repeat the string|
|`string`|`String`|The string to repeat|

Returns:

|type|description|
|----|-----------|
|`String`|A string containing the repeated input string|

Throws:

`InvalidArgument(String)`

* When the `count` is not an integer
* When the `count` is negative

Examples:

```grain
assert String.repeat(5, "=") == "====="
```

```grain
assert String.repeat(0, ".") == ""
```

0 comments on commit 6c33d08

Please sign in to comment.