Advertisement
opsftw

BrainF*ck Interpreter

Jan 17th, 2017
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 3.61 KB | None | 0 0
  1. <?php
  2. class BF
  3. {
  4.     /*
  5.      *
  6.      * Developer(s): Kai (Tux.)
  7.      * Description: A BrainF*ck interpreter
  8.      *
  9.      * USAGE:
  10.      * $bf = new BF();
  11.      * echo $bf->interpret('codeHere', 'optionalInputHere');
  12.      *
  13.      */
  14.      
  15.     protected $pointer = 0, $validChars = array('>','<','.',',','+','-','[',']');
  16.     protected $cell = array(), $output = '', $input = '', $inputPointer = 0;
  17.    
  18.     public function interpret( $code, $input = '' ) {
  19.         $preparedCode = $this->prepare($code); // strip invalid characters and break into sections
  20.         $this->initializeCells(); // initialize cells to 0 for 30,000 cells
  21.         $this->input = $input;
  22.         #return print_r($code);
  23.         foreach($preparedCode as $line) { //loop threw the sections
  24.             if($line[0]) { // is a loop
  25.                 $safeGuard = 0;
  26.                 // Loop until the it lands on a cell that is zeroed out.
  27.                 //Only starts if current cell is not 0
  28.                 while($this->cell[$this->pointer]) {
  29.                     // if has looped more that 10,000 times then exit script and throw an error
  30.                     if($safeGuard > 10000) {
  31.                         die(print("Error in section:<br />\n'[{$line[1]}]'"));
  32.                     }
  33.                     // loop threw and interpret each character in the section
  34.                     foreach(str_split($line[1]) as $char) {
  35.                         $this->interpretChar($char);
  36.                         $safeGuard++;
  37.                     }
  38.                 }
  39.             } else { // not a loop
  40.                 // loop threw and interpret each character in the section
  41.                 foreach(str_split($line[1]) as $char) {
  42.                     $this->interpretChar($char);
  43.                 }
  44.             }
  45.         }
  46.         return $this->output;
  47.     }
  48.    
  49.     protected function initializeCells() {
  50.         for($i=0;$i<=30000;$i++) {
  51.             $this->cell[$i] = 0;
  52.         }
  53.     }
  54.    
  55.     protected function prepare( $code ) {
  56.         // some needed functions
  57.         $inBrackets = false;
  58.         $buffer = '';
  59.         $array = array();
  60.         // strip invalid characters
  61.         foreach(str_split($code) as $char) {
  62.             if(!in_array($char, $this->validChars, true)) {
  63.                 $code = str_replace($char, '', $code);
  64.             }
  65.         }
  66.         //split into sections of loops and non loops
  67.         foreach(str_split($code) as $char) {
  68.             if($inBrackets) {
  69.                 if($char === ']') {
  70.                     $inBrackets = false;
  71.                     $array[] = array(true, $buffer);
  72.                     $buffer = '';
  73.                 } else {
  74.                     $buffer .= $char;
  75.                 }
  76.             } else {
  77.                 if($char === '[') {
  78.                     $inBrackets = true;
  79.                     $array[] = array(false, $buffer);
  80.                     $buffer = '';
  81.                 } else {
  82.                     $buffer .= $char;
  83.                 }
  84.             }
  85.         }
  86.         //get the last lingering section if there is one
  87.         if($buffer !== '') {
  88.             $array[] = array(false, $buffer);
  89.             $buffer = '';
  90.         }
  91.         //return the processed code
  92.         return $array;
  93.     }
  94.    
  95.     protected function interpretChar( $char ) {
  96.         switch($char) {
  97.             case '>':
  98.                 return $this->cellForward();
  99.             case '<':
  100.                 return $this->cellBackward();
  101.             case '.':
  102.                 return $this->cellPrint();
  103.             case ',':
  104.                 return $this->cellStore();
  105.             case '+':
  106.                 return $this->cellIncriment();
  107.             case '-':
  108.                 return $this->cellDecriment();
  109.         }
  110.     }
  111.    
  112.     protected function cellForward() {
  113.         if($this->pointer !== 30000) {
  114.             $this->pointer++;
  115.         } else {
  116.             $this->pointer = 0;
  117.         }
  118.     }
  119.    
  120.     protected function cellBackward() {
  121.         if($this->pointer !== 0) {
  122.             $this->pointer--;
  123.         } else {
  124.             $this->pointer = 30000;
  125.         }
  126.     }
  127.    
  128.     protected function cellPrint() {
  129.         $this->output .= chr($this->cell[$this->pointer]);
  130.     }
  131.    
  132.     protected function cellStore() {
  133.         if(isset($this->input[$this->inputPointer])) {
  134.             $this->cell[$this->pointer] = ord($this->input[$this->inputPointer]);
  135.             $this->inputPointer++;
  136.         }
  137.     }
  138.    
  139.     protected function cellIncriment() {
  140.         $this->cell[$this->pointer]++;
  141.     }
  142.    
  143.     protected function cellDecriment() {
  144.         if($this->cell[$this->pointer] !== 0) {
  145.             $this->cell[$this->pointer]--;
  146.         }
  147.     }
  148. }
  149. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement