Bynary/implementation.js
Jump to navigation
Jump to search
An implementation of Bynary written in node js by User:Conor O'Brien. Make sure you npm install readwrite before running.
Implementation
const rw = require("readwrite");
const error = (str) => (console.log("\n error: " + str), process.exit())
const bynary = (str) => {
let regs = new Map([
["a", 0],
["b", 0],
["c", 0],
["d", 0],
["e", 0],
["f", 0],
["g", 0],
["h", 0]
]);
// parse
let lines = str.split(/\r?\n/).map(e => {
e = [...e];
let parse = []
for(let i = 0; i < e.length; i++){
if(/[a-z]:/i.test(e[i] + e[i + 1])){
parse.push(e[i] + ":");
} else if(/[0-9]/.test(e[i])){
let build = "";
while(/[0-9]/.test(e[i])){
build += e[i++];
}
i--;
parse.push(build);
} else if(/[a-h]/.test(e[i])){
parse.push(e[i]);
}
}
return parse;
});
let index = 0;
let tr = (c) => regs.has(c) ? regs.get(c) : +!!Number(c);
let commands = new Map([
["v:", (a, b) => regs.set(a, tr(b))],
["d:", (a, b) => +!(regs.get(a)&tr(b))],
["i:", (a) => +!(regs.get(a))],
["p:", (a) => rw.log(
(+a ? String.fromCharCode : x => x)(
parseInt([...regs.values()].join(""), 2)
).toString()
)],
["r:", (n) => {
let nextLine = lines[++index];
if(typeof n === "undefined")
n = parseInt([...regs.values()].join(""), 2);
n = Number(n);
while(n --> 0){
exec(nextLine);
}
}]
]);
const exec = (c, lines, index) => {
if(!c.length) return 0;
let cp = c.map(e => e);
let cmd = cp.shift();
if(!commands.has(cmd))
error(`unrecognized command ${cmd} at ${c}`);
let efc = commands.get(cmd).bind({
lines: lines,
index: index
});
let n = efc.length;
let args = [];
while(n--){
let next = cp.shift();
if(typeof next === "undefined"){
if(cmd !== "r:"){
error(`insufficient arguments passed to "${cmd}"; expected ${cmd.length}, received ${args.length}`);
} else {
break;
}
}
if(next.endsWith(":")){
let [res, rem] = exec(cp);
args.push(res);
cp = rem;
} else {
args.push(next);
}
}
return [efc(...args), c];
}
for(index = 0; index < lines.length; index++){
let line = lines[index];
if(line && line.length)
exec(line);
}
}
bynary.of = (str) => {
let bytes = [...str].map(e =>
[...("00000000" +
e.charCodeAt().toString(2)
).slice(-8)].map(Number));
let states = [0,0,0,0,0,0,0,0];
let comp = "";
let re = "abcdefgh";
for(let byt of bytes){
for(let i = 0; i < byt.length; i++){
if(byt[i] !== states[i]){
comp += `v:${re[i]},${byt[i]}\n`;
states[i] = byt[i];
}
}
comp += "p:1\n";
}
return comp;
}
let args = process.argv.slice(2);
let ind = args.findIndex(e => e === "/c" || e === "-c");
if(ind >= 0){
args.splice(ind, 1);
console.log(bynary.of(args.join(" ")));
} else {
let name = args.shift();
let file = rw.read(name);
bynary(file);
}
Running
node Bynary.js <filename>
or, to convert strings to Bynary:
node Bynary.js /c "my text"
or
node Bynary.js -c "my text"
Notes
The example seems to be incorrect, yielding 0x90 0xD0, roughly (unprintable)Ð.
Implementation-specific features
When no arguments are given to r:, it repeats for the number of times as the number represented in abcdefgh.
Hello, World!
v:b,1 v:e,1 p:1 v:c,1 v:e,0 v:f,1 v:h,1 p:1 v:e,1 v:h,0 p:1 p:1 v:g,1 v:h,1 p:1 v:b,0 v:g,0 v:h,0 p:1 v:e,0 v:f,0 p:1 v:b,1 v:c,0 v:d,1 v:f,1 v:g,1 v:h,1 p:1 v:c,1 v:d,0 v:e,1 p:1 v:d,1 v:e,0 v:f,0 v:h,0 p:1 v:d,0 v:e,1 v:f,1 v:g,0 p:1 v:e,0 p:1 v:b,0 v:f,0 v:h,1 p:1
This outputs Hello, World!.