Brainfuck Converter/Interpreter in JavaScript : Brainfuck Converter Interpreter « Security « JavaScript DHTML






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