Files
scriptc/tests/corpus/3079-forward-mutable-tdz.ts
Chris Tate 8e95bcbe7f feat(compiler): advance native validator self-hosting (#492)
- Support mutable forward captures with correct initialization and exception behavior.
- Compile recursive literals, exhaustive bindings, and validator collection operations statically.
- Run validator control-flow analysis natively with C and LLVM differential coverage.
2026-09-27 12:14:06 -05:00

82 lines
2.4 KiB
TypeScript

export {};
function attempt(label: string, action: () => void): void {
try { action(); console.log(label, "unexpected success"); }
catch (error) {
if (error instanceof Error) console.log(label, error.name, error.message);
}
}
function numeric(): void {
let effects = "";
const rhs = (): number => { effects += "R"; return 5; };
const read = () => { console.log(value); };
const write = () => { value = rhs(); };
const expression = () => { console.log(value = rhs()); };
const add = () => { value += rhs(); };
const increment = () => { value++; };
const decrement = () => { console.log(--value); };
attempt("read", read);
attempt("write", write);
attempt("expression", expression);
attempt("add", add);
attempt("increment", increment);
attempt("decrement", decrement);
console.log("effects", effects);
let value = 1;
write();
expression();
add();
increment();
decrement();
console.log("initialized", value, effects);
}
numeric();
function references(): void {
const rhs = () => ({ label: "allocated", values: [1, 2, 3] });
const write = () => { value = rhs(); };
const expression = () => { console.log((value = rhs()).label); };
attempt("record write", write);
attempt("record expression", expression);
let value = { label: "initial", values: [0] };
write();
expression();
console.log(value.label, value.values.join(","));
}
references();
function text(): void {
const append = () => { value += "!"; };
const write = () => { value = "after"; };
attempt("text append", append);
attempt("text write", write);
let value = "before";
append();
console.log(value);
}
text();
// Calls during the initializer still see an empty box. The declaration
// becomes initialized only after its RHS returns normally.
function initializer(): void {
const set = () => { value = 3; };
const init = (): number => { attempt("inside initializer", set); return 2; };
let value = init();
set();
console.log("initializer", value);
}
initializer();
// A throwing initializer never initializes the box. An escaped closure
// still throws even after the declaring stack frame has unwound.
let escaped: () => void = () => { console.log("unset"); };
function failed(): void {
escaped = () => { console.log(value); };
function fail(): number { throw new Error("init failed"); }
let value = fail();
void value;
}
attempt("failed initializer", () => { failed(); });
attempt("escaped read", escaped);