(input: string, separator: string)
| 27 | * ╰──────────────┴──┴───────────── Ignored b/c inside >= 1 levels of parens |
| 28 | */ |
| 29 | export function segment(input: string, separator: string) { |
| 30 | class="cm">// SAFETY: We can use an index into a shared buffer because this function is |
| 31 | class="cm">// synchronous, non-recursive, and runs in a single-threaded environment. |
| 32 | let stackPos = 0 |
| 33 | let parts: string[] = [] |
| 34 | let lastPos = 0 |
| 35 | let len = input.length |
| 36 | |
| 37 | let separatorCode = separator.charCodeAt(0) |
| 38 | |
| 39 | for (let idx = 0; idx < len; idx++) { |
| 40 | let char = input.charCodeAt(idx) |
| 41 | |
| 42 | if (stackPos === 0 && char === separatorCode) { |
| 43 | parts.push(input.slice(lastPos, idx)) |
| 44 | lastPos = idx + 1 |
| 45 | continue |
| 46 | } |
| 47 | |
| 48 | switch (char) { |
| 49 | case BACKSLASH: |
| 50 | class="cm">// The next character is escaped, so we skip it. |
| 51 | idx += 1 |
| 52 | break |
| 53 | class="cm">// Strings should be handled as-is until the end of the string. No need to |
| 54 | class="cm">// worry about balancing parens, brackets, or curlies inside a string. |
| 55 | case SINGLE_QUOTE: |
| 56 | case DOUBLE_QUOTE: |
| 57 | class="cm">// Ensure we don't go out of bounds. |
| 58 | while (++idx < len) { |
| 59 | let nextChar = input.charCodeAt(idx) |
| 60 | |
| 61 | class="cm">// The next character is escaped, so we skip it. |
| 62 | if (nextChar === BACKSLASH) { |
| 63 | idx += 1 |
| 64 | continue |
| 65 | } |
| 66 | |
| 67 | if (nextChar === char) { |
| 68 | break |
| 69 | } |
| 70 | } |
| 71 | break |
| 72 | case OPEN_PAREN: |
| 73 | closingBracketStack[stackPos] = CLOSE_PAREN |
| 74 | stackPos++ |
| 75 | break |
| 76 | case OPEN_BRACKET: |
| 77 | closingBracketStack[stackPos] = CLOSE_BRACKET |
| 78 | stackPos++ |
| 79 | break |
| 80 | case OPEN_CURLY: |
| 81 | closingBracketStack[stackPos] = CLOSE_CURLY |
| 82 | stackPos++ |
| 83 | break |
| 84 | case CLOSE_BRACKET: |
| 85 | case CLOSE_CURLY: |
| 86 | case CLOSE_PAREN: |
no outgoing calls