Files
scriptc/tests/corpus/contextual-array-union-write.ts
Chris Tate 3f56576644 feat(compiler): rebuild the frontend with native compiler stages (#568)
- Share frontend loading, package selection, contracts, and FFI parsing between Node and native clients.
- Preserve collection layouts and optional method returns while lowering long nullish chains without recursive stack growth.
- Rebuild the frontend from TypeScript through native lowering and C emission with matching output.
2026-09-29 07:45:18 -05:00

53 lines
2.6 KiB
TypeScript

import type { IrExpr, IrType, SrcLoc } from "../../packages/compiler/src/ir/ir.js";
type Expr = { kind: "number"; value: number } | { kind: "sum"; values: Expr[] };
function valueOf(expr: Expr): number {
return expr.kind === "number" ? expr.value : expr.values.reduce((sum, value) => sum + valueOf(value), 0);
}
const values: Expr[] = [{ kind: "number", value: 1 }];
values.forEach((value, index) => {
values[index] = { kind: "sum", values: [value, { kind: "number", value: 2 }] };
});
console.log(valueOf(values[0]!));
const combined = [2, 3, 4].reduce<Expr>((left, right) => ({ kind: "sum", values: [left, { kind: "number", value: right }] }), { kind: "number", value: 1 });
console.log(valueOf(combined));
const reversed = [2, 3, 4].reduceRight<Expr>((left, right) => ({ kind: "sum", values: [left, { kind: "number", value: right }] }), { kind: "number", value: 1 });
console.log(valueOf(reversed));
// The frontend's recursive expression union has nested type and location
// fields. Construct values directly in that destination, including a
// callback parameter narrowed by one of its nested discriminants.
const location: SrcLoc = { file: "fixture.ts", start: 0, end: 1 };
const booleanType: IrType = { kind: "bool" };
const jsType: IrType = { kind: "jsval" };
const dynType: IrType = { kind: "dyn" };
const expressions: IrExpr[] = [
{ kind: "boolLit", value: true, type: booleanType, loc: location },
{ kind: "jsOp", op: "undefLit", args: [], type: jsType, loc: location },
];
expressions.forEach((value, index) => {
if (value.type.kind === "jsval") {
expressions[index] = { kind: "dynFromJsval", value, type: dynType, loc: value.loc };
} else {
expressions[index] = { kind: "jsMarshal", value, type: jsType, loc: value.loc };
}
});
console.log(expressions.map((value) => value.kind).join(","));
const initial: IrExpr = { kind: "boolLit", value: true, type: booleanType, loc: location };
const logical = expressions.reduce<IrExpr>((left, right) => ({
kind: "logical", op: "&&", left, right, type: booleanType, loc: location,
}), initial);
console.log(logical.kind, logical.kind === "logical" && logical.left.kind);
const getters = [{ name: "one", fn: initial }, { name: "two", fn: initial }];
const withGetters = getters.reduceRight<IrExpr>((value, getter) => ({
kind: "jsOp", op: "defineGetter", args: [
value,
{ kind: "jsMarshal", value: { kind: "strLit", value: getter.name, type: { kind: "string" }, loc: location }, type: jsType, loc: location },
getter.fn,
], type: jsType, loc: location,
}), initial);
console.log(withGetters.kind, withGetters.kind === "jsOp" && withGetters.args.length);