BrainCurses/implementation.js
Jump to navigation
Jump to search
This is an implementation of BrainCurses in node.js, written by User:Conor O'Brien.
Implementation
Remember to npm install readwrite
before running.
const rw = require("readwrite"); class Dequeue extends Array { pop(){ if(this.length === 0) return 0; return super.pop(); } get top(){ let v = this.pop(); this.push(v); return v; } set top(v){ return this[this.length - 1] = v; } inject(value){ return this.unshift(value); } eject(){ return this.shift(); } } class BrainCurses { constructor(program){ this.code = program.match(/'.|\[\$|./g); this.A = 0; this.Dequeue = new Dequeue(); this.instructions = new Map([ ["!", () => this.Dequeue.push(this.A)], ["@", () => this.A = this.Dequeue.pop()], ["^", () => this.Dequeue.inject(this.Dequeue.pop())], ["#", () => this.Dequeue.push(this.Dequeue.eject())], ["+", () => this.A++], ["-", () => this.A--], [":", (output, input) => output(this.A)], [";", (output, input) => this.A = input()], ["%", () => [this.A, this.Dequeue.top] = [this.Dequeue.top, this.A]], ["*", () => this.Dequeue.top = this.A], ["&", () => this.A = this.Dequeue.top], ["[", () => { if(this.A !== 0) return; let i, depth; for(i = this.index + 1, depth = 1; depth && i < this.code.length; i++){ if(this.code[i][0] === "[") depth++; else if(this.code[i] === "]") depth--; } this.index = i - 1; }], ["[$", () => { if(this.Dequeue.top !== 0) return; let i, depth; for(i = this.index + 1, depth = 1; depth && i < this.code.length; i++){ if(this.code[i][0] === "[") depth++; else if(this.code[i] === "]") depth--; } this.index = i - 1; }], ["]", () => { let i, depth; for(i = this.index - 1, depth = 1; depth && i >= 0; --i){ if(this.code[i][0] === "[") depth--; else if(this.code[i] === "]") depth++; } this.index = i; }], ["_", (output, input) => output(String.fromCharCode(this.A))] ]); } execute(output, input){ for(this.index = 0; this.index < this.code.length; this.index++){ let cmd = this.code[this.index]; // console.log(cmd, this.Dequeue); if(this.instructions.has(cmd)){ this.instructions.get(cmd)(output, input); } else if(cmd[0] === "'"){ this.A = cmd.charCodeAt(1); } } return this; } static eval(code, input){ let iar = input.reduce((p,c)=>p.concat(...c),[]).map(e => e.charCodeAt()); let BCinst = new BrainCurses(code); return BCinst.execute(rw.log, () => iar.length && iar.shift()); } } let args = process.argv.slice(2); let debug = false; if(args[0] === "-d" || args[0] === "/d"){ debug = true; args.shift(); } let res = BrainCurses.eval(rw.read(args.shift()), args); if(debug) console.log(res.Dequeue);
Usage
node BrainCurses.js <filename> <input>
or
node BrainCurses.js /d <filename> <input>
or
node BrainCurses.js -d <filename> <input>
The latter two print the contents of the dequeue at program termination.
Assumptions
:
outputsA
as a number;- input reads from left to right
Notices
The string reversal example given on the page ([;!]#[$@_#]
) seems to be incorrect, at least, as per this implementation; the correct way of doing it would be this:
;[!;][$@_]