Wolfram Language (Mathematica), 212 170 166 164 bytes
J[A_,B_]=Fold[Switch[{a,b}=#;#2,"f",{A,b},"F",{a,B},"e",{0,b},"E",{a,0},"p",#+{-1,1}Min[a,B-b],"P",#+{1,-1}Min[b,A-a],"o",Echo@a;#,_,Echo@b;#]&,{0,0},Characters@#]&
Calling J[A,B]
returns an interpreter for the (A,B)-bucket system, which can be applied to a program with J[A,B]["prog"]
. The "o" and "O" commands print using Echo
, and the return value of the program is the final bucket state.
The program is a big Switch
statement folded over the characters of the program, step-wise updating the contents of the buckets. Dispatching the Switch
takes a shortcut by defaulting to "O", as the spec says that there are no characters to be expected other than "fFeEpPoO".
Debugging is done by replacing Fold
with FoldList
, so that the return value of the program becomes the sequence of bucket states traversed during program execution.