tricu

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

cli.js (2680B)


      1 #!/usr/bin/env node
      2 /**
      3  * cli.js — Arboricx JS host shell via libarboricx C ABI.
      4  *
      5  * Usage:
      6  *   node cli.js inspect <bundle.arboricx>
      7  *   node cli.js run <bundle.arboricx> [args...]
      8  */
      9 
     10 import { readFileSync } from 'node:fs';
     11 import {
     12   init,
     13   free,
     14   loadBundleDefault,
     15   reduce,
     16   app,
     17   ofNumber,
     18   ofString,
     19   decode,
     20   decodeType,
     21   findLib,
     22 } from './lib.js';
     23 
     24 // ── Commands ─────────────────────────────────────────────────────────────────
     25 
     26 function cmdInspect(bundlePath) {
     27   const ctx = init();
     28   try {
     29     const bundle = readFileSync(bundlePath);
     30     console.log(`Bundle: ${bundlePath}`);
     31     console.log(`Size: ${bundle.length} bytes\n`);
     32 
     33     const term = loadBundleDefault(ctx, bundle);
     34     const result = reduce(ctx, term);
     35 
     36     const type = decodeType(ctx, result);
     37     let value;
     38     try {
     39       value = decode(ctx, result);
     40     } catch {
     41       value = '(raw tree)';
     42     }
     43 
     44     console.log(`Type: ${type}`);
     45     console.log(`Value: ${value}`);
     46   } catch (e) {
     47     console.error(`Error: ${e.message}`);
     48     process.exit(1);
     49   } finally {
     50     free(ctx);
     51   }
     52 }
     53 
     54 function cmdRun(bundlePath, args) {
     55   const ctx = init();
     56   try {
     57     const bundle = readFileSync(bundlePath);
     58     let term = loadBundleDefault(ctx, bundle);
     59 
     60     for (const arg of args) {
     61       const argTree = /^\d+$/.test(arg) ? ofNumber(ctx, BigInt(arg)) : ofString(ctx, arg);
     62       term = app(ctx, term, argTree);
     63     }
     64 
     65     const result = reduce(ctx, term);
     66     console.log(decode(ctx, result));
     67   } catch (e) {
     68     console.error(`Error: ${e.message}`);
     69     process.exit(1);
     70   } finally {
     71     free(ctx);
     72   }
     73 }
     74 
     75 // ── Main ─────────────────────────────────────────────────────────────────────
     76 
     77 const args = process.argv.slice(2);
     78 const command = args[0];
     79 
     80 switch (command) {
     81   case 'inspect': {
     82     if (args.length < 2) {
     83       console.error('Usage: node cli.js inspect <bundle.arboricx>');
     84       process.exit(1);
     85     }
     86     cmdInspect(args[1]);
     87     break;
     88   }
     89   case 'run': {
     90     if (args.length < 2) {
     91       console.error('Usage: node cli.js run <bundle.arboricx> [args...]');
     92       process.exit(1);
     93     }
     94     cmdRun(args[1], args.slice(2));
     95     break;
     96   }
     97   default:
     98     console.log('Arboricx JS Host (via libarboricx FFI)');
     99     console.log('');
    100     console.log('Usage:');
    101     console.log('  node cli.js inspect <bundle.arboricx>');
    102     console.log('  node cli.js run <bundle.arboricx> [args...]');
    103     break;
    104 }