PHP OOP Brainfuck Interpreter

From D3xt3r01.tk
Jump to navigationJump to search
<?php
/*
 * PHP OOP Brainfuck Interpreter (No Debugger)
 *
 * @version 0.1
 * @author "Ivan Lucian" <nophinity@gmail.com>
 *
 * @todo Add a debuger w/ breakpoints
 * @todo Add a profiler
 * @todo Optimize looping
 * @todo Fix EOF chr(0) problems
 * 
 */

error_reporting(0);

class Brainfuck {
	private $source;
	private $sourceIndex = 0;
	private $data = array();
	private $dataIndex = 0;
	private $input;
	private $inputIndex = 0;
	private $output = '';
	private $sourceLength;
	private $inputLength;
	
	public function __construct($source, $input = '', $flush = false) {
		$this->source = $source;
		$this->input = $input;
		$this->sourceLength = strlen($source);
		$this->inputLength = strlen($input);
		$this->data[0] = chr(0);
		$this->flush = $flush;
	}
	
	public function interpret() {
		$di =& $this->dataIndex;
		$si =& $this->sourceIndex;
		$sl =& $this->sourceLength;
		$ip =& $this->inputIndex;
		$il =& $this->inputLength;
		while (true) {
			switch ( $this->source{$this->sourceIndex} ) {
				case '+':
						$this->data[$di] = chr( ord($this->data[$di]) + 1 );
						break;
				case '-':
						$this->data[$di] = chr( ord($this->data[$di]) - 1 );
						break;
				case '>':
						$di++;
						if (!isset($this->data[$di])) $this->data[$di] = chr(0);
						break;
				case '<':
						if ($di == 0) break;
						$di--;
						break;
				case '.':
						if ($this->flush == true) 
							echo $this->data[$di];
						else 
							$this->output .= $this->data[$di];						
						break;
				case ',':
						$this->data[$di] = $ip == $il ? chr(0) : $this->input[$ip++];   
						break;
				case '[':
						if (ord($this->data[$di]) == 0 && $di != 0) {
							$brackets++;
							while ($brackets && $si++ < $sl) {
								if ($this->source[$si] == '[')
									$brackets++;
								elseif ($this->source[$si] == ']') 
									$brackets--;
							}
						} else {
							$pos = $si++ - 1;
							if ($this->interpret()) 
								$si = $pos;
						}
						break;
						
				case ']':
						return (ord($this->data[$di]) != 0);
			}
			
			if (++$si == $sl) break;
		}
		
		return $this->output;
	}
	
	
}

$code = <<< __EOF
  ++++[>+++++<-]>+++
  [
    [>+>+<<-]
    >++++++[<+>-]+++++++++[<++++++++++>-]
    >[<+>-]<-
  ]
  +++>+++++++++[<+++++++++>-]
  >++++++[<++++++++>-]<--[>+>+<<-]>>[<<+>>-]<--
  >>++++[<++++++++>-]++++++++++

  >+++++++++[>+++++++++++<-]>
  [
    [>+>+>+<<<-]>[<+>-]>>
    [
      [>+>+<<-]>>[<<+>>-]<
      [<->-[<->-[<->-[<->-[<->-[<->-[<->-[<->-[<->-[<<<+>---------->->[-]]]]]]]]]]]<
    ]
    <<[>>++++++++++++[<++++<++++>>-]<<[.[-]>]<<]
    >[<++++++[>++++++++<-]>.[-]]<<

    <<<.<<<<<.[<]>>>>>>>>>.<<<<<..>>>>>>>>.>>>>>>>.

    [>]>[>+>+<<-]>[<+>-]>[-[[-]+++++++++[<+++++++++++++>-]<--.[-]>]]<<

    <<<.[<]>>>>>>>>>.>>>>>>>>>.[>]<<.<<<<<.<<<..[<]>>>>>>.[>]<<.
    [<]>>>>>>>>>.>.[>]<<.[<]>>>>.>>>>>>>>>>>>.>>>.[>]<<.
    [<]>.[>]<<<<<<.<<<<<<<<<<<..[>]<<<.>.

    [>]>[>+>+>+<<<-]>[<+>-]>>
    [
      [>+>+<<-]>>[<<+>>-]<
      [<->-[<->-[<->-[<->-[<->-[<->-[<->-[<->-[<->-[<<<+>---------->->[-]]]]]]]]]]]<
    ]
    <<[>>++++++++++++[<++++<++++>>-]<<[.[-]>]<<]
    >[<++++++[>++++++++<-]>.[-]]<<

    <<<.<<<<<.[<]>>>>>>>>>.<<<<<..>>>>>>>>.>>>>>>>.

    [>]>[>+>+<<-]>[<+>-]>[-[[-]+++++++++[<+++++++++++++>-]<--.[-]>]]<<

    <<<.[<]>>>>>>>>>.>>>>>>>>>.[>]<<.<<<<<.<<<..[<]>>>>>>.[>]<<<<.>>>.

    <<<<.<.<<<<<<<<<<.>>>>>>.[>]<<.[<]>>>>>>>>>.>.>>>>>>>>>.[>]<<.
    <<<<<<<.[<]>>>>>>>>>.[<]>.>>>>>>>>>.[>]<<.<<<<.<<<<<<<<<<<<<.[>]<<<<<<<<<.
    [>]<<.[<]>>>>>>>>.[>]<<<<<<.[<]>>>>>..[>]<<.<<<<<<<<<<<<.[<]>>>>.
    [>]<<.<<<<.[<]>>>>>>.>>>.<<<<<<.>>>>>>>.>>>>>>>>>>.[>]<<<.>.

    >>>-

    [>+>+>+<<<-]>[<+>-]>>
    [
      [>+>+<<-]>>[<<+>>-]<
      [<->-[<->-[<->-[<->-[<->-[<->-[<->-[<->-[<->-[<<<+>---------->->[-]]]]]]]]]]]<
    ]
    <<[>>++++++++++++[<++++<++++>>-]<<[.[-]>]<<]
    >[<++++++[>++++++++<-]>.[-]]<<

    [>+>+<<-]>[<+>-]+>[<->[-]]<
    [-<<<[<]>>>>>>>>>>.<.[>]<<.[<]>>>>>>>>>>>.<<.<<<.[>]<<<<<<<<<<.[>]>>]<

    <<<.<<<<<.[<]>>>>>>>>>.<<<<<..>>>>>>>>.>>>>>>>.

    [>]>[>+>+<<-]>[<+>-]+>
    [<->-[<+>[-]]]<
    [++++++++[>+++++++++++++<-]>--.[-]<]<

    <<<.[<]>>>>>>>>>.>>>>>>>>>.[>]<<.<<<<<.<<<..[<]>>>>>>.[>]<<.
    [<]>>>>>>>>>.>.[>]<<.[<]>>>>.>>>>>>>>>>>>.>>>.[>]<<.
    [<]>.[>]<<<<<<.<<<<<<<<<<<..[>]<<<<.>>>..

    >>
  ]

__EOF;


$bf = new Brainfuck($code, 'Was it a dog or a cat I saw?', true);

echo "'" . $bf->interpret() . "'";
?>