Perl - 177 (source) + 172 (output) = 349
#!perl -p0 y/-+><.,[] -~/p-w/d;s/(.)\K\1+|rs|wv[^v]*(?=w)/$+&&length$&/ge;$_="eval'r$_'=~".'s/.(\d*)/(qw(--$ ++$ -- ++ print+chr$ $$i=ord+getc; while($$i){ })[$&&v63].q($i;))x($++1)/ger'
Counting the shebang as 2 bytes, one for each option. First, each of the eight commands is translated onto the range p-w, while at the same time removing all other characters. This string is then run-length encoded and output with a minimal decoder/interpreter. A few things are optimized away: the string >< obviously does nothing, and a for loop that follows directly after another may be removed entirely, as it will never be entered.
Output for the test program:
eval'rq4vpwq9vrq6rq9rq2s2pwrq1trqtq6t1q2trq1tsq7tp7tq2tp5tp7trqtp32vt44wsps1'=~s/.(\d*)/(qw(--$ ++$ -- ++ print+chr$ $$i=ord+getc; while($$i){ })[$&&v63].q($i;))x($++1)/ger
A sample run:
$ perl brainfusk.pl < in.bf | perl Hello world!
Perl - 232 (source) + 21 (output) = 253
#!perl -p0 y/-+><.,[] -~/0-7/d;$_="eval'2$_'=~".'s/./qw(--$ ++$ -- ++ print+chr$ $$i=ord+getc; while($$i){ })[$&].q($i;)/ger'; /5/||fork?(wait,$?||exit):($SIG{ALRM}=sub{exit 1},alarm 9,$S=select(open 1,'>',\$o),eval,print$S "print\"\Q$o\E\"")
This one is based on FIQ's observation that if the original program doesn't contain an input statement, the output will be static, and therefore can be reduced to a single print statement. If you like this one, be sure to give his answer a +1.
So what we can do is pipe stdout to a variable, eval the code we would have output, and wrap the result in a print.
...that won't always work, though. Whenever the code to be translated would have resulted in an infinite loop, (e.g. +[.]), this cannot be reduced to a single print statement, for obvious reasons. So instead, we launch the eval in a child process with a short timeout, and if it doesn't finish executing within that time we output the translated program as before.
Structured and commented:
if(!/5/) { # no `,` in program if(fork) { # parent process # wait for child wait; # no child error, terminate without output $?||exit } else { # child process # alarm handler, exit with error $SIG{ALRM}=sub{exit 1}; # set an alarm in 9 seconds alarm 9; # redirect STDOUT to variable $o $S=select open 1,'>',\$o; # execute translated code eval; # wrap the result in a print statement print$S "print\"\Q$o\E\"" } }
Output for sample program:
print"Hello\ world\!"
Output for ,[.]:
eval'25647'=~s/./qw(--$ ++$ -- ++ print+chr$ $$i=ord+getc; while($$i){ })[$&].q($i;)/ger
Output for +[.] (after 9 seconds):
eval'21647'=~s/./qw(--$ ++$ -- ++ print+chr$ $$i=ord+getc; while($$i){ })[$&].q($i;)/ger
byte count of source + (byte count of output)^2, would that encourage people to focus more on simplifying the output? \$\endgroup\$