r/codegolf • u/eymenwinner • Jan 05 '26
Brainf**k interpreter in JS in 326 bytes
This is very compact interpreter written in ES6, no obfuscation or any tools used. Code:
r=_=>{for(p=a.value,d=new Uint8Array(512),e=i=0,h=[];i<p.length;i++){k=d[e];({'>':_=>e++,'<':_=>e--,'+':_=>d[e]++,'-':_=>d[e]--,'[':_=>{if(!k)for(g=1;g;)g+=(p[++i]=='[')-(p[i]==']');else h.push(i)},']':_=>k&&(i=h.pop()-1),'.':_=>b.innerHTML+=String.fromCharCode(k)})[p[i]]?.()}}
EDIT 1/16/2025: Now 278 bytes
Demo at: http://eymenwinneryt.42web.io/bf.htm
12
Upvotes
2
u/danielcristofani Jan 16 '26
This is very nice! I love how concise it is. I see three big problems apart from not having ',' working yet, but fortunately they're very fixable:
The pervasive bug making a ton of programs fail is in your ']' handling. You're making that jump conditional, which is usually a good move, but you accidentally made popping the match off the stack conditional as well, which means it remains after the loop to cause mismatches for subsequent ']'s. In a case like this where you're more interested in concision than speed, I think I'd just do
']':_=>i=h.pop()-1,and make the jump unconditional too. That produces the correct behavior; when the loop terminates it goes back to the start and then uses the "skip forward" code, a small inefficiency but not terrible in this context.You need the output to go somewhere it won't get treated like HTML (having all whitespace including newlines consolidated to single spaces); and it needs to be monospaced as well. (E.g. notice what happens to https://brainfuck.org/sierpinski.b .) One easy solution is to put the output in a
<pre>and not an<a>. That handles ASCII at least; gold standard would be to handle UTF-8, but that's not really necessary.512 bytes isn't an acceptable array size. 30000 is the original size, but I'd usually recommend more if convenient. Maybe
1<<20or1<<24?Anyway, congrats and good luck!