tricu

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

tree-session.mjs (1867B)


      1 // Private implementation shared by today's two tree adapters, not a requirement
      2 // on other backends. Runtime handles and checkpoints never leave this closure.
      3 import {compiledDefinitions} from '../demo-site/dist/compiler.js';
      4 export function treeSession(g, root, adapter) {
      5   let definitions=new Map(), disposed=false;
      6   const active=()=>{if(disposed)throw new Error('Session disposed');};
      7   const definition=name=>{const h=definitions.get(name);if(h===undefined)throw new Error('Missing definition');return h;};
      8   const scoped=fn=>{active();return adapter.scope(fn);};
      9   return {
     10     runText(value) {return scoped(()=>adapter.toText(g.app(root,adapter.ofText(value))));},
     11     compile(source) {
     12       const next=scoped(({keep})=>{
     13         const input=adapter.ofText(source,16384);
     14         const defs=compiledDefinitions(g,g.apply(root,[g.leaf,input]));
     15         for(const h of defs.values())keep(h);
     16         return defs;
     17       });
     18       for(const h of definitions.values())adapter.release(h);
     19       definitions=next;
     20       return [...definitions.keys()];
     21     },
     22     inspect(name,args) {return scoped(()=>g.toTernary(g.apply(definition(name),args.map(x=>g.fromTernary(x)))));},
     23     preview(name,limit) {active();return g.preview(definition(name),limit);},
     24     // Bounded tree inputs are a harness operation, not source compilation.
     25     // Worker termination is the deadline for divergent evaluation.
     26     runTree(program,args) {return scoped(()=>{
     27       const applied=g.apply(g.fromTernary(program),args.map(x=>g.fromTernary(x)));
     28       return g.toTernary(g.force(applied,0x7fffffffffffffffn));
     29     });},
     30     collect() {active();adapter.collect([root,...definitions.values()]);},
     31     stats() {active();return adapter.stats();},
     32     dispose() {if(disposed)return;disposed=true;definitions.clear();try{adapter.dispose();}finally{g=undefined;adapter=undefined;}},
     33   };
     34 }