<?php
/**
* Brainf*ck interpreter.
*
* This class was made so that brainf*ck doesn't f*ck with your brain anymore.
*
* A good tutorial for learning brainf*ck can be found at:
* http://nieko.net/data/bf.txt
*
* @author Tom Reitsma <hide@address.com>
* @version 0.8
*/
Class bf
{
var $stack = array();
var $pointer = 0;
var $loop_points = array();
var $code = null;
var $result = "";
/**
* load()
*
* Sets the input for the brainf*ck code.
* If the given input is a file, it will get its contents, else it will load the given string.
*
* @param mixed $file
* @return void
*/
function load($file)
{
if(is_file($file))
{
$this->code = file_get_contents($file);
if(strlen($this->code) == 0)
{
$this->code == null;
}
}
else if(is_string($file))
{
$this->code = $file;
}
else
{
die("File $file not found");
}
}
/**
* execute()
*
* Starts interpreting the given input, set by load()
* You can, aswell as in load, give a string to execute.
* This will overrule the previously loaded string or file.
*
* @param string $code
* @return void
*/
function execute($code=false)
{
if($code == false && $this->code == null)
{
die("Interpretation failed: No code was found.");
}
if($code == false)
{
$code = $this->code;
}
for($i=0;$i<strlen($code);$i++)
{
$curChar = $code{$i};
switch($curChar)
{
case '+':
$this->stack[$this->pointer]++;
if($this->stack[$this->pointer] > 255)
$this->stack[$this->pointer] = 1;
break;
case '-':
$this->stack[$this->pointer]--;
if($this->stack[$this->pointer] < 0)
$this->stack[$this->pointer] = 255;
break;
case '>':
$this->pointer++;
break;
case '<':
$this->pointer--;
break;
case '.':
$this->result .= chr($this->stack[$this->pointer]);
break;
case '[':
$this->loop_points[] = $i;
break;
case ']':
if($this->stack[$this->pointer] > 0)
$i = $this->loop_points[sizeof($this->loop_points) - 1];
else
array_pop($this->loop_points);
break;
case ',':
$this->stack[$this->pointer] = chr($this->stack[$this->pointer]);
break;
// This is one of my own commands.
// This echoes the byte under the current pointer
// (for debug usage)
case '#':
$this->result .= " debug::". $this->stack[$this->pointer]." ";
break;
case '?':
$this->result .= "<pre>[".print_r($this->stack, true)."]</pre>";
break;
// This resets the stack, the pointer and the all the loop points
case '%':
$this->stack = array();
$this->pointer = 0;
$this->loop_points = array();
break;
default:
break;
}
}
return $this->result;
}
}
?>