Skip to content

Instantly share code, notes, and snippets.

@0racle
Last active May 11, 2023 03:04
Show Gist options
  • Save 0racle/8ae25d97538f02d33e1eec57f7d18c25 to your computer and use it in GitHub Desktop.
Save 0racle/8ae25d97538f02d33e1eec57f7d18c25 to your computer and use it in GitHub Desktop.
J REPL in Node

This Node script creates a REPL for the J langage by calling out to the J shared lib (libj.so) via the node-ffi-napi.

I would like to be able to do syntax highlighting on the input (and perhaps output) using emphasize, which wraps highlight.js through lowlight to output ANSI syntax highlighting.

emphasize is "ESM only". I'm not a Node guy, so I'm not sure exactly what that means, apart from the fact that I can't simply do require('emphasize') in my Node script. Any help on how to get this working would be appreciated.

The highlight.js language definition for J is here.

//!/usr/bin/env node
var ffi = require('ffi-napi');
const BIN = '/opt/j904/bin';
const LIB = `${BIN}/libj.so`;
const PRO = `${BIN}/profile.ijs`;
var libj = ffi.Library(LIB, {
'JInit': [ 'pointer', [ ] ],
'JDo': [ 'int', [ 'pointer', 'string' ] ],
'JGetR': [ 'string', [ 'pointer' ] ],
});
let j = libj.JInit();
libj.JDo(j, `0!:0<'${PRO}'[BINPATH_z_=:'${BIN}'[ARGV_z_=:''`);
var readline = require('readline');
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.setPrompt(' ')
rl.prompt()
rl.on('line', expr => {
libj.JDo(j, expr);
var out = libj.JGetR(j);
process.stdout.write(out);
}),
// force trigger of _writeToOutput on each keystroke
process.stdin.on(
'keypress', (c, k) => {
setTimeout(() => { rl._refreshLine() }, 0);
},
);
rl._writeToOutput = function _writeToOutput(out) {
// This is where the highlighting would occur
// eg. rl.output.write(emphasize.highlight('J', out);
rl.output.write(out)
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment