I have this Brainf***Brainfuck interpreter (this is the JavaScript part):
// Credit goes to where it is due
function throwException(cause, index) {
// Execute when there is an error in Brainf*** code
$('p#output').text("Interpreting Terminated because " + cause + " at char index " + index);
}
function runBrainfuck(data) {
console.time("Running Brainf*** code");
var memory = new Array(); // memory
// Initialize memory
console.time("Initialize memory");
for(var i = 0; i < 30000; i++) {
memory[i] = 0;
}
console.timeEnd("Initialize memory");
var p = 0; // pointer to memory
$('p#output').text("");
// Loop through the Brainf*** code
var data = $('#code').val();
for(var j = 0; j < data.length; j++) {
switch(true) {
case data[j] === ">": // go right one cell
if(p < 30000) {
p++;
} else {
throwException("There are only 30000 usable cells of memory.", j); // are you using too many cells?
}
break;
case data[j] === "<": // go left one cell
if(p > 0) {
p--;
} else {
throwException("Cannot decrement pointer when it is at first cell.", j); // are you going below cell 0?
}
break;
case data[j] === "+": // Increment cell value
memory[p]++;
if(memory[p] > 255) {
memory[p] = 0; // Whoops, overflown the memory!
}
break;
case data[j] === "-": // decrement cell value
if(memory[p] > 0) {
memory[p]--;
} else {
memory[p] = 255; // Overflow back to 255
}
break;
case data[j] === ".": // put character to screen
var memoryChar = String.fromCharCode(memory[p]);
if(memoryChar == '\n') {
memoryChar = ""; // Turn newlines into linebreaks
}
$('p#output').append(String.fromCharCode(memory[p]));
break;
case data[j] === ",":
memory[p] = window.prompt("Please enter one character").charCodeAt(0); // Set memory to the character code
break;
case data[j] === "[": // start loop
if(memory[p] != 0) {
continue;
} else {
var openLoopCnt = 0; // number of open loops
for(var k = j; k < data.length; k++) {
if(data[k] === '[') {
openLoopCnt++; // Another open loop is in existence
} else if(data[k] === ']') {
openLoopCnt++; // Decrement open count
if(openLoopCnt === 0) {
j = k;
break;
}
}
}
if(openLoopCnt != 0) {
throwException("Open loop.", j);
}
}
break;
case data[j] === "]": // end loop
if(memory[p] != 0) {
var closedLoopCnt = 0; // Due to the fact that we are at closing loops, we use closedLoopCnt
for(var l = j; l >= 0; l--) {
if(data[l] === "]") {
closedLoopCnt++;
} else if(data[l] === "[") {
closedLoopCnt--;
}
if(closedLoopCnt === 0) {
j = l;
break;
}
}
if(closedLoopCnt != 0) {
throwException("Too many loop closings.", i);
}
}
break;
}
}
console.timeEnd("Running Brainf*** code");
console.time("Saving output in localStorage");
localStorage.setItem("brainfuck_output", $('#output').text());
console.timeEnd("Saving output in localStorage");
}
Here is the HTML part if you are wondering where this came from:
<h1>Interpret your Brainf*** code!</h1>
<form action="#" method="get" id="brainf***" onsubmit="runBrainfuck($('#code').val())">
<label for="brainf***">Brainf*** code:</label> <br />
<textarea name="code" rows="25" cols="70" id="code"></textarea> <br />
<input type="submit" value="Interpret Brainf*** code!" />
</form>
<h2>Brainf*** output:</h2>
<p id="output"></p>
// Credit goes to where it is due
function throwException(cause, index) {
// Execute when there is an error in Brainf*** code
$('p#output').text("Interpreting Terminated because " + cause + " at char index " + index);
}
function runBrainfuck(data) {
console.time("Running Brainf*** code");
var memory = new Array(); // memory
// Initialize memory
console.time("Initialize memory");
for(var i = 0; i < 30000; i++) {
memory[i] = 0;
}
console.timeEnd("Initialize memory");
var p = 0; // pointer to memory
$('p#output').text("");
// Loop through the Brainf*** code
var data = $('#code').val();
for(var j = 0; j < data.length; j++) {
switch(true) {
case data[j] === ">": // go right one cell
if(p < 30000) {
p++;
} else {
throwException("There are only 30000 usable cells of memory.", j); // are you using too many cells?
}
break;
case data[j] === "<": // go left one cell
if(p > 0) {
p--;
} else {
throwException("Cannot decrement pointer when it is at first cell.", j); // are you going below cell 0?
}
break;
case data[j] === "+": // Increment cell value
memory[p]++;
if(memory[p] > 255) {
memory[p] = 0; // Whoops, overflown the memory!
}
break;
case data[j] === "-": // decrement cell value
if(memory[p] > 0) {
memory[p]--;
} else {
memory[p] = 255; // Overflow back to 255
}
break;
case data[j] === ".": // put character to screen
var memoryChar = String.fromCharCode(memory[p]);
if(memoryChar == '\n') {
memoryChar = ""; // Turn newlines into linebreaks
}
$('p#output').append(String.fromCharCode(memory[p]));
break;
case data[j] === ",":
memory[p] = window.prompt("Please enter one character").charCodeAt(0); // Set memory to the character code
break;
case data[j] === "[": // start loop
if(memory[p] != 0) {
continue;
} else {
var openLoopCnt = 0; // number of open loops
for(var k = j; k < data.length; k++) {
if(data[k] === '[') {
openLoopCnt++; // Another open loop is in existence
} else if(data[k] === ']') {
openLoopCnt++; // Decrement open count
if(openLoopCnt === 0) {
j = k;
break;
}
}
}
if(openLoopCnt != 0) {
throwException("Open loop.", j);
}
}
break;
case data[j] === "]": // end loop
if(memory[p] != 0) {
var closedLoopCnt = 0; // Due to the fact that we are at closing loops, we use closedLoopCnt
for(var l = j; l >= 0; l--) {
if(data[l] === "]") {
closedLoopCnt++;
} else if(data[l] === "[") {
closedLoopCnt--;
}
if(closedLoopCnt === 0) {
j = l;
break;
}
}
if(closedLoopCnt != 0) {
throwException("Too many loop closings.", i);
}
}
break;
}
}
console.timeEnd("Running Brainf*** code");
console.time("Saving output in localStorage");
localStorage.setItem("brainfuck_output", $('#output').text());
console.timeEnd("Saving output in localStorage");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h1>Interpret your Brainf*** code!</h1>
<form action="#" method="get" id="brainf***" onsubmit="runBrainfuck($('#code').val())">
<label for="brainf***">Brainf*** code:</label> <br />
<textarea name="code" rows="25" cols="70" id="code"></textarea> <br />
<input type="submit" value="Interpret Brainf*** code!" />
</form>
<h2>Brainf*** output:</h2>
<p id="output"></p>