Files
scriptc/tests/corpus/string-split-traversal.ts
Chris Tate 7fec9715c3 Stream string split loops
- Preserve snapshots, bindings, and cleanup during eligible traversal.
- Reuse unescaped piece storage and batch materialized results.
- Cover limits, Unicode, debugging, and native/WASI behavior.
2026-10-06 18:26:14 -05:00

132 lines
4.4 KiB
TypeScript

function collect(input: string, separator: string, limit: number): string {
let result = "";
for (const piece of input.split(separator, limit)) result += "[" + piece + "]";
return result;
}
for (const limit of [0, 1, 2, 7, -1, 1.9, NaN, Infinity, 4294967296, 4294967297]) {
console.log("limit", limit, collect(",a,,b,", ",", limit));
}
console.log("empty", collect("", "", 9), collect("", ",", 9));
console.log("overlap", collect("ababa", "aba", 9));
console.log("unicode", collect("é世界é中é", "é", 9), collect("世界", "", 9));
console.log("zero", collect("a\0b\0", "\0", 9));
function snapshot(): string {
let input = "left,right";
let separator = ",";
let limit = 2;
const pieces = input.split(separator, limit);
input += ",changed";
separator += "changed";
limit = 0;
let result = "";
for (let pass = 0; pass < 3; pass++) {
for (const piece of pieces) result += "[" + piece + "]";
}
return result + ":" + input + ":" + separator + ":" + limit;
}
console.log("snapshot", snapshot());
let receiver = "first,second";
let effects = "";
function source(): string { effects += "s"; return receiver; }
function separator(): string { effects += "p"; receiver += ",late"; return ","; }
function limit(): number { effects += "l"; return 2; }
let evaluated = "";
for (const piece of source().split(separator(), limit())) {
receiver += ",body";
evaluated += "[" + piece + "]";
}
console.log("order", effects, evaluated, receiver);
function failingSeparator(): string { throw new Error("separator"); }
function failingLimit(): number { throw new Error("limit"); }
try {
for (const piece of (receiver + ",temporary").split(failingSeparator())) console.log(piece);
} catch (error) { console.log("argument", (error as Error).message); }
try {
for (const piece of (receiver + ",temporary").split(receiver + ",separator", failingLimit())) console.log(piece);
} catch (error) { console.log("argument", (error as Error).message); }
function bindings(): string {
const readers: (() => string)[] = [];
for (let piece of "first-word,second-word,third-word".split(",")) {
piece += "!";
readers.push(() => piece);
}
let result = "";
for (const read of readers) result += read();
const shared: (() => string)[] = [];
for (var piece of "four,five".split(",")) shared.push(() => piece);
for (const read of shared) result += read();
let existing = "unchanged";
for (existing of "six,seven".split(",")) result += existing;
result += existing;
for (const [first, second = "_"] of "ab,c".split(",")) result += first + second;
return result;
}
console.log("bindings", bindings());
function exits(input: string): string {
const pieces = input.split(",");
let result = "";
outer: for (const piece of pieces) {
try {
for (const inner of "a,b,c".split(",")) {
if (inner === "a") continue;
if (piece === "break") break outer;
if (piece === "return") return result;
if (piece === "throw") throw new Error("stop");
result += piece + inner;
break;
}
} finally { result += "!"; }
}
return result;
}
console.log("break", exits("one,break,three"));
console.log("return", exits("one,return,three"));
try { console.log(exits("one,throw,three")); } catch (error) { console.log("throw", (error as Error).message); }
function observable(): string {
const pieces = "one,two".split(",");
const alias = pieces;
alias.push("three");
let result = "";
for (const piece of pieces) {
result += piece;
if (piece === "one") pieces.push("four");
}
return result + ":" + pieces.length;
}
console.log("observable", observable());
function escapes(): string {
const pieces = "one,two".split(",");
const read = (): string => pieces.join("/");
let result = "";
for (const piece of pieces) result += piece;
return result + ":" + read();
}
console.log("escapes", escapes());
async function suspended(): Promise<string> {
let input = "one,two";
const pieces = input.split(",");
input += ",late";
let result = "";
for (const piece of pieces) {
await Promise.resolve();
result += piece;
}
for await (const piece of "three,four".split(",")) result += piece;
return result;
}
suspended().then((value) => console.log("async", value));
function* generator(): Generator<string> {
for (const piece of "one,two".split(",")) yield piece;
}
for (const piece of generator()) console.log("generator", piece);