Skip to content

Commit

Permalink
feat(stdlib): String.implode (#489)
Browse files Browse the repository at this point in the history
  • Loading branch information
ospencer committed Dec 19, 2020
1 parent 1e4a691 commit 045077b
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 0 deletions.
5 changes: 5 additions & 0 deletions compiler/test/stdlib/string.test.gr
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ let codes = [> 119, 101, 32, 102, 111, 117, 110, 100, 32, 97, 32, 112, 97, 116,
let chars = Array.map(Char.fromCode, codes)
assert String.explode(emojis) == chars

// implode tests
assert String.implode([>]) == ""
assert String.implode([> '5', ' ', '4', '3', 'a', 'b', 'c']) == "5 43abc"
assert String.implode(String.explode(emojis)) == emojis

// split tests
assert String.split(empty, empty) == [>]
assert String.split(short, empty) == [> "f", "o", "x"]
Expand Down
50 changes: 50 additions & 0 deletions stdlib/stdlib-external/string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,56 @@ export function explode(str: u32): u32 {
return explodeHelp(str, true)
}

export function implode(arr: u32): u32 {
arr = arr ^ GRAIN_GENERIC_HEAP_TAG_TYPE

let arrLength = load<u32>(arr, 4)

let stringByteLength = 0

for (let i: u32 = 0; i < arrLength; i++) {
const char = load<u32>(arr + (i << 2), 8) ^ GRAIN_GENERIC_HEAP_TAG_TYPE
const byte = load<u8>(char, 4)

let n: u32
if ((byte & 0x80) === 0x00) {
n = 1
} else if ((byte & 0xF0) === 0xF0) {
n = 4
} else if ((byte & 0xE0) === 0xE0) {
n = 3
} else {
n = 2
}

stringByteLength += n
}

let str = allocateString(stringByteLength)
let offset = 8

for (let i: u32 = 0; i < arrLength; i++) {
const char = load<u32>(arr + (i << 2), 8) ^ GRAIN_GENERIC_HEAP_TAG_TYPE
const byte = load<u8>(char, 4)

let n: u32
if ((byte & 0x80) === 0x00) {
n = 1
} else if ((byte & 0xF0) === 0xF0) {
n = 4
} else if ((byte & 0xE0) === 0xE0) {
n = 3
} else {
n = 2
}

memory.copy(str + offset, char + 4, n)
offset += n
}

return str ^ GRAIN_GENERIC_HEAP_TAG_TYPE
}

export function split(str: u32, pat: u32): u32 {
let s = str ^ GRAIN_GENERIC_HEAP_TAG_TYPE
let p = pat ^ GRAIN_GENERIC_HEAP_TAG_TYPE
Expand Down
5 changes: 5 additions & 0 deletions stdlib/string.gr
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ let indexOf = (s, p) => {
// @returns Array<Char>
import foreign wasm explode : String -> Array<Char> from "stdlib-external/string"

// Create a string from an array of characters
// @param input: Array<Char> - The array to implode
// @returns String
import foreign wasm implode : Array<Char> -> String from "stdlib-external/string"

// Split a string by the given sequence
// @param input: String - The string to split
// @param sequence: String - The sequence to split on
Expand Down

0 comments on commit 045077b

Please sign in to comment.