Input: Brainfuck program (must not contain the pipe character |), then a pipe, then (if not empty) the input for the brainfuck program.
1 pixel per codel. Tested with npiet.
You can also generate a Brainfuck interpreter in Piet with hard coded Brainfuck code in it. Just enter your Brainfuck program here and generate a Piet program, that executes your Brainfuck code and only needs the input of your Brainfuck program at runtime.
Let c1c2...cn be a Brainfuck programm.
Let s-m, s-m+1, ..., s-1, s0, s1, ..., sm-1, sm be all used memory cells (or more memory cells).
So S=2*m+1 is the number of the memory cells that may contain a value unequal zero and P=n is the size of the program.
Let s be the number of the memory cell to which the data pointer points.
Let p+1 be the number of the next command of the Brainfuck program that should be executed.
Then the Brainfuck program and its state is stored at the Piet stack in the following way:
cn, cn-1, ..., c2, c1, s0, s-1, s1, s-2, s2, ..., s-m, sm, P, p, S, s
The reader module (cf. fig. 1) reads characters from STDIN and pushes them at the stack (and counts them). After | is read, it flips their order at the stack and pushes s0=0 and P, p=0, S=1 and s=0.
After this the interpreter can start executing the Brainfuck programm. It fetches cp+1 and compares it with the ASCII codes for < > + - . , [ ] (cf. fig. 2) and then changes s, ss or p and/or reads from STDIN or writes to STDOUT (cf. fig. 3). After that p will be increased (cf. fig. 4) and the next command will be fetched. If p=P the interpreter will terminate (cf. fig. 2).
Figure 1: The reader module.
Figure 2: Fetch cp+1
Figure 3: Execute cp+1
Figure 4: Increase p.