Interpreteur brainfuck

Description

sur cette source, je vous presente trois interpreteurs brainfuck.

le premier sans preprocessing

le second, est plus rapide, il evite une boucle.

le troisime est plus un compilateur brainfuck vers php.

Source / Exemple :


<?php

$stdin = fopen('php://stdin', 'r') or die ('erreur etrange');
/**

  • @brief fonction d'entree
  • renvoie le caractere ascii du caractere suivant de stdin.
  • @return int
  • /
function prompt(){ global $stdin; return ord(fread($stdin, 1)); } /**
  • @brief fonction qui interprete un code brainfuck
  • solution sans preprocessing
  • @param $code le code a interpreter
  • /
function brainfuck_verbeux($code){ $code_len = strlen($code); $mem = array(); $indice_memoire = 0; for ($i=0;$i<$code_len;$i++){ if (!isset($mem[$indice_memoire])) $mem[$indice_memoire]=0; else { // les valeurs sont comprises entre 0 et 256. $mem[$indice_memoire] = (256 + $mem[$indice_memoire] ) % 256; } switch($code[$i]){ case '>': $indice_memoire++; break; case '<': $indice_memoire--; break; case '.': echo chr($mem[$indice_memoire]); break; // on affiche la valeur case ',': $mem[$indice_memoire]=prompt(); break; case '+': $mem[$indice_memoire]++; break; // on incremente la valeur case '-': $mem[$indice_memoire]--; break; // on decremente la valeur case ']': $n = 1; // on doit remonter $n [ en arriere while ($n){ $i --; // on cherche en arriere if ($code[$i]==']') $n++; // si on rencontre un ], alors on attend un [ de plus else if ($code[$i]=='[') $n--; // si on trouve un [. alors on en attend un de moins } $i--; // on "jump" devant le [ correspondant. break; case '[': if ( $mem[$indice_memoire] == 0 ){ $n = 1; // on doit monter $n ] en avant while ($n){ $i ++; if ($code[$i]=='[') $n++; // si on rencontre un [, alors on attend un ] de plus else if ($code[$i]==']') $n--; // si on trouve un ]. alors on en attend un de moins } // ici, on a pas de $i-- parce-qu'on jump apres le ] } break; } } } /* la version ci dessus est une version legerement naive. On peut faire plus fin : eviter les boucles plus haut. Celles qui gerent les [ ]. Pour les eviter, il faut resoudre les [] en preprocessing, pour cela, il nous suffit d'utiliser une pile. quand on croise un [, on l'empile, quand on croise un ], on depile et on a le couple.
  • /
/**
  • @brief fonction qui interprete un code brainfuck
  • solution avec preprocessing ( relier les [ aux ] )
  • @param $code le code a interpreter
  • /
function brainfuck($code){ $code_len = strlen($code); // on gere les jumps ( [] ) $jmp = array(); $tmp = array(); for ($i=0;$i<$code_len;$i++){ if ($code[$i] == '[') array_push($tmp, $i); else if ($code[$i] == ']'){ $start = array_pop($tmp); $jumps[$start] = $i; $jumps[$i] = $start - 1; } } // on interprete $mem = array(); $indice_memoire = 0; for ($i=0;$i<$code_len;$i++){ if (!isset($mem[$indice_memoire])) $mem[$indice_memoire]=0; else { // les valeurs sont comprises entre 0 et 256. $mem[$indice_memoire] = (256 + $mem[$indice_memoire] ) % 256; } switch($code[$i]){ case '>': $indice_memoire++; break; case '<': $indice_memoire--; break; case '.': echo chr($mem[$indice_memoire]); break; case ',': $mem[$indice_memoire]=prompt(); break; case '+': $mem[$indice_memoire]++; break; case '-': $mem[$indice_memoire]--; break; case ']': $i = $jumps[$i]; break; case '[': if ( $mem[$indice_memoire] == 0 ) $i = $jumps[$i]; break; } } } function brainfuck_compilateur($str){ $checktab='if(!isset($tab[$pos])) $tab[$pos]=0;'; $replace = array( '+'=>'$tab[$pos] = ($tab[$pos]==255)?0:($tab[$pos]+1);', '-'=>'$tab[$pos] = ($tab[$pos]==0)?255:($tab[$pos]-1);', '>'=>'$pos++;'.$checktab, '<'=>'$pos--;'.$checktab, '['=>'while($tab[$pos]){', ']'=>'}', '.'=>'echo chr($tab[$pos]);', ','=>'$tab[$pos]=prompt();', ); for ($i=0, $code='$tab = array(0); $pos = 0;', $len = strlen($str); $i<$len; $i++) if (isset($replace[$str[$i]])) $code.=$replace[$str[$i]]."\n"; eval ($code); } brainfuck_verbeux( '++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.'); brainfuck_verbeux(',>,<+>+<.>.'); ?>

Conclusion :


branifuck powaaa

Codes Sources

A voir également