Brainfuck Converter/Interpreter in JavaScript
<html>
<head>
<!--
CryptoMX Tools
Copyright (C) 2004 - 2006 Derek Buitenhuis
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-->
<title>Brainfuck Converter/Interpreter</title>
<!-- bf.js -->
<script>
BF_ARRAY_LEN = 4000;
arr = new Array(BF_ARRAY_LEN);
function push(el, stack)
{
stack[stack.length] = el;
return stack;
}
function peek(stack)
{
return stack[stack.length-1];
}
function pop(stack)
{
return stack.slice(0,stack.length-2);
}
function evalBF(codestr, outputField)
{
outputField.value = "";
for (i=0; i<BF_ARRAY_LEN; i++) arr[i] = 0;
ptr = 0;
loopstack = Array();
i = 0;
while (i < codestr.length)
{
switch (codestr.charAt(i))
{
case "[":
if (arr[ptr]!=0) loopstack = push(i,loopstack);
else i = codestr.indexOf("]",i);
i++;
break;
case "]":
i = peek(loopstack);
loopstack = pop(loopstack);
break;
case "+":
arr[ptr]++;
i++;
break;
case "-":
arr[ptr]--;
i++;
break;
case "<":
ptr--;
i++;
break;
case ">":
ptr++;
i++;
break;
case ".":
outputField.value += String.fromCharCode(arr[ptr]);
i++;
break;
case ",":
input = prompt("BF program input:","");
arr[ptr] = input.charCodeAt(0);
i++;
break;
default:
i++;
break;
}
}
}
function strTimes(str,times)
{
endstr = "";
for (var i=0; i<times; i++) endstr += str;
return endstr;
}
function printDifference(diff,poschar,negchar)
{
str = "";
if (diff>0)
for (var b=0; b<diff; b++) str += poschar;
else
for (var b=0; b<-diff; b++) str += negchar;
return str;
}
function writeBins(numBins,diff)
{
str = strTimes("+",diff) + "[";
for (var i=1; i<numBins; i++)
{
str += ">" + strTimes("+",i+1);
}
str += strTimes("<",numBins-1) + "-]";
str += strTimes("+",diff);
return str;
}
function findClosestBin(val,bins,currbin)
{
var minBin = 0;
for (var b=1; b<bins.length; b++)
{
if (Math.abs(val-bins[b]) < Math.abs(val-bins[minBin])) minBin = b;
}
if (Math.abs(val-bins[minBin]) > Math.abs(val-bins[currbin])) return currbin;
return minBin;
}
function text2BF(textstr, numBins)
{
if (numBins<=0) return "error: too few bins";
var bins = new Array(numBins);
var diff = Math.floor(127/numBins);
for (var i=0; i<numBins; i++) bins[i] = (i + 1) * diff;
var codestr = writeBins(numBins,diff);
var i = 0;
var currbin = 0;
var newbin = 0;
while (i < textstr.length)
{
c = textstr.charCodeAt(i);
newbin = findClosestBin(c,bins,currbin);
codestr += printDifference(newbin-currbin,">","<");
codestr += printDifference(c-bins[newbin],"+","-");
codestr += ".";
currbin = newbin;
bins[newbin] = c;
i++;
}
return codestr;
}
function smartText2BF(textstr, binField)
{
var bestbin = 1;
var results = new Array(16);
var beststr = "";
var resultstr = "";
for (var i=1; i<=16; i++)
{
var str = text2BF(textstr, i);
results[i-1] = str.length;
if (results[i-1] < results[bestbin-1])
{
beststr = str;
bestbin = i;
}
resultstr += i + ": " + results[i-1] + "\n";
}
binField.value = bestbin;
return beststr;
}
</script>
</head>
<body>
<form>
Input:<br>
<textarea name="codestr" rows="4" cols="50" wrap="hard"></textarea><br><br>
Bins (1-10): <input name="numBins" value="5" size="1" type="text">
<input value="Text2BF" onclick="bfout.value = text2BF(codestr.value, numBins.value)" type="button">
<input value="Smart Text2BF" onclick="bfout.value = smartText2BF(codestr.value, numBins)" type="button">
<input value="Interpret" onclick="evalBF(codestr.value,bfout)" type="button"><br><br>
Output:<br>
<textarea name="bfout" rows="6" cols="50"></textarea><br>
</form>
</body>
</html>
Related examples in the same category