PDA

View Full Version : Ext.util.BF (bf language interpreter/converter)



analpaper
17 Aug 2009, 8:02 PM
Today i was bored enough to write (okok, not without google) some lines:


Ext.util.BF = {

get:function(s,n){ return this.produce(s,n); },

run:function(s,u){ return this.execute(s,u); },

execute: function(src, usr) {
var interpret = function(bf) {
if (typeof bf.out == 'undefined') bf.out = new String();
do {
switch(bf.src[bf.pos.src]) {
case '+':
bf.mem[bf.pos.mem]++;
break;
case '-':
bf.mem[bf.pos.mem]--;
break;
case '>':
bf.pos.mem++;
if (typeof bf.mem[bf.pos.mem] == 'undefined')
bf.mem[bf.pos.mem] = 0;
break;
case '<':
bf.pos.mem--;
break;
case '.':
bf.out += String.fromCharCode(bf.mem[bf.pos.mem]);
break;
case ',':
bf.mem[bf.pos.mem] = (bf.pos.usr==bf.usr.length)
? 0 : bf.usr.charCodeAt(bf.pos.usr++);
break;
case '[':
if (bf.mem[bf.pos.mem] == 0) {
var end = 1;
while(end && bf.pos.src++ < bf.src.length)
if (bf.src[bf.pos.src] == '[') end++;
else if (bf.src[bf.pos.src] == ']') end--;
} else {
var pos = bf.pos.src++;
if ((bf=interpret(bf)).yes) bf.pos.src = --pos;
}
break;
case ']':
bf.yes = (bf.mem[bf.pos.mem] != 0);
return bf;
}
} while (++bf.pos.src < bf.src.length);
return bf.out;
};
return ( (typeof src != 'string')
|| (typeof usr != 'string' && typeof usr != 'undefined')
) ? new String() : interpret({
src: src,
usr: usr || new String(),
mem: [new Number()],
pos: {
src: new Number(),
usr: new Number(),
mem: new Number()
}
});
},

produce:function(str, numStacks) {
if (numStacks<=0 || typeof numStacks == 'undefined')
return this.produceShortest(str);
var writeStacks = function(stack,amount) {
var repeat = function(c,loops) {
var newStr = new String();
for (var i=0; i<loops; i++) newStr += c;
return newStr;
};
var s = repeat("+",amount) + "[";
for (var i=1; i<stack; i++)
s += ">" + repeat("+",i+1);
s += repeat("<",stack-1) + "-]";
s += repeat("+",amount);
return s;
};
var getRange = function(amount,inc,dec) {
var s = new String();
if (amount>0)
for (var i=0; i<amount; i++) s += inc;
else
for (var i=0; i<-amount; i++) s += dec;
return s;
};
var stacks = new Array(numStacks);
var diff = Math.floor(127/numStacks);
for (var i=0; i<numStacks; i++) stacks[i] = (i + 1) * diff;
var src = writeStacks(numStacks,diff);
var i = new Number();
var curStack = new Number();
var newStack = new Number();
while (i < str.length) {
var c = str.charCodeAt(i);
var minStack = 0;
for (var j=1; j<stacks.length; j++)
if (Math.abs(c-stacks[j]) < Math.abs(c-stacks[minStack]))
minStack = j;
if (Math.abs(c-stacks[minStack]) > Math.abs(c-stacks[curStack]))
newStack = curStack;
else newStack = minStack;
src += getRange(newStack-curStack,">","<");
src += getRange(c-stacks[newStack],"+","-");
src += ".";
curStack = newStack;
stacks[newStack] = c;
i++;
}
return src;
},

produceShortest:function(str) {
var products = new Array(16);
var shortStack = new Number(1);
var shortSrc = new String();
for (var i=1; i<=16; i++) {
var src = this.produce(str, i);
products[i-1] = src.length;
if (products[i-1] < products[shortStack-1]) {
shortSrc = src;
shortStack = i;
}
}
return shortSrc;
}
};
You can found more info at: http://www.google.com/search?q=bf+language
For instance, you can test it with:

alert(
Ext.util.BF.run(
Ext.util.BF.get("Hello World!")
)
);
okok, no fun, i see.. better try with:

alert(
Ext.util.BF.run(
prompt(
bf = Ext.util.BF.get("Hello World"),
bf
) ) );
have a nice coding!