# Interpret brainfuck

Write the shortest program in your favourite language to interpret a brainfuck program. The program is read from a file. Input and output are standard input and standard output.

1. Cell size: 8bit unsigned. Overflow is undefined.
2. Array size: 30000 bytes (not circled)
3. Bad commands are not part of the input
4. Comments begin with # and extend to the end of line Comments are everything not in +-.,[]<>
5. no EOF symbol

A very good test can be found here. It reads a number and then prints the prime numbers up to that number. To prevent link rot, here is a copy of the code:

compute prime numbers
to use type the max number then push Alt 1 0
===================================================================
======================== OUTPUT STRING ============================
===================================================================
>++++++++[<++++++++>-]<++++++++++++++++.[-]
>++++++++++[<++++++++++>-]<++++++++++++++.[-]
>++++++++++[<++++++++++>-]<+++++.[-]
>++++++++++[<++++++++++>-]<+++++++++.[-]
>++++++++++[<++++++++++>-]<+.[-]
>++++++++++[<++++++++++>-]<+++++++++++++++.[-]
>+++++[<+++++>-]<+++++++.[-]
>++++++++++[<++++++++++>-]<+++++++++++++++++.[-]
>++++++++++[<++++++++++>-]<++++++++++++.[-]
>+++++[<+++++>-]<+++++++.[-]
>++++++++++[<++++++++++>-]<++++++++++++++++.[-]
>++++++++++[<++++++++++>-]<+++++++++++.[-]
>+++++++[<+++++++>-]<+++++++++.[-]
>+++++[<+++++>-]<+++++++.[-]

===================================================================
======================== INPUT NUMBER  ============================
===================================================================
+                          cont=1
[
-                         cont=0
>,
======SUB10======
----------

[                         not 10
<+>                      cont=1
=====SUB38======
----------
----------
----------
--------

>
=====MUL10=======
[>+>+<<-]>>[<<+>>-]<     dup

>>>+++++++++
[
<<<
[>+>+<<-]>>[<<+>>-]<    dup
[<<+>>-]
>>-
]
<<<[-]<
======RMOVE1======
<
[>+<-]
]
<
]
>>[<<+>>-]<<

===================================================================
======================= PROCESS NUMBER  ===========================
===================================================================

==== ==== ==== ====
numd numu teid teiu
==== ==== ==== ====

>+<-
[
>+
======DUP======
[>+>+<<-]>>[<<+>>-]<

>+<--

>>>>>>>>+<<<<<<<<   isprime=1

[
>+

<-

=====DUP3=====
<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]<<<

=====DUP2=====
>[>>+>+<<<-]>>>[<<<+>>>-]<<< <

>>>

====DIVIDES=======
[>+>+<<-]>>[<<+>>-]<   DUP i=div

<<
[
>>>>>+               bool=1
<<<
[>+>+<<-]>>[<<+>>-]< DUP
[>>[-]<<-]           IF i THEN bool=0
>>
[                    IF i=0
<<<<
[>+>+<<-]>>[<<+>>-]< i=div
>>>
-                  bool=0
]
<<<
-                    DEC i
<<
-
]

+>>[<<[-]>>-]<<
>[-]<                  CLR div
=====END DIVIDES====

[>>>>>>[-]<<<<<<-]     if divides then isprime=0

<<

>>[-]>[-]<<<
]

>>>>>>>>
[
-
<<<<<<<[-]<<

[>>+>+<<<-]>>>[<<<+>>>-]<<<

>>

===================================================================
======================== OUTPUT NUMBER  ===========================
===================================================================
[>+<-]>

[
======DUP======
[>+>+<<-]>>[<<+>>-]<

======MOD10====
>+++++++++<
[
>>>+<<              bool= 1
[>+>[-]<<-]         bool= ten==0
>[<+>-]             ten = tmp
>[<<++++++++++>>-]  if ten=0 ten=10
<<-                 dec ten
<-                  dec num
]
+++++++++            num=9
>[<->-]<             dec num by ten

=======RROT======
[>+<-]
<  [>+<-]
<  [>+<-]
>>>[<<<+>>>-]
<

=======DIV10========
>+++++++++<
[
>>>+<<                bool= 1
[>+>[-]<<-]           bool= ten==0
>[<+>-]               ten = tmp
>[<<++++++++++>>>+<-] if ten=0 ten=10  inc div
<<-                   dec ten
<-                    dec num
]
>>>>[<<<<+>>>>-]<<<<   copy div to num
>[-]<                  clear ten

=======INC1=========
<+>
]

<
[
=======MOVER=========
[>+<-]

+++++++[<+++++++>-]<->

=======PUTC=======
<.[-]>

======MOVEL2========
>[<<+>>-]<

<-
]

>++++[<++++++++>-]<.[-]

===================================================================
=========================== END FOR ===============================
===================================================================

>>>>>>>
]
<<<<<<<<

>[-]<
[-]
<<-
]

======LF========

++++++++++.[-]
@


Example run:

$python2 bf.py PRIME.BF Primes up to: 100 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97  • You should clarify about 1) size of memory 2) is memory circled 4) maybe any other details Jan 28, 2011 at 1:37 • I wonder if there should be two categories: Those programs that use eval (or shell out to compile) -- and those that don't. Feb 15, 2011 at 7:52 • I'd love to see someone answer this in brainfuck. Mar 14, 2011 at 19:15 • What does "no EOF symbol" mean? That the cell value remains unchanged when trying , on EOF? Or that it's up to us to choose a value when trying , on EOF? Or is EOF undefined behaviour altogether? Apr 1, 2016 at 14:07 • Likewise, what should happen when someone tries to leave the 30k cells to either side? Should the tape head remain in place or is this undefined behaviour? Apr 1, 2016 at 14:09 ## 67 Answers # Python (no eval), 317 bytes from sys import* def f(u,c,k): while(c[1]>=k)*u: j,u='[]<>+-,.'.find(u[0]),u[1:];b=(j>=0)*(1-j%2*2);c[1]+=b*(j<2) while b*c[c[0]]and j<1:f(u,c,k+1);c[1]+=1 b*=c[1]==k;c[[0,c[0],2][j/2-1]]+=b if(j==6)*b:c[c[0]]=ord(stdin.read(1)) if(j>6)*b:stdout.write(chr(c[c[0]])) f(open(argv[1]).read(),[-1]+[0]*30003,0)  • That is one beautiful piece of noise, sir Dec 6, 2014 at 1:44 • -1 byte if you replace while b*c[c[0]]and j<1 with while b*c[c[0]]*(j<1) Jun 24, 2019 at 7:58 • -2 bytes if you remove the whitespace as well: while(j<1)*b*c[c[0]] Aug 11, 2020 at 21:34 # brainfuck, 843 691 bytes Edit: decided to revisit this and found a surprising number of ways to golf off bytes >>>,[>++++[-<-------->]<-[>+<<]>[----------[>]>[<+<+>>>>]<<<-[>]>[<+<+>>>>]<<<-[>]>[<+<+>>>>]<<<-[>]>[<-<+++>>>>]<<<--------------[>]>[<++<+>>>>]<<<--[>]>[<-<+++++++>>+>>]<<++++[-<------>]+<+[>]>[<++<+>>>>]<<<--[>]>[<<+>>>>]<<-<[+]<[>]>,>]<]<-[<]>[-[<<]>[<+[>]>>[<+[<<[<]<<-[>>]<[>>>>[>]>+<<[<]<]<-[>>]<[>>>>[>]>-<<[<]<]<++[->>+<<]>>[>]>]]<<<[<]>-<]>-[<<]>[<++[>]>+>[<-]<[<<[<]>[-<<+>>]>--[<<]>[[>]>+<<[<]<]>+[<<]>[[>]>-<<[<]<]>+[>]>]<<[<]>--<]>-[<<]>[[>]>>.<<<[<]<]>-[<<]>[[>]>>-<<<[<]<]>-[<<]>[[>]>>,<<<[<]<]>-[<<]>[[>]>>+<<<[<]<]>-[<<]>[[>]>>>[>>]>[<<<[<<]<+>>>[>>]>-]>[-]<<+[<[->>+<<]<]<[->>+<<]<[<]<]>-[<<]>[[>]>-[+>[-<<+>>]>]+<<[-]+[-<<]<[->>>[>>]>+<<<[<<]<]<[<]<]<++++++++>>[+<<->>]>]  This takes input in the form code!input where the !input is optional. It also simulates negative cells without using negative cells itself and can store up to (30000-(length of code+6))/2 cells. Try it online! • Just to make sure I got this right, if I ran this program with this program I could nest it 5 levels deep and still handling code-inputs of length 262. Oct 1, 2019 at 21:46 • @Draco18s I suspect you'd run out the 30000 cells before that, since the size of each nested interpreter increases exponentially. I think you'd get 2, maybe 3 levels deep – Jo King Oct 1, 2019 at 23:03 • Even 3 deep would be hilariously silly. Oct 2, 2019 at 2:34 • It seems to only work two layers deep, 3 just makes it hang Sep 5, 2020 at 1:47 • @the-cobalt It's not hanging, it's just taking an extremely long time. On copy.sh, it takes a mere 50 minutes to execute that program – Jo King Sep 5, 2020 at 6:54 ## 16 bit 8086 machine code: 168 bytes Here's the base64 encoded version, convert and save as 'bf.com' and run from Windows command prompt: 'bf progname' gMYQUoDGEFKzgI1XAgIfiEcBtD3NIR8HcmOL2LQ/i88z0s0hcleL2DPA86sz/zP2/sU783NHrL0I AGgyAU14DTqGmAF194qOoAH/4UfDJv4Fwyb+DcO0AiaKFc0hw7QBzSGqT8MmODV1+jPtO/NzDaw8 W3UBRTxddfJNee/DJjg1dPoz7U509YpE/zxddQFFPFt18U157sM+PCstLixbXUxjTlJWXmV+  EDIT Here's some assembler (A86 style) to create the executable (I had to reverse engineer this as I'd misplaced the original source!)  add dh,10h push dx add dh,10h push dx mov bl,80h lea dx,[bx+2] add bl,[bx] mov [bx+1],al mov ah,3dh int 21h pop ds pop es jb ret mov bx,ax mov ah,3fh mov cx,di xor dx,dx int 21h jb ret mov bx,ax xor ax,ax repz stosw xor di,di xor si,si inc ch program_loop: cmp si,bx jnb ret lodsb mov bp,8 push program_loop symbol_search: dec bp js ret cmp al,[bp+symbols] jnz symbol_search mov cl,[bp+instructions] jmp cx forward: inc di ret increment: inc b es:[di] ret decrement: dec b es:[di] ret output: mov ah,2 mov dl,es:[di] int 21h ret input: mov ah,1 int 21h stosb backward: dec di ret jumpforwardifzero: cmp es:[di],dh jnz ret xor bp,bp l1: cmp si,bx jnb ret lodsb cmp al,'[' jnz l2 inc bp l2: cmp al,']' jnz l1 dec bp jns l1 ret jumpbackwardifnotzero: cmp es:[di],dh jz ret xor bp,bp l3: dec si jz ret mov al,[si-1] cmp al,']' jnz l4 inc bp l4: cmp al,'[' jnz l3 dec bp jns l3 ret symbols: db '><+-.,[]' instructions: db forward and 255 db backward and 255 db increment and 255 db decrement and 255 db output and 255 db input and 255 db jumpforwardifzero and 255 db jumpbackwardifnotzero and 255  • I've added a source code version of the program. I've just noticed that non-bf characters cause the program to exit rather than be ignored. Easy to fix that and I'll leave it as an exercise for people to do that themselves. Aug 14, 2012 at 13:18 • I remember I got the Linux ELF version 166 bytes, 10 years ago, here muppetlabs.com/~breadbox/software/tiny Jul 28, 2014 at 17:34 ## Perl, 120 138 %c=qw(>$p++ < $p-- + D++ - D-- [ while(D){ ] } . print+chrD , D=ord(getc));$/=$,;$_=<>;s/./$c{$&};/g;s[D]'$b[$p]'g;eval


This runs hello.bf and primes.bf flawlessly:

$perl bf.pl hello.bf Hello World!$ perl bf.pl prime.bf
Primes up to: 100
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97


Initialization: The opcode to Perl translation table is stored in %c. The readable form looks like this:

%c=(
'>' => '$p++', '<' => '$p--',
'+' => '$b[$p]++',
'-' => '$b[$p]--',
'[' => 'while($b[$p]){',
']' => '}',
'.' => 'print chr$b[$p]',
',' => '$b[$p]=ord(getc)',
);


Step 1: Slurp program input to $_ and transform it to Perl code using the translation table. Comments are automatically stripped (replaced with undef) in this step. Step 2: Uncompress all $b[$p] occurrences Step 3: Launch the program using eval. • Just use Perl's qw syntax to define %c directly -- good for 7 fewer chars (you'll have to say print+chr$b[$p] and ord(getc), though) – mob Sep 11, 2012 at 23:36 • I count 18 saved… thanks! (updating in a minute) – J B Sep 12, 2012 at 8:19 • The %c table is declared and defined in the first line; its characters are perfectly accounted for. – J B Sep 19, 2012 at 13:46 • Someone called "Grimy" did it on 105 bytes when competing at this competition (web.archive.org/web/20131113171000/http://codegolf.com/…) How to reach Grimy ? Do you know him ? – YOGO Jun 15 at 23:06 # Vim, 809 580 bytes -229 bytes because shenanigans and balderdash. qq<C-v><C-v><C-v>q<Esc>^mbO<C-r>q elsei "<C-r>q<C-r>c"=="<Esc>^"xc$<C-r>q
norm <Esc>^"zc$en<C-r>q <Esc>^"yd$ib"cyl:if "<C-v><C-r>c"==">"<C-r>z@f<C-r>x<"<C-r>z@b<C-r>x+"<C-r>z@i<C-r>x-"<C-r>z@d<C-r>x,"<C-r>z@p<C-r>x."<C-r>z@o<C-r>x["<C-r>z@s<C-r>x]"<C-r>z@l<C-v>
<C-r>yblmb@e<Esc>^"ec$b^mbjj30000ddk30000o0<C-v><Esc>jjmolk$doxbjjmpljmib<Esc>^"rc$p:if line(".")<30002<C-r>zj<C-v> <C-r>ymp<Esc>^"fc$p:if line(".")>3<C-r>zk<C-v>
<C-r>ymp<Esc>^"bc$p<C-v><C-a>Y:if <C-v><C-r>"<C-v><C-h>>255<C-r>z<C-v><C-x><C-v> <C-r>y<Esc>^"ic$p<C-v><C-x>Y:if <C-v><C-r>"<C-v><C-h><0<C-r>z<C-v><C-a><C-v>
<C-r>y<Esc>^"dc$i"qxp:if "<C-v><C-r>""!="<C-r>q<Esc>"<C-r>z3xi<C-r>q<C-r>=char2nr("<C-r>q<C-r>q")<C-r>q <C-r>q<Esc><C-v> else<C-r>zi3i<C-v><C-v><Esc>a<C-v><Esc><C-r>q<Esc><C-v> <C-r>y<Esc>^"pc$py$oA<C-v><C-r>=nr2char(<C-v><C-r>")<C-v> <C-v><Esc>$mo<Esc>^"oc$py$b:if <C-v><C-r>"==0<C-r>z%mb<C-v>
<C-r>y<Esc>^"sc$py$b:if <C-v><C-r>"!=0<C-r>z%mb<C-v>
<C-r>y<Esc>^"ld$ddo<Esc>90i-<Esc>30000o0<Esc>o<Esc>90i-<Esc>o<Esc>moo<Esc>ml90i-<Esc>o<C-v><Esc><Esc>mio<Esc>90i-<Esc>bjjmp  Try it online! More than just an interpreter, this sets up an environment for programming in brainfuck with the following format: brainfuck program ------------------------------------------------------------------- list of 30000 memory cells ------------------------------------------------------------------- program output ------------------------------------------------------------------- program input ^[ -------------------------------------------------------------------  It also sets up some macros: • @f - > moves the MP forward • @b - < moves the MP backward • @i - + increments the cell at the MP • @d - - decrements the cell at the MP • @p - , input a character and store it in the cell at the MP • @o - . output the signified by the cell at the MP • @s - [ start while loop • @l - ] end while loop • @e - Execute. Recursively get the command at the IP and call the corresponding macro if it is a valid command, then increment the IP. • @r - Reset. Clear the output, reset all memory cells, and move the IP back to the beginning of the program. If using the TIO link, the input box is where the program goes to be executed. To pass input to the brainfuck program, add this to the footer before anything else: iiYour Input Here<Esc>. Additionally, I added gg30003ddl3dd to the footer to strip away everything except the brainfuck program's output, so you can remove that from the footer to see the entire result. If using Vim, copy the TIO code and paste it into Vim to set up the environment. From there, you can use b to jump to the brainfuck program, p to jump to the MP, o to jump to the output, and i to jump to the input. A few caveats: • The environment does not support newlines in the program, so the brainfuck program must be a single line. • The input must be terminated with <Esc>. The setup code automatically puts the <Esc> in the input section, so just make sure that the input goes before the ^[. • To "read the program from a file", as it were, you can use Vim to open a file containing the brainfuck program and paste this code to set everything up and then execute it, as long as the program is already in a single line. • It's kinda slow. The test program for finding primes took ~2 minutes to finish with n=2. It took ~10 minutes with n=7. I didn't even bother trying anything higher. Nevertheless, it works. Note: This is the second version, and is golfed much further than the original, but I could almost certainly get it even shorter by defining the macros as macros instead of deleting into named registers. However, that will require pretty much rewriting this entire program, which I just golfed into illegibility, so I don't feel like doing it right now, but I might do it some time later. • what in the world.. Apr 20, 2021 at 14:32 • I've been delaying learning vim for quite some time now, I have to learn vim after seeing this answer – user100752 Jun 20, 2021 at 16:54 # Binary Lambda Calculus 112 The program shown in the hex dump below 00000000 44 51 a1 01 84 55 d5 02 b7 70 30 22 ff 32 f0 00 |DQ...U...p0".2..| 00000010 bf f9 85 7f 5e e1 6f 95 7f 7d ee c0 e5 54 68 00 |....^.o..}...Th.| 00000020 58 55 fd fb e0 45 57 fd eb fb f0 b6 f0 2f d6 07 |XU...EW....../..| 00000030 e1 6f 73 d7 f1 14 bc c0 0b ff 2e 1f a1 6f 66 17 |.os..........of.| 00000040 e8 5b ef 2f cf ff 13 ff e1 ca 34 20 0a c8 d0 0b |.[./......4 ....| 00000050 99 ee 1f e5 ff 7f 5a 6a 1f ff 0f ff 87 9d 04 d0 |......Zj........| 00000060 ab 00 05 db 23 40 b7 3b 28 cc c0 b0 6c 0e 74 10 |....#@.;(...l.t.| 00000070  expects its input to consist of a Brainfuck program (looking only at bits 0,1,4 to distinguish among ,-.+<>][ ) followed by a ], followed by the input for the Brainfuck program. Save the above hex dump with xxd -r > bf.Blc Grab a blc interpreter from https://tromp.github.io/cl/cl.html cc -O2 -DM=0x100000 -m32 -std=c99 uni.c -o uni echo -n "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.]" > hw.bf cat bf.Blc hw.bf | ./uni  Hello World! • Why does this even exist? Apparently, it even exists in the realm of research. O.o Dec 4, 2014 at 4:11 • So this wouldn't work with commented brainfuck programs? Feb 15, 2018 at 20:05 • No, not without stripping out the comments first. Feb 16, 2018 at 22:27 # Ruby 1.8.7, 188185149 147 characters eval"a=[i=0]*3e4;"+$<.bytes.map{|b|{?.,"putc a[i]",?,,"a[i]=getc",?[,"while a[i]>0",?],"end",?<,"i-=1",?>,"i+=1",?+,"a[i]+=1",?-,"a[i]-=1"}[b]}*";"


code = "a = [0] * 3e4; i = 0;"
more_code ARGF.bytes.map {|b|
replacements = {
?. => "putc a[i]",
?, => "a[i] = getc",
?[ => "while a[i] > 0 do",
?] => "end",
?< => "i -= 1",
?> => "i += 1",
?+ =>"a[i]+=1",
?- =>"a[i]-=1"
}
replacements[b]
}.join(";")
eval code+more_code


As you see I shamelessly stole your idea of translating to the host language and then using eval to run it.

• You can shave off a byte byte comparing to zero >0 rather than testing equality: !=0. The specs say unsigned, and overflow is undefined. Feb 6, 2011 at 5:32
• 3e4 will also work as opposed to 30000 Feb 6, 2011 at 5:36
• @Charlie: Thanks. Though to be fair it didn't say "unsigned" when I wrote the code. I honestly didn't know that you could write 3e4 though. That's a very good point and good to know. Feb 6, 2011 at 5:40
• File.read($*.pop).bytes -> $<.bytes should work too Feb 12, 2011 at 22:31
• Ruby 1.8.7 has an even shorter syntax to build a literal hash: {?a,"foo"}, which is equivalent to {?a=>"foo"}. And testing here shows that you actually can replace File.read($*.pop).bytes with $< without any problems. Also inlining everything to something like eval"a[0]..."+$<.bytes.map{?.,"putc a[i]",...}*";" shortens the solution by another few characters. Feb 14, 2011 at 15:58 # Retina 0.8.2, 386391 386 bytes Code contains unprintable NUL (0x00) characters. It's also not super golfed yet, because it's already really slow, and if I golf it more, I don't know how long it'd take to finish. Appears to time out on the prime-finding sample. There may be bugs in the online interpreter or in my program (leading new lines don't show in the output?). Takes input like <code>│<input>. No, that is not a pipe (|). It's the Unicode character U+2502. The code also uses the Unicode characters ÿ▶◀├║. Unicode characters are used in order to support input of all ASCII characters. Therefore, these characters need to be separated from the code by a non-ASCII character. Try it online s^.* ▶$0├║▶
s{(▶>.*║.*)▶(.)(.?)
$1$2▶$3 ▶$
▶
║▶
║▶
(▶<.*║.*)(.)▶
$1▶$2
Tÿ-o(?<=▶\+.*║.*▶).
^\+

T-ÿÿo(?<=▶-.*║.*▶).
^-

(▶\..*├.*)(║.*▶)(.)
$1$3$2$3
(▶,.*│)(.?)(.*├.*▶).
$1$3$2 ▶$(.*║.*▶) [▶▶{1} {(▶▶+)([^[$]*)$2[1▶ }▶(▶+)([^[$]*)\]$2]$1 r([[\]]*)▶\](.*║.*▶[^])$1◀◀]$2 r{$([^[$]*)(◀+)◀$2[$1 }\]([^[\]]*)(◀◀+)$2◀]$1 ◀ ▶ }▶([^│])(.*║)$1▶$2 s\.*├|║.*  Note there is a trailing newline there. ### Brief Explanation: Zeros 0x00 are used for the tape, which is infinite. The first replacement sets up the interpreter in the form ▶<code>│<input>├<output>║▶<tape>, where the first ▶ is the pointer for the code, and the second one is the pointer for the tape. ÿ is 0xFF (255), which is used for Transliteration (used to implement + and -) to wrap the cells back around to zero. ◀ is only used for readability (in case the program is stopped in the middle or you want to see the program mid-execution). Otherwise, you couldn't tell which way the pointer was moving. ### Commented Code: s^.* # Initialize ▶$0├║▶
s{(▶>.*║.*)▶(.)(.?)        # >
$1$2▶$3 ▶$
▶
║▶                          # <
║▶
(▶<.*║.*)(.)▶
$1▶$2
Tÿ-o(?<=▶\+.*║.*▶).      # +
^\+

T-ÿÿo(?<=▶-.*║.*▶).      # -
^-

(▶\..*├.*)(║.*▶)(.)         # .
$1$3$2$3
(▶,.*│)(.?)(.*├.*▶).        # ,
$1$3$2 ▶$(.*║.*▶) # [ [▶▶{1} {(▶▶+)([^[$]*)$2[1▶ }▶(▶+)([^[$]*)\]$2]$1 r([[\]]*)▶\](.*║.*▶[^]) # ]$1◀◀]$2 r{$([^[$]*)(◀+)◀$2[$1 }\]([^[\]]*)(◀◀+)$2◀]$1 ◀ ▶ }▶([^│])(.*║) # next instruction$1▶$2 s\.*├|║.* # print output  Click here for the code with zeros in place of null bytes. Any occurrences of $0 should not be replaced with nulls.

Edit: Now supports empty input and suppresses trailing newline.

Infinite output is now supported. (403 bytes)

• I kind of wish that I'd placed the <code> and the <tape> next to each other (though it'd be more characters) so that transitioning to an SMBF interpreter would be easier, if I ever decide to do that. Jul 20, 2016 at 16:43

## Conveyor, 953

This might be the most beautiful code you will ever see:

0

:I\1\@p
>#====)
^#====<
PP0
P<=======================<
00t:)01t1  a:P:P:P:P:P:P:^
>===========">">2>">2>">"^
^           +^-^5^ ^5^]^.^
^           "^"^*^"^*^"^"^
^           -^-^6^-^6^-^-^
^           #^#^*^#^*^#^#^
^           P P -^P )^P P
^           P P #^P )^P P
^t1\)t0:))t01   P   -^  1
^===========<   P   #^  0
^  t1\(t0:))t01     P   t
^=============<     P   )
^         t11(t01   0 0 )
^===============<. t P 10
^                 FT#T#=<
^=================< P
^             t11)t01
^===================< 10t))0tP00t:(01t(1a:P:
^                     >=====#=>==========">"
^                             ^          ]^[
^                           P ^          "^"
^===========================<=^#=====<   -^-
^==<     ^ PP#^#=
^===PTPT<
^  )P P
^=<=< (
^===<

• Could you add an explanation and a link to an implementation? I want to understand the beauty. ;) May 12, 2015 at 22:47
• Well, I'm currently developing it, there is a compiler and a very bad explanation at github.com/loovjo/Conveyor. The source is pretty readable if you want to understand it. May 13, 2015 at 8:30

import IO
import System
z=return
'>'#(c,(l,d:r))=z(d,(c:l,r))
'<'#(d,(c:l,r))=z(c,(l,d:r))
'+'#(c,m)=z(succ c,m)
'-'#(c,m)=z(pred c,m)
'.'#t@(c,_)=putChar c>>hFlush stdout>>z t
','#(_,m)=getChar>>=(\c->z(c,m))
_#t=z t
_%t@('\0',_)=z t
i%t=i t>>=(i%)
b('[':r)=k$b r b(']':r)=(z,r) b(c:r)=f(c#)$b r
b[]=(z,[])
f j(i,r)=(\t->j t>>=i,r)
k(i,r)=f(i%)$b r main=getArgs>>=readFile.head>>=($('\0',("",repeat '\0'))).fst.b


This code "compiles" the BF program into an IO action of the form State -> IO State the state is a zipper on an infinite string.

Sad that I had to expend 29 characters to turn buffering off. Without those, it works, but you don't see the prompts before you have to type input. The compiler itself (b, f, and k) is just 99 characters, the runtime (# and %) is 216. The driver w/initial state another 32.

>ghc -O3 --make BF.hs
[1 of 1] Compiling Main             ( BF.hs, BF.o )

>./BF HELLO.BF
Hello World!

>./BF PRIME.BF
Primes up to: 100
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97


update 2011-02-15: Incorporated J B's suggestions, did a little renaming, and tightened up main

• You should be able to get the buffering from just IO, and the arguments from just System (-19). The buffering issue bothers me as well, as the spec doesn't really mention it and the top-voted answer doesn't even do I/O. If you must keep it, it's probably shorter to hFlush after each write than change the global buffering mode (-34+15).
– J B
Feb 15, 2011 at 10:49

## Python 275248 255

I decided to give it a try.

import sys
i=0
b=[0]*30000
t=''
i+=(92-ord(e))*(e in'][')
exec t

• Neat, you are generating python source code using brainfuck.
– user11
Jan 30, 2011 at 2:00
• You may strip 1 char, "import sys as s" and replace "sys" to "s" in the rest
– YOU
Feb 6, 2011 at 6:52
• Note that this is actually 247 chars. (See the nasty space after exec t?). If you use S.Mark's tip and also make the whole for cycle into one line, you can shrink this to 243 chars. Apr 4, 2011 at 15:18
• I wrote a 227 character version of this in python myself, and there are a few tricks you could use to shorten your code. Rather than storing the number of indents in i, and incrementing/decrementing i, you can store the indent itself, which takes exactly as many characters to update (i=i[e==']':]+' '[e!='[':]), and saves you from doing i*' ', and lets you do i=t=''. Rather than storing '' as the last item in the array, you can keep pass as the last one, which translates any non-operation into pass, which works fine. Everything else I did has been suggested already. Oct 20, 2012 at 5:42
• I'd +1, but many improvements have been suggested and not implemented. Nov 15, 2016 at 17:01

# C (gcc) Linux x86_64, 884 621 525 487 439 383 358 352 bytes

*z,*mmap();d[7500];(*p)();*j(a,g)char*a;{char*t=a,*n,c,q=0;for(;read(g,&c,!q);t=c==47?n=j(t+9,g),z=mempcpy(t,L"\xf003e80Ƅ",5),*z=n-t-9,n:c==49?q=*t++=233,z=t,*z=a-13-t,z+1:stpcpy(t,c-18?c-16?~c?c-1?c-2?c?"":"1\xc0P_\xF\5":"RXR_\xF\5":L"໾":L"۾":L"컿":L"웿"))c-=44;return t;}main(P,g)int**g;{p=mmap(0,1<<20,6,34,0,0);p(*j(p,open(g[1],0))=195,d,1);}


Try it online!

This is a JIT that compiles BF code into x86_64 machine language at runtime. This performs a straight translation so commonly occurring sequences such as >>>, <<<, +++ and --- aren't coalesced into faster instructions.

Less golfed version:

// size of data area
*z,c,*mmap();d[7500];(*p)();
// recursive function translates BF commands to x86_64 instructions
*j(a,g)char*a;{
char*t=a,*n,q=0;
c-=44,
t=c==47? // [
// cmpb $0x0,(%rsi) // je n-t-9 n=j(t+9,g), z=mempcpy(t,L"\xf003e80Ƅ",5) *z=n-t-9, n : c==49? // ] // jmp a-13-t q=*t++=233, z=t, *z=a-13-t, z+1 : stpcpy(t,c-18? // > c-16? // < ~c? // + c-1? // - c-2? // . c? // , "" : // xor %eax,%eax // push %rax // pop %rdi // syscall "1\xc0P_\xF\5" : // push %rdx // pop %rax // push %rdx // pop %rdi // syscall "RXR_\xF\5" : // decb (%rsi) L"໾" : // incb (%rsi) L"۾" : // dec %esi L"컿" : // inc %esi L"웿"); return t; } main(P,g)int**g;{ // allocate text (executable) memory and mark as executable p=mmap(0,1<<20,6,34,0,0); // run JIT, set %rdx=1 and call code like a function p(*j(p,open(g[1],0))=195,d,1); }  # Brainfuck, 948 bytes Well, that took a while. I golfed a Brainfuck self-interpreter by ... not me. ->->>>-[,+>+<[->-]>[->]<+<-------------------------------------[+++++++++++++++++++++++++++++++++++++>-]>[->]<<[>++++++++[-<----->]<---[-[-[-[--------------[--[>+++++++[-<---->]<-[--[[+]->]<+[->++>]->]<+[->+>]->]<+[->+++++>]->]<+[->++++++>]->]<+[->+++++++>]->]<+[->++++>]->]<+[->++++++++>]->]<+[->+++>]->]+<+[->->]>[-<->]<]>>->>-<<<<<+++[<]>[-[-[-[-[-[-[-[-<<++++++++>>>[>]>>>>+[->>+]->,<<<+[-<<+]-<<<[<]<]>[<<<+++++++>>>[>]>>>>+[->>+]->.<<<+[-<<+]-<<<[<]]<]>[<<<++++++>>>[>]>>>>+[->>+]<<-<<+[-<<+]-<<<[<]]<]>[<<<+++++>>>[>]>>>>+[->>+]+>>-<<[-<<+]-<<<[<]]<]>[<<<++++>>>[>]>>>>+[->>+]->-<<<+[-<<+]-<<<[<]]<]>[<<<+++>>>[>]>>>>+[->>+]->+<<<+[-<<+]-<<<[<]]<]>[<++[>]>>>>+[->>+]->[<<<+[-<<+]-<<<[<]-[<<-[>->-[<+]]<+[->>[<]]<-[>-->+[<++]]<++[-->>[<]]<++>>[[-<+>]<<[->>+<<]]<[>]>]]<[<<+[-<<+]-<<<[<]>--<<++>]>]<]>[<<<+>>>[>]>>>>+[->>+]->[<<<+[-<<+]-<<<[<]]<[<<+[-<<+]-<<<[<]+[>-[<-<]<<[>>]>>-[<+<]<<[>>]>>++<[>[-<<+>>]<[->+<]]<[>]>]]>[[-<<+>>]<[->+<]>]]>]  # CJam, 75 bytes lq3e4Vc*@{"-<[],.+>"#"T1$T=(t T(:T; { _T=}g \0+(@T@t _T=o "_'(')er+S/=}%s~@


Try it online: string reverser, Hello World.

## Explanation

Takes code on the first line of STDIN and input on all lines below it.

l            Read a line from STDIN (the program) and push it.
q           Read the rest of STDIN (the input) and push it.
3e4Vc*     Push a list of 30000 '\0' characters.
@    Rotate the stack so the program is on top.

{               }%   Apply this to each character in prog:
"-<[],.+>"#         Map '-' to 0, '<' to 1, ... and everything else to -1.
...=     Push a magical list and index from it.

s~       Concatenate the results and evaluate the resulting string as CJam code.
@      Rotate the top three elements again -- but there are only two, so the
program terminates.


"T1$T=(t T(:T; { _T=}g \0+(@T@t _T=o " Space-separated CJam snippets. (Note the final space! We want an empty string at the end of the list.) _'(')er+ Duplicate, change (s to )s, append. S/ Split over spaces.  The resulting list is as follows: T1$T=(t    (-)
T(:T;      (<)
{          ([)
_T=}g      (])
\0+(@T@t   (,)
_T=o       (.)
T1$T=)t (+) T):T; (>) { (unused) _T=}g (unused) \0+(@T@t (unused) _T=o (unused) (all other characters)  We generate the snippets for + and > from those for - and <, simply by changing left parens (CJam’s “decrement”) into right parens (CJam’s “increment”). • Shortest answer & biggest winner May 15, 2018 at 0:32 # TypeScript Types, 1807 1771 bytes //@ts-ignore type B<X="\0\x01\x02\x03\x04\x05\x06\x07\b\t\n\v\f\r\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_abcdefghijklmnopqrstuvwxyz{|}~\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",a=[]>=X extends${infer A}${infer C}?B<C,[...a,A]>:a;type C={[K in keyof B&${number}as B[K]]:D<K>};type D<T,A=[]>=T extends${A["length"]}?A["length"]:D<T,[0,...A]>;type E<A=[]>=255 extends A["length"]?[...A,0]:E<[...A,[...A,0]["length"]]>;type F=[255,0,...E];type G<L,D=never>=L extends[infer A,{}]?A:D;type H<L,D=never>=L extends[{},infer B]?B:D;type M<a,b,c=0,d="",e=0,f=0,g=0,h=0,i=[],>=a extends${infer j}${infer a}?h extends 0?j extends"+"?M<a,b,c,d,e,E<[]>[f],g>:j extends"-"?M<a,b,c,d,e,F[f],g>:j extends"<"?e extends 0?M<a,b,c,d,e,f,g>:M<a,b,c,d,H<e>,G<e>,[f,g]>:j extends">"?M<a,b,c,d,[f,e],G<g,0>,H<g,[]>>:j extends"["?f extends 0?M<a,b,c,d,e,f,g,1>:M<a,b,[a,c],d,e,f,g>:j extends"]"?f extends 0?M<a,b,H<c>,d,e,f,g>:M<G<c>,b,c,d,e,f,g>:j extends","?b extends${infer k}${infer b}?M<a,b,c,d,e,k extends keyof j?j[k]:0,g>:M<a,b,c,d,e,0,g>:j extends"."?M<a,b,c,${d}${B[f]},e,f,g>:M<a,b,c,d,e,f,g>:j extends"]"?M<a,b,c,d,e,f,g,G<i,0>,H<i,[]>>:j extends"["?M<a,b,c,d,e,f,g,1,[1,i]>:M<a,b,c,d,e,f,g,h,i>:d


Try it online!

Ungolfed / Explanation

• How does this work? Nov 28, 2021 at 18:35

## C 284 362 (From a file)

#include <stdio.h>
char b[30000],z[9999],*p=b,c,*a,i;f(char*r,int s){while(c=*a++){if(!s){(c-62)?(c-60)?(c-43)?(c-45)?(c-46)?(c-44)?0:(*p=getchar()):putchar(*p):--*p:++*p:--p:++p;if(c==91)f(a,!*p);else if(c==93){if(!*p)return;else a=r;}}else{if(c==93){--s;if(!*p&&!s)return;}else if(c==91){s++;}}}}main(int c,char**v){fread(z,1,9999,fopen(*++v,"r"));a=z;f(0,0);}


Primes:

Primes up to: 100
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
Press any key to continue . . .


Compiled and ran successfully VS2008

Original solution failed to recognize loops that were initially set to zero. Still some room to golf. But finally solves the Prime Number program.

Ungolfed:

#include <stdio.h>
char b[30000],z[9999],*p=b,c,*a,i;
f(char*r,int s)
{
while(c=*a++)
{
if(!s)
{
(c-62)?(c-60)?(c-43)?(c-45)?(c-46)?(c-44)?0:(*p=getchar()):putchar(*p):--*p:++*p:--p:++p;
if(c==91)f(a,!*p);
else if(c==93){if(!*p)return;else a=r;}
}
else
{
if(c==93)
{
--s;
if(!*p&&!s)return;
}
else if(c==91)
{
s++;
}
}
}
}

main(int c,char**v){
a=z;
f(0,0);
}


Tests:

Hello World

Rot13

• Are you checking the same pointer (l) every time you loop? I think you are supposed to check the current location of the head (p). Jan 30, 2011 at 19:51
• I pass the pointer to the buffer and the pointer to the stream. It checks at the end of the loop to see if the pointer l in the buffer has reached zero and breaks else it resets the stream back to the original loop [. This is necessary for nested [ loops. Jan 30, 2011 at 20:00
• Yeah. I thought so. You should not check the value at pointer at first enter in the loop, but the value at the current pointer. Check the test in the question. Your program hangs. Jan 30, 2011 at 20:10
• You can replace break;else by return;. Jan 30, 2011 at 20:56
• I think you can replace (c==62)?a:b with (c-62)?b:a. Jan 30, 2011 at 22:01

## PHP 5.4, 296294273263261209191183178 166 characters:

I gave it a shot without using eval, but I eventually had to use it

<?$b=0;eval(strtr(cat$argv[1],["]"=>'}',"["=>'while($$b){',"."=>'echo chr($$b);',","=>'$$b=fgetc(STDIN);',"+"=>'$$b++;',"-"=>'b--;',">"=>'$b++;',"<"=>'$b--;']));


All commands are working. This heavily abuses variable variables, and spews warnings. However, if one changes their php.ini to squelch warnings (or pipes stderr to /dev/null), this works great.

Verification (It's the "Hello World!" example from Wikipedia): http://codepad.viper-7.com/O9lYjl

Ungolfed, 367 365 335 296 267 characters:

<?php
$a[] =$b = 0;
$p = implode("",file($argv[1])); // Shorter than file_get_contents by one char
$m = array("]" => '}', "[" => 'while($a[$b]){',"." => 'echo chr($a[$b]);', "," => '$a[$b]=fgetc(STDIN);', "+" => '$a[$b]++;', "-" => '$a[$b]--;', ">" => '$b++;', "<" => '$b--;');$p = strtr($p,$m);
@eval($p);  This should be run via the command line: php bf.php hello.bf ## Windows PowerShell, 204 '$c=,0*3e4;'+@{62='$i++ ';60='$i--
';43='$c[$i]++
';45='$c[$i]--
';44='$c[$i]=+[console]::ReadKey().keychar
';46='write-host -n([char]$c[$i])
';91='for(;$c[$i]){';93='}'}[[int[]][char[]]"$(gc$args)"]|iex


Fairly straightforward conversion of the instructions and then Invoke-Expression.

History:

• 2011-02-13 22:24 (220) First attempt.
• 2011-02-13 22:25 (218) 3e4 is shorter than 30000.
• 2011-02-13 22:28 (216) Unnecessary line breaks. Matching on integers instead of characters is shorter.
• 2011-02-13 22:34 (207) Used indexes into a hash table instead of the switch.
• 2011-02-13 22:40 (205) Better cast to string removes two parentheses.
• 2011-02-13 22:42 (204) No need for a space after the argument to Write-Host.

## C, 333 characters

This is my first BF interpreter and the first golf I actually had to debug.

This runs the prime number generator on Mac OS X/GCC, but an additional #include<string.h> may be necessary at a cost of 19 more characters if the implicit definition of strchr doesn't happen to work on another platform. Also, it assumes O_RDONLY == 0. Aside from that, leaving int out of the declaration of M saves 3 characters but that doesn't seem to be C99 compliant. Same with the third * in b().

This depends on the particulars of ASCII encoding. The Brainfuck operators are all complementary pairs separated by a distance of 2 in the ASCII code space. Each function in this program implements a pair of operators.

#include<unistd.h>
char C[30000],*c=C,o,P[9000],*p=P,*S[9999],**s=S,*O="=,-\\",*t;
m(){c+=o;}
i(){*c-=o;}
w(){o<0?*c=getchar():putchar(*c);}
b(){if(o>0)*c?p=*s:*--s;else if(*c)*++s=p;else while(*p++!=93)*p==91&&b();}
int(*M[])()={m,i,w,b};
main(int N,char**V){
while(o=*p++)
if(t=strchr(O,++o&~2))
o-=*t+1,
M[t-O]();
}

• I think you can shrink it more by using the 'e' notation for all the big numbers. Aug 16, 2011 at 4:34
• @luser: I was initially surprised too, but the language and compiler won't allow that. I did manage to shrink another 4 chars with tweaks, and using a #define instead of the function table would also probably be terser. I just like the number 333 and the table :v) . Aug 16, 2011 at 5:56
• Oh, right. I really should've known that. E-notation is in the production for a floating-point constant, whereas a declaration requires an integer. BTW, this may be cheating, but check out nieko.net/projects/brainfuck for Urban Müller's version. The biggest gain appears to be heavy use of ||. Aug 16, 2011 at 6:10

## C, 267

#define J break;case


Run as ./a.out primes.bf

## Ungolfed Version:

#define J break;case

char*p,a[40000],*q=a; // packed so program immediately followed by data

w(n){
for(;*q-93;q++){ // until ']'
if(n)switch(*q){ // n = flagged whether loop evaluate or skip(0)
J'>':++p;
J'<':--p;
J'+':++*p;
J'-':--*p;
J'.':putchar(*p);
J',':*p=getchar();
}
if(*q==91){char*r=*p&&n?q-1:0;q++;w(r);q=r?r:q;} // recurse on '[', record loop start
}
}

main(int n,char**v){
*p++=93; // mark EOF with extra ']' and set data pointer to next
w(1); // begin as a loop evaluate
}


# C, 260 + 23 = 283 bytes

I created a C program which can be found here.

main(int a,char*s[]){int b[atoi(s[2])],*z=b,p;char*c=s[1],v,w;while(p=1,
*c){q('>',++z)q('<',--z)q('+',++*z)q('-',--*z)q('.',putchar(*z))q(',',*z
=getchar())if(*c=='['||*c==']'){v=*c,w=184-v;if(v<w?*z==0:*z!=0)while(p)
v<w?c++:c--,p+=*c==v?1:*c==w?-1:0;}c++;}}


Has to be compiled via gcc -D"q(a,b)"="*c-a||(b);" -o pmmbf pmmbf.c and can be called as follows: pmmbf ",[.-]" 30000 whereby the first argument (quoted) contains the bf-program to run, the second determines how large the tape should be.

• I think that you need to add 23 characters to your count for the -D"q(a,b)"="*c-a||(b);" option, since that seems (to my limited understanding, at least) to be helping you shrink your code. Aug 5, 2011 at 9:23
• The option is included in the posted text. The reason for it is to avoid the lengthy word define and newline, but I don't think that's really kosher. Anyway with the quotes, comment, and gcc -D I don't see the advantage at all. Aug 6, 2011 at 3:30

## F#: 489 chars

The following program doesn't jump at '[' / ']' instructions, but scans the source code for the next matching token. This of course makes it kind of slow, but it can still find the primes under 100. F# integer types don't overflow but wrap.

Here's the short version:

[<EntryPoint>]
let M a=
let A,B,i,p,w=Array.create 30000 0uy,[|yield!System.IO.File.ReadAllText a.[0]|],ref 0,ref 0,char>>printf"%c"
let rec g n c f a b=if c then f i;if B.[!i]=a then g(n+1)c f a b elif B.[!i]=b then(if n>0 then g(n-1)c f a b)else g n c f a b
while !i<B.Length do(let x=A.[!p]in match B.[!i]with|'>'->incr p|'<'->decr p|'+'->A.[!p]<-x+1uy|'-'->A.[!p]<-x-1uy|'.'->w x|','->A.[!p]<-byte<|stdin.Read()|'['->g 0(x=0uy)incr '['']'|']'->g 0(x>0uy)decr ']''['|_->());incr i
0


A nasty gotcha was that the primes.bf program chokes on windows newlines. In order to run it I had to save the input number to a UNIX formatted text document and feed it to the program with a pipe:

interpret.exe prime.bf < number.txt


Edit: entering Alt+010 followed by Enter also works in Windows cmd.exe

Here's the longer version:

[<EntryPoint>]
let Main args =
let memory = Array.create 30000 0uy
let source = [| yield! System.IO.File.ReadAllText args.[0] |]
let memoryPointer = ref 0
let sourcePointer = ref 0
let outputByte b = printf "%c" (char b)
let rec scan numBraces mustScan adjustFunc pushToken popToken =
if mustScan then
if source.[!sourcePointer] = pushToken then
scan (numBraces + 1) mustScan adjustFunc pushToken popToken
elif source.[!sourcePointer] = popToken then
if numBraces > 0 then scan (numBraces - 1) mustScan adjustFunc pushToken popToken
else
scan numBraces mustScan adjustFunc pushToken popToken

while !sourcePointer < source.Length do
let currentValue = memory.[!memoryPointer]
match source.[!sourcePointer] with
| '>' -> incr memoryPointer
| '<' -> decr memoryPointer
| '+' -> memory.[!memoryPointer] <- currentValue + 1uy
| '-' -> memory.[!memoryPointer] <- currentValue - 1uy
| '.' -> outputByte currentValue
| ',' -> memory.[!memoryPointer] <- byte <| stdin.Read()
| '[' -> scan 0 (currentValue = 0uy) incr '[' ']'
| ']' -> scan 0 (currentValue > 0uy) decr ']' '['
|  _  -> ()
incr sourcePointer
0

• I solved the Enter issue by not pressing it but Ctrl+J :-)
– Joey
Feb 14, 2011 at 8:11
• Ctrl+J didn't work for me, but entering Alt+010 followed by Enter did. Feb 14, 2011 at 9:28

## Delphi, 397382378371366364 328 characters

Eat this Delphi!

328 var p,d:PByte;f:File;z:Word=30000;x:Int8;begin p:=AllocMem(z+z);d:=p+z;Assign(F,ParamStr(1));Reset(F,1);BlockRead(F,p^,z);repeat z:=1;x:=p^;case x-43of 1:Read(PChar(d)^);3:Write(Char(d^));0,2:d^:=d^+44-x;17,19:d:=d+x-61;48,50:if(d^=0)=(x=91)then repeat p:=p+92-x;z:=z+Ord(p^=x)-Ord(p^=x xor 6);until z=0;end;Inc(p)until x=0;end.


Here the same code, indented and commented :

var
d,p:PByte;
x:Int8;
f:File;
z:Word=30000;
begin
// Allocate 30000 bytes for the program and the same amount for the data :
p:=AllocMem(z+z);
d:=p+z;
// Read the file (which path must be specified on the command line) :
Assign(F,ParamStr(1));
Reset(F,1);
// Handle all input, terminating at #0 (better than the spec requires) :
repeat
// Prevent a begin+end block by preparing beforehand (values are only usable in '[' and ']' cases) :
z:=1;                       // Start stack at 1
x:=p^;                      // Starting at '[' or ']'
// Choose a handler for this token (the offset saves 1 character in later use) :
case x-43of
3:Write(Char(d^));        // '.'     : Write 1 character from data-pointer to output
0,2:d^:=d^+44-x;          // '+','-' : Increase or decrease data
17,19:d:=d+x-61;          // '<','>' : Increase or decrease data pointer
48,50:                    // '[',']' : Start or end program block, the most complex part :
if(d^=0)=(x=91)then     // When (data = 0 and forward), or when (data <> 0 and backward)
repeat                  //
p:=p+92-x;            // Step program 1 byte back or forward
z:=z+Ord(p^=x)        // Increase stack counter when at another bracket
-Ord(p^=x xor 6); // Decrease stack counter when at the mirror char
until z=0;              // Stop when stack reaches 0
end;
Inc(p)
until x=0;
end.


This one took me a few hours, as it's not the kind of code I normally write, but enjoy!

Note : The prime test works, but doesn't stop at 100, because it reads #13 (CR) before #10 (LF)... do other submissions suffer this problem too when running on CRLF OSes?

• Wow! I never would have expected to trump C in terseness with Delphi! Not until you apply my ideas to C I guess ;-) Mar 12, 2011 at 16:30

# Python 2, 223

I admit that I recycled an old program of mine (but had to change it quite a bit, because the old version didn't have input, but error checking...).

P="";i,a=0,[0]*30000
import os,sys
for c in open(sys.argv[1]).read():x="><+-.[,]".find(c);P+=" "*i+"i+=1 i-=1 a[i]+=1 a[i]-=1 os.write(1,chr(a[i])) while+a[i]: a[i]=ord(os.read(0,1)) 0".split()[x]+"\n";i+=(x>4)*(6-x)
exec P


Runs the primes calculator fine.

I see now that Alexandru has an answer that has some similarities. I'll post mny answer anyways, because I think there are some new ideas in it.

# Recall, 594 bytes

In short: Recall has no arithmetic operators in a classic sense, it only has bitwise operations. You can not just "add one" etc. Recall is also strictly stack-based.

DC505M22022M32032M606M42042M707M92092M4405022o032o06o042o07o092o044o1305022o06o042o092o52052q.q2305022o06o07o93093q.q5403206o07o14014q.q6403206o042o07o24024q.q74Yx34034z03MMMMMMMM034o3yY030401r3.4.101zyY040301r4.3.101zY01052gZ02Z040301052023s4.3.10zyY01023gZ02z030401023052s3.4.10zyY01093gZ02q20zyY01054gZ02u20zyY01014gZx20zyY01064gZ02X0zyY01024gZ03304302r33.43.20zyY01074gZ04303302r43.33.20zyyQ6205.8Y06208g6206208iZ08M808013izy062U7205.9Y07209g7207209iz09M909013izy072R53.63.82063MMMMMMMM053o63082013i53082KKKKKKKK82053063082S84.94.12.73.83t012073083TY083073012r83.73.12012084gzY012094gZt0zyy


### Example 1: Print something

Input:

-[--->+<]>-----..-[----->+<]>.++++.+[->++++<]>.---[----->++<]>.---.------------.++++++++.++++++++.+[-->+++++<]>-.


Output:

PPCG rocks!


### Example 2: Output square numbers up to 100

Input:

+[>++<-]>[<+++++>-]+<+[>[>+>+<<-]++>>[<<+>>-]>>>[-]++>[-]+>>>+[[-]++++++>>>]<<<[[<++++++++<++>>-]+<.<[>----<-]<]<<[>>>>>[>>>[-]+++++++++<[>-<-]+++++++++>[-[<->-]+[<<<]]<[>+<-]>]<<-]<<-]


Output:

0
1
4
9
16
25
36
49
64
81
100


This example might take a few minuted to execute and might cause a "this tab is frozen" message. Ignore that and wait.

# C (gcc), 273 268 bytes

main(_,a){_=fopen("w.c","w");fputs("main(){char a[30000],*p=a;",_);x:a=getchar();fputs(a-62?a-60?a-43?a-45?a-46?a-44?a-91?a-93?~a?"":"}":"}":"while(*p){":"*p=getchar();":"putchar(*p);":"--*p;":"++*p;":"--p;":"++p;",_);if(~a)goto x;fclose(_);system("cc w.c;./a.out");};


Try it online!

-5 thanks to ceilingcat

Takes input from stdin.

This relies a little bit on the environment, but is pretty consistent. This is effectively the eval solution for c. It writes an appropriate C program to the file w.c, compiles it, and runs it as the desired executable. Thus as a bonus effect this actually compiles the bf code and leaves a.out as a binary for it. Note that depending on the system you may need to modify the last string. In particular most windows c compilers call the default executable "a.exe". Luckily as far as I can tell, they all have the same length so the bytecount is the same. (though if you don't have a cc defined you may need to add a letter such as gcc to the compile command, adding 1 byte).

I am aware that this thread is a bit old, but I didn't see this style of C solution yet, so I thought I'd add it.

• 253 bytes Aug 21, 2020 at 7:22

# Lua, 285

loadstring("m,p={0},1 "..io.open(arg[1]):read"*a":gsub("[^.,<>[%]+-]",""):gsub(".",{["."]="io.write(string.char(@)) ",[","]="@=io.read(1):byte() ",["<"]="p=p-1 ",[">"]="p=p+1 @=@or 0 ",["["]="while @~=0 do ",["]"]="end ",["+"]="@=(@+1)%256 ",["-"]="@=(@-1)%256 "}):gsub("@","m[p]"))()


loadstring( --execute
"m,p={0},1 ".. --initialize memory and pointer
io.open(arg[1]) --open file
:gsub("[^.,<>[%]+-]","") --strip non-brainfuck
:gsub(".", --for each character left
{["."]="io.write(string.char(@)) ", -- '@' is shortcut for 'm[p]', see below
["<"]="p=p-1 ",
[">"]="p=p+1 @=@or 0 ", --if a before unexplored memory cell, set to 0
["["]="while @~=0 do ",
["]"]="end ",
["+"]="@=(@+1)%256 ", --i like it overflowing
["-"]="@=(@-1)%256 "
}
)
:gsub("@","m[p]") --replace the '@' shortcut
() --call it


Works perfectly

local m,p,i,r,c={0},1,1,{},io.open(arg[1]):read"*a"while i<=#c do(({[43]=function()m[p]=(m[p]+1)%256 end,[45]=function()m[p]=(m[p]-1)%256 end,[62]=function()p=p+1 m[p]=m[p]or 0 end,[60]=function()p=p-1 end,[46]=function()io.write(string.char(m[p]))end,[44]=function()m[p]=io.read(1):byte()end,[91]=function()if m[p]==0 then i=select(2,c:find("%b[]",i))else r[#r+1]=i end end,[93]=function()if m[p]==0 then r[#r]=nil else i=r[#r] end end})[c:byte(i)]or function()end)()i=i+1 end


local m,   p, i, r,  c= --memory, pointer, brackets stack, code
{0}, 1, 1, {}, io.open(arg[1]) --open file
while i<=#c do --while there's code
(
(
{
[43]=function() -- +
m[p]=(m[p]+1)%256
end,
[45]=function() -- -
m[p]=(m[p]-1)%256
end,
[62]=function() -- >
p=p+1 m[p]=m[p]or 0 --if new memory cell, set it to 0
end,
[60]=function() -- <
p=p-1
end,
[46]=function() -- .
io.write(string.char(m[p]))
end,
[44]=function() -- ,
end,
[91]=function() -- [
if m[p]==0 then
i=select(2,c:find("%b[]",i)) --find matching ]
else
r[#r+1]=i --push position to the stack
end
end,
[93]=function() -- ]
if m[p]==0 then
r[#r]=nil --pop from stack
else
i=r[#r] --go to position on the top of stack
end
end
}
)[c:byte(i)] --transform character into code
or function()end --do nothing on non-brainfuck
)() --run the resulting function
i=i+1 --go to the next opcode
end


# VyxalDOb, 5453 50 bytes

><+-][.,£¥↔¥‟„›‹}f{:|:C₴_¼²JĿ?ṘƛC⅛;k23*(0)„Ė


Try it Online!

-4 thanks to Aaron Miller.

The basic idea is that a stack is a wrapping tape if you can rotate the whole thing. So it's really just setting up the input, pushing 0s, and transpiling:

• > - ‟ - rotate stack right
• < - „ - rotate stack left
• + - › - increment the current item
• - - ‹ - decrement the current item
• [ - {:| - set a while loop without popping the top
• ] - } - close a while loop
• . - :C₴ - Duplicate, make a char and output without a trailing newline
• , - _¼ - pop, then take a character from input

?ṘƛC⅛; takes the input and pushes each character to the global array. Then k23*(0) pushes 30k zeroes, then „Ė runs the code!

• 52 bytes because why not Jul 15, 2021 at 12:58
• @AaronMiller That doesn't seem to work - it outputs 0 instead of a. Nice idea though! Jul 15, 2021 at 20:14
• I swear it worked perfectly this morning. Somebody must've broken it sometime today. Jul 15, 2021 at 20:16
• @AaronMiller Lyxal.... I'll try it on hyper's fork Jul 15, 2021 at 20:31
• Until it gets fixed, here's 53 bytes Jul 15, 2021 at 20:36

# Vyxal, 150149 148 bytes

k2T0ẋ→_0→0?£{D¥L<|¥i:‛+-$c[:‛ +ḟ←_:_←›Ǔṫ∇∇+J←›ǔ→_|:‛<>$c[:‛ >ḟ←+→|:\.=[←_← iC₴|:\,=[←_:_←?CȦ→_|:$=[←_← i¬[Ȯ¥ȯ$ḟ∇∇+$]|:\]=[Ȯ¥$Ẏf$=TG‹∇_]]]]]]]_›  Try it Online! "But there's already a Vyxal answer that's 100 99 98 bytes shorter bro what is this cringe" I hear you say. Well this version doesn't use eval, and instead runs it manually. Note that it can be slow because it's doing things like rotating a 30000 item list quite frequently, so here's a version with only 100 cells for testing Some assumptions this program makes: • Closed brackets • EOF handled manually • Program on first line, each input character on a new line ## Explained ### Quick Overview 30 0ẋ →_ # Tape 0→ # Cell pointer 0 # Instruction pointer ?£ # Prog {D¥L<| # While the instruction pointer is less than program length :,←_,¥i # Get command :‛+-c[:‛ +ḟ←_:_←›Ǔṫ∇∇+J←›ǔ→_| # Handle addition and subtraction in the same place :‛<>c[:‛ >ḟ←+→| # Handle moving the pointer left and right :\.=[←_← iC,| # Output :\,=[←_:_←?CȦ→_| # Input :$$=[ # jump to next ] if tape[cell] == 0 ←_← i¬[Ȯ¥ȯ:,$ḟ›∇+]| :$$=[Ȯ¥$Ẏf$=TG›∇_] # Jump back to the previous [ ]]]]]] _ # Remove the char from the stack › # Next command }  ### Detailed Explanation k2T0ẋ→_  This is the tape. It consists of 30000 0s in a list. It's stored in a global variable called _. 0→  This is the cell pointer. It tracks which cell is being pointed to. It's stored in the ghost variable. The ghost variable is another name for the variable with no name (as in, its name is literally "" - the empty string.) 0  This is the instruction pointer. It tracks which character of the program is being executed. It's stored on the stack as the bottom of the stack. Throughout this answer, the stack is [instruction pointer, current character, ...] where ... is whatever processing is happening in each command. ?£  This gets the program to execute and stores it in the register. {D¥L<|  This is the main program execution loop. It calls its code while the instruction pointer is less than the length of the program. Before performing the comparison, the instruction pointer is triplicated (i.e. three copies of it are pushed to the stack). This is so that there is a copy for the comparison, for getting the current character in the program and for maintaining the value of the pointer. ¥i  This gets the character at the index of the instruction pointer and puts it on the stack. The stack is now [instruction pointer, command]. We now move on to handling the commands #### Addition and Subtraction :‛+-c[:‛ +ḟ←_:_←›Ǔṫ∇∇+J←›ǔ→_  The above snippet is the entirety of the section that handles the + and - commands. :‛+-c  This checks if the command is in the string "+-", while leaving a copy of the command on the stack for further comparison if needed. [:‛ +ḟ  If the command is one of + or -, then the command is duplicated yet again, and its index in the string " +" is returned. This returns 1 for + and -1 for -, as -1 is returned for characters not in the string. The 1 or -1 acts as an offset for the current cell, and saves having to check for + and - individually. It also means + can be used for both commands instead of › for addition and ‹ for subtraction. ←_:_←›Ǔ  This pushes the tape (stored in the global variable called _), the value of the cell pointer + 1 (stored in the ghost variable and then incremented) and then rotates the tape left that many times. The :_ after ←_ is needed because there seems to be a bug with list mutability when rotating. (TODO: Fix) After the rotation, the cell that is to be incremented or decremented is at the tail of the tape. ṫ∇∇+J  This separates the tail and the rest of the list - first it pushes tape[:-1] and then it pushes tape[-1]. It then rotates the top three items on the stack so that the order is [tape[:-1], tape[-1], offset]. The offset is then added to the tail, and the tail is then appended back to the rest of the tape. ←›ǔ→_  The tape is then rotated cell pointer + 1 times to the right to "undo" the left rotation and then placed back into the global variable called _. #### Moving the Cell Pointer |:‛<>c[:‛ >ḟ←+→  The above snippet is the entirety of the section that handles the < and > commands. |:‛<>c  Just like with the + and - commands, a check is done to see if the command is in the string "<>". [:‛ >ḟ  And also just like with the + and - commands, if the command is one of < or >, then the command is duplicated yet again, and its index in the string " >" is returned. This returns 1 for > and -1 for <. The 1 or -1 acts as an offset for the current cell location, and saves having to check for < and > individually. It also means + can be used for both commands instead of › for moving right and ‹ for moving left. ←+→  This adds the offset to the cell pointer and updates the value stored in the ghost variable. It also acts as a weird face. #### Output |:\.=[←_← iC₴  The above snippet is the entirety of the section that handles the . command. |:\.=  This checks if the command is equal to the string ".". Unlike addition/subtraction and cell pointer movement, input and output cannot be handled in the same if-statement, as their functions are different at a fundamental level. [←_← i  If the command is ., the tape is pushed, as well as the cell pointer's value. The item at the location of the cell pointer is then retrieved. The space after the second ← is needed to avoid it being interpreted as ←i C₴  This prints that item after converting it to its ASCII equivalent (think chr in python) #### Input |:\,=[←_:_←?CȦ→_  The above snippet is the entirety of the section that handles the , command. |:\,=  This checks if the command is equal to the string ",". [←_:_←?C  If the command is ,, the tape and current cell pointer are pushed to the stack, as well as the ordinal value (think ord in python) of the next input. Ȧ→_  This sets the cell pointerth item of tape to the input. Basically tape[cell_pointer] = ord(input()). #### Looping |:$$=[←_← i0=[Ȯ¥ȯ$ḟ∇∇+]  The above snippet is the entirety of the section that handles the [ command. |:$=  The usual check for a certain character. [ this time. [←_← i  If the command is [, get the cell pointerth item of tape. ¬[  If the cell is not a truthy value (i.e. not 0), then: Ȯ¥ȯ$ḟ  Push program[instruction_pointer:] and find the first ] in that string. The stack is now [instruction pointer, command, position of "]"]. ∇∇+  Rotate the stack so that its order is [command, position of "]", instruction pointer] and add the position of the ] to the instruction pointer. This has the effect of iterating through the program until the next ] is found without having to have lengthy while loops. |:$$=[Ȯ¥$Ẏf$=TG‹∇_  The above snippet is the entirety of the section that handles the ] command. |:$=


Check if the command is ]

[Ȯ¥$Ẏf\[=TG  And if it is, get the greatest index of all [s in the string program[0:instruction_pointer]. This has the effect of backtracking to the matching [ without having to have a lengthy while loop. ‹∇$_


Decrement that so that the instruction pointer will be re-incremented to the position of the matching [ and rotate the stack so that the stack order is once again [instruction pointer, command]

#### Final bits

]]]]]]] # Close all the if statements
_      # Remove the command from the stack
›      # Move the instruction pointer forward 1
}      # Close the main while loop

• ←_← 10/10 emoticon Jun 13 at 7:59

## C, 374 368

Reads from a file. Passes PRIME.BF test.

Usage: ./a.out PRIME.BF

#include <stdio.h>
main(int c,char**v){int m[30000],s[99],p=0,i=0,n=0;char l[9999],d;FILE*f=fopen(v[1],"r");for(l[i]=0;i<9999&&l[i]!=EOF;l[i]=getc(f))i++;for(i=1;d=l[i];i++){if(!n){p+=d-62?0:1;p-=d-60?0:1;m[p]+=d-43?0:1;m[p]-=d-45?0:1;if(d==46)putchar(m[p]);if(d==44){m[p]=getchar();}if(d==93){i=s[c]-1;c--;n++;}}if(d==91){if(m[p]){c++;s[c]=i;}else{n++;}}n-=d-93?0:1;}}


Reformatted:

#include <stdio.h>
main(int c,char**v){
int m[3000],s[99],p=0,i=0,n=0;
char l[9999],d;
FILE*f=fopen(v[1],"r");
for(l[i]=0;i<9999&&l[i]!=EOF;l[i]=getc(f))i++;
for(i=1;d=l[i];i++){
if(!n){ // > < + - . , ] \n [ ]
p+=d-62?0:1;
p-=d-60?0:1;
m[p]+=d-43?0:1;
m[p]-=d-45?0:1;
if(d==46)putchar(m[p]);
if(d==44){m[p]=getchar();}
if(d==93){i=s[c]-1;c--;n++;}
}
if(d==91){if(m[p]){c++;s[c]=i;}else{n++;}}
n-=d-93?0:1;
}
}
`
• 3000 vs 30000. Your buffer is too small. The program size is too small also. Jan 31, 2011 at 12:54
• I made a typo, fixed. What do you mean by program size? If you mean max file size, you didn't specify a minimum it should handle. Jan 31, 2011 at 15:27