Skip to content

Instantly share code, notes, and snippets.

@a-c-t-i-n-i-u-m
Created September 13, 2014 10:16
Show Gist options
  • Save a-c-t-i-n-i-u-m/8844b318db403fbe88f3 to your computer and use it in GitHub Desktop.
Save a-c-t-i-n-i-u-m/8844b318db403fbe88f3 to your computer and use it in GitHub Desktop.
myBrainfuck; Javascript Brainfuck Interpreter
/**
* myBrainfuck; Javascript Brainfuck Interpreter
* http://actinium.org/ <Lianol>
* Usage:
* var interpreter = new MyBrainfuck();
* var result = interpreter.execute(source);
* alert(result.stdout);
*/
(function () {
var myBrainfuck = function (option) {
var defaults = {
command: {
next: '>',
prev: '<',
inc: '+',
dec: '-',
put: '.',
get: ',',
do: '[',
done: ']',
},
memsize: Math.pow(2, 15),
};
this.setting = this.extend(defaults, option);
};
myBrainfuck.prototype.extend = function () {
var target = arguments[0] || {};
for (var i = 1; i < arguments.length; i++) {
for (var j in arguments[i]) {
if (typeof arguments[i][j] === 'object') {
target[j] = this.extend(target[j], arguments[i][j]);
} else {
target[j] = arguments[i][j];
}
}
}
return target;
};
myBrainfuck.prototype.decodeSource = function (source) {
// sort command by length DESC
var commandName = Object.keys(this.setting.command)
.sort(function (a, b) { return this.setting.command[b].length - this.setting.command[a].length; }.bind(this)),
temp = [];
// decode
while (source.length > 0) {
var notfound = true;
for (var i = 0; i < commandName.length; i++) {
var command = this.setting.command[commandName[i]];
if (source.indexOf(command) === 0) {
temp.push(commandName[i]);
source = source.replace(command, '');
notfound = false;
}
}
if (notfound) {
source = source.substr(1);
}
}
return temp;
};
myBrainfuck.prototype.execute = function (source, stdin) {
// initialize
var commandLine = this.decodeSource(source),
stdin = stdin.split(''),
stdout = '',
memory = [],
pointer = 0;
for (var i = 0; i < this.setting.memsize; i++) {
memory[i] = 0;
}
// run
for (var i = 0; i < commandLine.length; i++) {
// execute command
switch (commandLine[i]) {
case 'next':
if (pointer++ === this.setting.memsize) {
pointer = 0;
}
break;
case 'prev':
if (pointer-- === -1) {
pointer += this.setting.memsize;
}
break;
case 'inc':
if (memory[pointer]++ === 128) {
memory[pointer] = -128;
}
break;
case 'dec':
if (memory[pointer]-- === -129) {
memory[pointer] = 127;
}
break;
case 'put':
stdout += String.fromCharCode(memory[pointer]);
break;
case 'get':
memory[pointer] = stdin.pop().charCodeAt(0);
break;
case 'do':
if (memory[pointer] === 0) {
for (var o = i; o < commandLine.length; o++) {
if (commandLine[o] === 'done') {
i = o;
break;
}
}
}
break;
case 'done':
for (var o = i; o >= 0; o--) {
if (commandLine[o] === 'do') {
i = o - 1;
break;
}
}
break;
}
}
return {stdout: stdout, source: commandLine};
};
window.myBrainfuck = myBrainfuck;
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment