tricu

An interpreted language for exploring Tree Calculus
Log | Files | Refs | README | LICENSE

io-v2-private.ts (2220B)


      1 // Private native-adapter validation runner, not RuntimeSession IO dispatch.
      2 // Bare computations only; no facility implementation/capability advertisement.
      3 import { Core, type Trees } from './io-v2-core.js';
      4 import { canonicalNat, type Reader } from './io-v2-protocol.js';
      5 export function constructors<H>(base: Reader<H> & Pick<Trees<H>, 'leaf' | 'fork' | 'stem' | 'app'>): Trees<H> {
      6   const natural = (value: bigint): H => {
      7     const bits: H[] = [];
      8     if (value < 0n) throw new Error('negative natural');
      9     for (; value; value >>= 1n) bits.push(value & 1n ? base.stem(base.leaf) : base.leaf);
     10     let out = base.leaf; for (let i = bits.length - 1; i >= 0; i--) out = base.fork(bits[i]!, out); return out;
     11   };
     12   return { ...base, natural, text(value: string): H {
     13     let out = base.leaf; const chars = Array.from(value);
     14     for (let i = chars.length - 1; i >= 0; i--) out = base.fork(natural(BigInt(chars[i]!.codePointAt(0)!)), out);
     15     return out;
     16   } };
     17 }
     18 export async function runPrivate<H>(tree: Trees<H>, action: H, identity: bigint, sweep: (roots: Iterable<H>) => void) {
     19   const engine = new Core(tree, identity, action, [null, null, null], {
     20     request: (core, _scope, request) => () => core.wire.result(false, core.wire.problem('unsupported', `${request.group}/${request.operation}`)),
     21     release: () => { throw new Error('unexpected owned backend in private core probe'); } });
     22   sweep(engine.roots());
     23   for (let turns = 0; !engine.result; turns++) {
     24     const progress = engine.advance(); sweep(engine.roots());
     25     if (!progress) {
     26       if (!engine.work.counts.pending) throw new Error('private interpreter stalled');
     27       await engine.wait();
     28     }
     29     if (turns % 32 === 0) await new Promise<void>(resolve => setTimeout(resolve, 0));
     30   }
     31   if (engine.hasFault) throw engine.fault;
     32   const out = engine.result;
     33   // Terminal diagnostics stay opaque, including when the test requests a number.
     34   const value = out.kind === 'completed' ? canonicalNat(tree, out.value, 64)?.toString() ?? null : null;
     35   return { kind: out.kind, value, cleanup: out.cleanup?.items.length ?? 0,
     36     tasks: engine.lifecycle.tasks.counts, resources: engine.lifecycle.resources.counts, host: engine.work.counts };
     37 }