<?PHP
// Create function refs, for those which have characters too high.
$FILL = 'ARRA' . CHR(89) . CHR(95) . 'FILL'; // Array_fill to create the tape.
$CHOP = 'ARRA' . CHR(89) . CHR(95) . CHR(83) . 'LICE'; // Array_slice for array indexing.
$POP = 'ARRA' . CHR(89) . CHR(95) . CHR(83) . 'HIF' . CHR(84); // Array_shift for array indexing.
$DEPOP = 'ARRA' . CHR(89) . CHR(95) . CHR(83) . 'PLICE'; // Array_splice for array inserting.
$LEN = CHR(83) . CHR(84) . 'RLEN'; // Strlen
$LOP = CHR(83) . CHR(84) . 'R' . CHR(95) . CHR(83) . 'PLI' . CHR(84); // Str_split
// "Hello world!" - note using round braces instead of square in the brainfsck code.
$IN = (">+++++++++(<++++++++>-)<.>+++++++(<++++>-)<+.+++++++..+++.>>>++++++++(<++++>-)<.>>>++++++++++(<+++++++++>-)<---.<<<<.+++.------.--------.>>+.>++++++++++.");
$INLEN = $LEN($IN);
$IN = $LOP($IN);
// Init tape with 10 zeros (add more for longer tape).
$A = $FILL(0,10,0);
// Set $AA ptr to first cell of tape.
$AA = 0;
FOR ($I = 0; $I < $INLEN; $I++):
// Extract element: $CH = $IN[$I].
$CH = $CHOP($IN, $I);
$CH = $POP($CH);
// Increment element at $I.
//$CH++;
//$CH = $FN($AA, $I, 1, $CH);
// Only need one of '+' or '-' for TC if memory wraps.
IF ($CH == '>'):
$AA++;
ENDIF;
IF ($CH == '<'):
$AA--;
ENDIF;
// Only one of '+' or '-' is critical for Turing completeness.
IF ($CH == '+'):
// Increment element: $A[$AA]++;
$ID = $CHOP($A, $AA);
$ID = $POP($ID);
$ID++;
$DEPOP($A, $AA, 1, $ID);
ENDIF;
IF ($CH == '-'):
// Decrement element: $A[$AA]--;
$ID = $CHOP($A, $AA);
$ID = $POP($ID);
$ID--;
$DEPOP($A, $AA, 1, $ID);
ENDIF;
IF ($CH == ')'):
$ID = $CHOP($A, $AA);
$ID = $POP($ID);
IF ($ID):
FOR ($LOOP = 1; $LOOP > 0; ):
$CH = $CHOP($IN, --$I);
$CH = $POP($CH);
IF ($CH == '('):
$LOOP--;
ENDIF;
IF ($CH == ')'):
$LOOP++;
ENDIF;
ENDFOR;
ENDIF;
ENDIF;
// I/O is non-critical for Turing completenessTC.
IF ($CH == '.' ):
$ID = $CHOP($A, $AA);
$ID = $POP($ID);
ECHO CHR($ID);
ENDIF;
ENDFOR;