Fully featured with loops, input, output and comments.
139bytes!
Chrome and Firefox only
( | |
a, // brainfuck input and later used as brainfuck "register" | |
b, // function to use for user input and output | |
// if any data is passed, it is printed out, | |
// otherwise b returns user input | |
c // placeholder index argument | |
) => eval( | |
// replace every char | |
a.replace( | |
// use regex as register | |
a = /./g, | |
// mapping table from identifiers to javascript | |
d => '1=-~101=~-10while1{0}0c++0c--0b101=b()' | |
// saving some space | |
.replace(/1/g, '(a[c])') | |
.split(0)['+-[]><.,'.indexOf(d)] | |
// add semicolon to separate statements | |
+ ';', | |
// reset index | |
c = 0) | |
) |
(a,b,c)=>eval(a.replace(a=/./g,d=>'1=-~101=~-10while1{0}0c++0c--0b101=b()'.replace(/1/g,'(a[c])').split(0)['+-[]><.,'.indexOf(d)]+';',c=0)) |
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE | |
Version 2, December 2004 | |
Copyright (C) 2013 Johan Hillerström <https://github.com/hillerstorm> | |
Everyone is permitted to copy and distribute verbatim or modified | |
copies of this license document, and changing it is allowed as long | |
as the name is changed. | |
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE | |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | |
0. You just DO WHAT THE FUCK YOU WANT TO. |
{ | |
"name": "brainfuck", | |
"description": "Executes a brainfuck program.", | |
"keywords": [ | |
"brainfuck", | |
"interpreter", | |
"compiler" | |
] | |
} |
<!DOCTYPE html> | |
<title>Brainfuck interpreter</title> | |
<div>Expected Value: <b>Hello World! | |
</b></div> | |
<div>Actual value: <b id="ret"></b></div> | |
<script> | |
var brainfuck = (a,b,c)=>eval(a.replace(a=/./g,d=>'1=-~101=~-10while1{0}0c++0c--0b101=b()'.replace(/1/g,'(a[c])').split(0)['+-[]><.,'.indexOf(d)]+';',c=0)); | |
brainfuck( | |
'++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.', | |
function (output) { | |
// if no output is given, read user input instead | |
if (typeof output === 'undefined') { | |
return prompt().charCodeAt(); | |
} | |
// else buffer the char | |
document.getElementById('ret').innerHTML += String.fromCharCode(output); | |
}); | |
</script> |
The only other way I can imagine to save space would be to use clever mathematics with the charcode (my current approach to do so is woefully as long as the previous implementation):
';'+'1=-~101=~-10while1{0}0b++0b--0i101=i()'.replace(/1/g,'(a[b])').split(0)['+-[]><.,'.indexOf(a[b])]
';'+'while1{00}001=-~101=~-100b++0b--00i101=i()'.replace(/1/g,'(a[b])').split(0)[a[b].charCodeAt()%13]
Maybe we'll find a way to reduce this approach further.
Interesting...
I tried (and failed) with this crazy attempt (163b):
function(a,i,b){eval(eval(a.replace(/./g,"'1=-~101=~-10while1{0}0b++0b--0i101=i()'.replace(/1/g,'(a[b])').split(0)['+-[]><.,'.indexOf('$&')]+';'+")+"''"),a=[b=0])}
every char gets replaced with the whole lookup table and evaled twice :)
I guess I can give up my dream to be able to parse commented code and instead go for 140b by restricting the input to valid BF identifiers :)
We could reluctantly externalize the main command string to go below 140bytes (114, to be precise). It's a bit of a gray area that I have used for my JS syntax highlighter and base64 decoder, too.
function(a,i,s,b,c){for(b in a)c+=';'+s.replace(/1/g,'(a[b])').split(0)['+-[]><.,'.indexOf(a[b])];a=[b=0];eval(c)}
// i=function(b,u){return b==u?prompt().charCodeAt():document.getElementById('output').innerHTML+=String.fromCharCode(b)},
// s='1=-~101=~-10while1{0}0b++0b--0i101=i()'
Let's keep the version with 151bytes as a great learning example, anyway.
It could even be 82b if the command string is the complete array, with the 1's already replaced with a[b]:
function(a,i,s,b,c){for(b in a)c+=';'+s['+-[]><.,'.indexOf(a[b])];a=[b=0];eval(c)}
// s=['a[b]=-~a[b]','a[b]=~-a[b]','while(a[b]){','}','b++','b--','i(a[b])','a[b]=i()']
but that actually feels like too much of a gray area for my taste :D
not at all plug-and-play! as much code outside as there is inside the function
I wholeheartedly agree. Maybe we'll find a solution after all. Until then, we do have a gray area solution and another one that's too big.
Only if one of those chars were in our command array, but it's a valid point anyway.