tricu

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

compiler-conformance.mjs (2383B)


      1 import {COMPILER_BUDGET} from './budgets.mjs';
      2 // Opt-in expensive compiler execution, deliberately not a *.test.mjs/default gate.
      3 import assert from 'node:assert/strict';
      4 import {readFile} from 'node:fs/promises';
      5 import {createHash} from 'node:crypto';
      6 import {contractEnvironment} from '../dist/contracts.js';
      7 import {Graph} from '../dist/graph.js';
      8 import {COMPILER_BUNDLE_LIMIT,decodeBundle,loadBundle} from '../dist/bundle.js';
      9 import {COMPILER_EXPORT,COMPILER_COLLECTION,sourceLiteral,compiledDefinitions} from '../dist/compiler.js';
     10 import {runIO} from '../dist/io.js';
     11 const vectors=JSON.parse(await readFile(new URL('./compiler-conformance.json',import.meta.url)));
     12 const descriptor=JSON.parse(await readFile(new URL('../compiler.json',import.meta.url)));
     13 const bytes=await readFile(new URL('../bundles/'+descriptor.hash+'.arboricx',import.meta.url));
     14 assert.equal(createHash('sha256').update(bytes).digest('hex'),vectors.compilerBundleSha256);
     15 assert.equal(descriptor.hash,vectors.compilerBundleSha256);
     16 const bundle=decodeBundle(bytes,COMPILER_BUNDLE_LIMIT);
     17 for(const c of vectors.cases){
     18   const g=new Graph({...COMPILER_BUDGET,...(c.extended?{fuel:500_000_000}:{})},COMPILER_COLLECTION),exports=loadBundle(g,bundle),start=performance.now();
     19   const result=g.apply(exports.get(COMPILER_EXPORT),[contractEnvironment(g,exports),sourceLiteral(g,c.source)]);
     20   if(c.diagnostic)assert.throws(()=>compiledDefinitions(g,result),error=>error.message===c.diagnostic);
     21   else {
     22     const definitions=compiledDefinitions(g,result);
     23     g.collect(definitions.values());
     24     assert.deepEqual([...definitions.keys()],Object.keys(c.definitions));
     25     for(const [name,tree] of Object.entries(c.definitions))assert.equal(g.toTernary(definitions.get(name),50000),tree);
     26     let applied=g.apply(definitions.get(c.export),c.arguments.map(arg=>g.fromTernary(arg)));
     27     if(c.mode==='io')applied=await runIO(g,applied,{before:async()=>{},after(){},running(){},read:async()=>c.input,write(){throw Error('unexpected output');}},true);
     28     assert.equal(g.toTernary(applied,50000),c.result);
     29   }
     30   assert.ok(g.stats.collections>0);assert.ok(g.stats.peakNodes<(c.extended?2_000_000:600_000));
     31   if(c.source.includes('other ='))assert.ok(g.stats.allocations>6_000_000);
     32   console.log('PASS Haskell compiler comparison',JSON.stringify(c.source),Math.round(performance.now()-start)+'ms',g.stats);
     33 }