mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-24 06:14:01 +08:00
- Compile the production C emitter and reproduce its output across native generations. - Support the union operations, recursive spreads, and compression options needed by the emitter. - Fix temporary ownership and verify the bootstrap and shared call operands with both backends and sanitizers.
60 lines
2.4 KiB
TypeScript
60 lines
2.4 KiB
TypeScript
// Removal widens union tags while preserving the identities of payloads.
|
|
interface Left { kind: "left"; label: string; count: number }
|
|
interface Right { kind: "right"; label: string; enabled: boolean }
|
|
type Item = Left | Right;
|
|
const left: Left = { kind: "left", label: "left", count: 1 };
|
|
const right: Right = { kind: "right", label: "right", enabled: true };
|
|
const items: Item[] = [left, right, left];
|
|
const identity = new Map<Item, string>();
|
|
identity.set(left, "original-left");
|
|
identity.set(right, "original-right");
|
|
let calls = 0;
|
|
function source(): Item[] { calls++; return items; }
|
|
const last = source().pop();
|
|
if (last !== undefined) {
|
|
console.log(identity.get(last), last.kind, items.length, calls);
|
|
if (last.kind === "left") last.count = 42;
|
|
}
|
|
console.log(left.count);
|
|
const first = source().shift();
|
|
if (first !== undefined) console.log(identity.get(first), first.label, items.length, calls);
|
|
const final = items.shift();
|
|
if (final !== undefined) console.log(identity.get(final), final.label, items.length);
|
|
console.log(items.pop() === undefined, items.shift() === undefined);
|
|
|
|
// Payload kinds can differ, and the insertion of undefined can reorder tags.
|
|
const scalars: (string | number | boolean)[] = ["text", 0, false, 9, "last"];
|
|
for (let i = 0; i < 7; i++) {
|
|
const value = i % 2 === 0 ? scalars.pop() : scalars.shift();
|
|
console.log(typeof value, value, scalars.length);
|
|
}
|
|
|
|
// Holes are missing values, yet the removal still shrinks the receiver.
|
|
const sparse: (string | number)[] = ["start", 2];
|
|
sparse.length = 5;
|
|
console.log(sparse.pop(), sparse.length);
|
|
console.log(sparse.shift(), sparse.length);
|
|
console.log(sparse.pop(), sparse.length);
|
|
console.log(sparse.shift(), sparse.length);
|
|
console.log(sparse.shift(), sparse.length);
|
|
console.log(sparse.shift(), sparse.length);
|
|
|
|
// A removed refcounted payload survives after the array drops its ownership.
|
|
function fresh(): Item[] {
|
|
return [{ kind: "left", label: "fresh", count: 7 }, { kind: "right", label: "fresh-right", enabled: false }];
|
|
}
|
|
const popped = fresh().pop();
|
|
const shifted = fresh().shift();
|
|
if (popped !== undefined) console.log(popped.label);
|
|
if (shifted !== undefined) console.log(shifted.label);
|
|
|
|
// Discarded results use the same mutation semantics and release ownership.
|
|
for (let i = 0; i < 40; i++) {
|
|
const temporary = fresh();
|
|
temporary.pop();
|
|
temporary.shift();
|
|
temporary.pop();
|
|
if (temporary.length !== 0) throw new Error("not empty");
|
|
}
|
|
console.log("removed");
|