Execute Brain****/JavaScript

Revision as of 16:30, 28 January 2009 by rosettacode>Mwn3d (<code>)

Presented here is the core of a Brainf*** interpreter/debugger designed to run within a web page. The full source can be found at http://www.quirkster.com/iano/js/bf.html by viewing the page source.

Execute Brain****/JavaScript is an implementation of Brainf***. Other implementations of Brainf***.
Execute Brain****/JavaScript is part of RCBF. You may find other members of RCBF at Category:RCBF.

var code; // formatted code var ip = 0; // current instruction within code var nest = 0; // current bracket nesting (for Out button) var ahead = []; // locations of matching brackets

var data = [0]; // data array (mod by +, -) var dp = 0; // index into data (mod by <, >)

var inp = 0; // current input character (fetch with ,) var quit = 0; // termination flag

var commands = { '>':function() { if (++dp >= data.length) data[dp]=0 },

	'<':function() { if (--dp < 0) quit++ },
	'+':function() { ++data[dp] },

'-':function() { --data[dp] },

	'[':function() { if (!data[dp]) ip = ahead[ip]; else ++nest },
	']':function() { if ( data[dp]) ip = ahead[ip]; else --nest },
	',':function() {

data[dp] = document.getElementById("input").value.charCodeAt(inp++); if (isNaN(data[dp])) { data[dp]=0; quit++; } // EOF

	},

'.':function() { var s = document.getElementById("output").innerHTML + String.fromCharCode(data[dp]); s = s.replace(/\n/g,"
").replace(/ /g,"&nbsp;"); document.getElementById("output").innerHTML = s; }, };

function format(id) { var el = document.getElementById(id); code = el.value || el.textContent || el.innerText; // scan for matching braces var st = [], back, error = -1; ahead = []; for (ip=0; ip<code.length; ip++) { switch(code[ip]) { case '[': st.push(ip); break; case ']': if (st.length == 0) error = ip; back = st.pop(); ahead[ip] = back; ahead[back] = ip; break; } } if (st.length > 0) error = st[0]; init(); if (error >= 0) { ip = error; // highlight error alert("Unmatched '"+code[error]+"' at "+error+"!"); } // show the code in a PRE block (id=code) dump(); window.scroll(0,document.getElementById("code").offsetTop); }

function encode(s) { var e = s.replace(/&/g, "&amp;"); e = e.replace(/</g, "&lt;"); e = e.replace(/>/g, "&gt;"); e = e.replace(/ /g, "&nbsp;"); return e.replace(/\n/g, "
"); } function dump() { document.getElementById("code").innerHTML = encode(code.substring(0,ip)) + '' + encode(code.charAt(ip)) + "" + encode(code.substring(ip+1)); document.getElementById("mem").value = data.join(); }

function init() { inp = 0; quit = 0; dp = 0; data = [0]; ip = 0; document.getElementById("output").innerHTML = ""; }

function done() { return quit || ip >= code.length; }

function body() {

       var fn;
       do {
         fn = commands[code.charAt(ip)];

if (fn) fn(); ++ip; } while (fn == null && !done()); }

// button handlers

var tid = 0; function step() { var n = document.getElementById("repeat").value - 0;

if (done()) init(); while (--n>=0 && !done()) body();

if (done() && tid) slow(); // stop timer dump(); }

function out() { var d = nest; while (nest>=d && !done()) body(); dump(); }

function slow() { if (tid) { clearInterval(tid); tid = 0; document.getElementById("slow").value = "Slow"; } else { var n = document.getElementById("speed").value - 0; tid = setInterval(step, Math.max(n,10)); document.getElementById("slow").value = "Stop"; } }

function run() { while (!done()) body(); dump(); }