3v4l.org

run code in 150+ php & hhvm versions
Bugs & Features
<?PHP if (!class_exists('RuntimeException')) { class RuntimeException extends Exception { } } class InvalidStateException extends RuntimeException { } class Compiler { private $ptr; private $arr; private $code; private $commands = array('>', '<', '+', '-', '.', ',', '[', ']'); private $call_stack = array(); private $cellsize = 8; public function parseString($code, $throwException = true) { $this->code = $code; for ($i=0;$i<strlen($this->code);$i++) { $c = substr($this->code, $i, 1); if (!in_array($c, $this->commands)) { continue; } } } public function execute($code) { $this->arr = array(0 => 0); $this->ptr = 0; $this->code = $code; $jump = -1; $loop = array(); $depth = 0; for ($this->i=0;$this->i<strlen($this->code);$this->i++) { $c = $this->c = substr($this->code, $this->i, 1); $cell = $this->arr[$this->ptr]; if (!in_array($c, $this->commands)) { continue; } else if ($jump >= 0) { if ($c == '[') { $depth++; } if ($c == ']') { if ($depth === $jump) { $jump = -1; $this->stack(); } $depth--; } } else { if ($c == '>') { $this->increment_pointer(); } elseif ($c == '<') { $this->decrement_pointer(); } elseif ($c == '+') { $this->increment_val(); } elseif ($c == '-') { $this->decrement_val(); } elseif ($c == '.') { $this->output_val(); } elseif ($c == ',') { $this->store_val($this->input_val()); } elseif ($c == '[') { $depth++; if ($cell == 0) { $this->stack('jump'); $jump = $depth; } else { array_push($loop, $this->i); } } elseif ($c == ']') { if ($cell > 0) { $this->i = $loop[count($loop)-1]; continue; } else { array_pop($loop); $depth--; continue; } } } } } private function stack($func=null) { if (is_null($func)) { if (count($this->call_stack) == 0) { throw new InvalidStateException("Trying to pop empty call stack"); return false; } array_pop($this->call_stack); return true; } else { $info = array('command' => $this->c, 'pos' => $this->i, 'internal_function' => $func); array_push($this->call_stack, $info); echo 'Stacking '.$func.PHP_EOL; return true; } } public function minimum_cellsize() { return (-1*(pow(2, $this->cellsize-1))); } public function maximum_cellsize() { return pow(2, $this->cellsize-1)-1; } private function increment_pointer() { $this->stack(__FUNCTION__); $this->ptr++; if (!isset($this->arr[$this->ptr])) $this->arr[$this->ptr] = 0; $this->stack(); return true; } private function decrement_pointer() { $this->stack(__FUNCTION__); $this->ptr--; if ($this->ptr < 0) { throw new InvalidStateException("The data pointer is less than 0"); return false; } $this->stack(); return true; } private function increment_val() { $x = $this->arr[$this->ptr]++; if ($x < $this->minimum_cellsize()) { $this->arr[$this->ptr] = $this->maximum_cellsize(); } elseif ($x > $this->maximum_cellsize()) { $this->arr[$this->ptr] = $this->minimum_cellsize(); } return true; } private function decrement_val() { $x = $this->arr[$this->ptr]--; if ($x < $this->minimum_cellsize()) { $this->arr[$this->ptr] = $this->maximum_cellsize(); } elseif ($x > $this->maximum_cellsize()) { $this->arr[$this->ptr] = $this->minimum_cellsize(); } return true; } private function output_val() { $c = $this->arr[$this->ptr]; echo ''.chr($c); } private function store_val($chr) { $x = ord($chr); $this->arr[$this->ptr] = $x; } private function input_val() { return fgets(STDIN); } public function getCallStack() { return $this->call_stack; } public function getCells() { return $this->arr; } public function getPointer() { return $this->ptr; } } $c = new Compiler(); $bf = ' +++++++++++ >+>>>>++++++++++++++++++++++++++++++++++++++++++++ >++++++++++++++++++++++++++++++++<<<<<<[>[>>>>>>+> +<<<<<<<-]>>>>>>>[<<<<<<<+>>>>>>>-]<[>++++++++++[- <-[>>+>+<<<-]>>>[<<<+>>>-]+<[>[-]<[-]]>[<<[>>>+<<< -]>>[-]]<<]>>>[>>+>+<<<-]>>>[<<<+>>>-]+<[>[-]<[-]] >[<<+>>[-]]<<<<<<<]>>>>>[+++++++++++++++++++++++++ +++++++++++++++++++++++.[-]]++++++++++<[->-<]>++++ ++++++++++++++++++++++++++++++++++++++++++++.[-]<< <<<<<<<<<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]<-[>>.>.<<< [-]]<<[>>+>+<<<-]>>>[<<<+>>>-]<<[<+>-]>[<+>-]<<<-] '; try { $c->execute($bf); } catch (Exception $e) { echo PHP_EOL."An exception was thrown whilst processing your BF program.".PHP_EOL; echo $e->getMessage().":".PHP_EOL; } echo "The pointer was set to ".$c->getPointer()." and the cell array resembled:".PHP_EOL; echo "[".implode(", ", $c->getCells())."]".PHP_EOL; echo "The current stack trace was:".PHP_EOL; foreach ($c->getCallStack() as $k => $call) { echo '#'.$k.' '.$call['command'].' ('.$call['internal_function'],') on pos '.$call['pos'].PHP_EOL; } echo PHP_EOL.'Finished.'.PHP_EOL; ?>