brainfuck program;⎕IO;check;memory;mi;pi;pe;input;output;memout ⍝ check we can run the program program←,program :If ~∧/program∊'<>+-.,[]' 'ILLEGAL SYMBOL'⎕SIGNAL 501 :Return :EndIf check←+\('['=program)-(']'=program) :If (0>⌊/check)∨(0≠⊃⌽check) 'UNMATCHED []'⎕SIGNAL 502 :EndIf ⍝ initialise interpreter ⎕IO←0 memory←1⍴0 ⍝ memory cells mi←0 ⍝ memory pointer pi←0 ⍝ program pointer pe←¯1+⊃⍴program ⍝ program end (max pi) input←'' ⍝ program input output←'' ⍝ program output ⍝ function to output data :If 82=⎕DR'' ⍝ Classic APL memout←⊃∘⎕AV numchars←256 :Else ⍝ Unicode APL memout←⎕UCS numchars←1114112 :EndIf ⍝ execute program :While pi≤pe :Select pi⊃program :Case '>' ⍝ increment the data pointer (to point to the next cell to the right). mi+←1 :Case '<' ⍝ decrement the data pointer (to point to the next cell to the left). mi-←1 :Case '+' ⍝ increment (increase by one) the byte at the data pointer. (mi⊃memory)←numchars|1+(mi⊃memory) :Case '-' ⍝ decrement (decrease by one) the byte at the data pointer. (mi⊃memory)←numchars|¯1+(mi⊃memory) :Case '.' ⍝ output the value of the byte at the data pointer. output,←memout mi⊃memory :Case ',' ⍝ accept one byte of input, storing its value in the byte at the data pointer. :If 0=⍴input input,←⍞ :EndIf (mi⊃memory)←⊃input input←1↓input :Case '[' ⍝ if the byte at the data pointer is zero, then instead of moving the instruction pointer forward to the next command, jump it forward to the command after the matching ] command*. :If 0=mi⊃memory pi+←1+{⍵⍳¯1}{+\('['=⍵)-(']')=⍵}(1+pi)↓program :EndIf :Case ']' ⍝ if the byte at the data pointer is nonzero, then instead of moving the instruction pointer forward to the next command, jump it back to the command after the matching [ command*. :If 0≠mi⊃memory pi-←1+{⍵⍳¯1}{+\(']'=⍵)-('[')=⍵}⌽pi↑program :EndIf :EndSelect pi+←1 :If mi≥⍴memory memory←(1+mi)↑memory :ElseIf mi<0 memory←((-mi)⍴0),memory mi←0 :EndIf :EndWhile ⎕←output