<?php
/*
*
* a PATH interpreter written in PHP by Alexis Ulrich (http://alx2002.free.fr)
* This code is in the public domain.
*
*/
class TuringMachine {
var $tape;
var $head; // the head position in the $tape array representation (from 0 to sizeOf($tape))
function TuringMachine() {
$this->tape = array();
$this->head = 0;
}
// moves the head one cell to the left
function toTheLeft() {
if ($this->head == 0) array_unshift($this->tape, 0);
else $this->head--;
}
// moves the head one cell to the right
function toTheRight() {
array_push($this->tape, 0);
$this->head++;
}
// increments the value of the current cell
function incrementCell() {
$this->tape[$this->head] += 1;
}
// decrements the value of the current cell
function decrementCell() {
$this->tape[$this->head] -= 1;
}
// writes the $value value in the current cell
function writeCell($value) {
$this->tape[$this->head] = $value;
}
// returns the content of the current cell
function readCell() {
return $this->tape[$this->head];
}
// dipslays the content of the Turing Machine tape
function showTape() {
if (sizeOf($this->tape) != 0) {
foreach ($this->tape as $cell)
echo "$cell*";
echo ' (head on '.$this->head.')<br>';
}
}
}
// opens a path file and puts it in an array
function getPath($file_name) {
return file($file_name);
}
// displays the ASCII art array representation of a path program
function displayPath($path_array) {
echo "<pre>\n";
foreach ($path_array as $line) echo $line;
echo "</pre>\n";
}
// gets the character at the given coordinates
function getChar ($path_array, $coord) {
$line = $path_array[$coord[0]];
return substr($line,$coord[1],1);
}
// gets the next coordinates from a given coordinates and direction
function nextCoord ($direction, $coord) {
switch ($direction) {
case 'right':
return array($coord[0],$coord[1]+1);
break;
case 'left':
return array($coord[0],$coord[1]-1);
break;
case 'up':
return array($coord[0]-1,$coord[1]);
break;
case 'down':
return array($coord[0]+1,$coord[1]);
break;
}
}
// gets the starter character ('$') position
function getStarter($path_array) {
$line_number = 0;
foreach ($path_array as $line) {
$start_pos = strpos($line, '$');
if ($start_pos !== False) return array($line_number,$start_pos);
$line_number++;
}
return False;
}
// interprets the path program with a Turing Machine
function pathInterpreter($path_array, $input='') {
global $TM, $output, $consumption;
if ($input != '') $input_head = 0;
$starter = getStarter($path_array);
$consumption = '$';
$direction = 'right';
$coord = nextCoord($direction, $starter);
$char = getChar($path_array, $coord);
$consumption .= $char;
$jump_next_symbol = False;
while ($char != '#') {
if (!$jump_next_symbol) {
switch ($char) {
case '!':
$jump_next_symbol = True;
break;
case '+':
$TM->incrementCell();
break;
case '-':
$TM->decrementCell();
break;
case '{':
$TM->toTheLeft();
break;
case '}':
$TM->toTheRight();
break;
case ',':
// read one character from $input string
$TM->writeCell(ord($input[$input_head++]));
break;
case '.':
$output .= chr($TM->readCell());
break;
case '/':
switch ($direction) {
case 'right':
$direction = 'up';
break;
case 'left':
$direction = 'down';
break;
case 'up':
$direction = 'right';
break;
case 'down':
$direction = 'left';
break;
}
break;
case '\\':
switch ($direction) {
case 'right':
$direction = 'down';
break;
case 'left':
$direction = 'up';
break;
case 'up':
$direction = 'left';
break;
case 'down':
$direction = 'right';
break;
}
break;
case '^':
if ($TM->readCell() != 0) $direction = 'up';
break;
case '<':
if ($TM->readCell() != 0) $direction = 'left';
break;
case '>':
if ($TM->readCell() != 0) $direction = 'right';
break;
case 'v':
if ($TM->readCell() != 0) $direction = 'down';
break;
}
}
else $jump_next_symbol = False;
// reads the next character
$coord = nextCoord($direction, $coord);
$char = getChar($path_array, $coord);
$consumption .= $char;
}
}
// counts the number of 'useful' characters in a path program
function pathCountChars($linearized_path) {
return count(preg_split("/[\}\{,.$#<>+-]/", $linearized_path)) - 3;
}
// removes all the 'unnecessary' characters from a path program
function pathCleaner($linearized_path) {
preg_match_all("/[\}\{,.$#<>+-]/", $linearized_path, $matches);
return implode('', $matches[0]);
}
$file_name = 'media.txt';
$path = getPath($file_name);
displayPath($path);
$TM = new TuringMachine();
$output = '';
$consumption = '';
pathInterpreter($path,'');
//$TM->showTape();
//echo "linearized program: $consumption<br>";
//echo "cleaned-up program: ".pathCleaner($consumption).'<br>';
//echo "which contains only ".pathCountChars($consumption).' useful characters (besides the begin and end characters).<br>';
echo "output: $output<br>";
?>