Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

INTERPRETEUR BRAINFUCK


Information sur la source

Catégorie :Divers Classé sous : brainfuck, interpreteur, fonction, procedure, mysql Niveau : Initié Date de création : 17/08/2008 Date de mise à jour : 18/08/2008 18:56:51 Vu : 3 611

Note :
Aucune note

Commentaire sur cette source (2)
Ajouter un commentaire et/ou une note


Description

certains m'ont dit que le mysql n'etait pas un langage de programmation, mais seulement un langage de description de requetes, d'interrogations de db, etc....

ils ont alors ajoute que le caractere turing complete etait caracteristique d'un langage de programmation (ce qui n'est pas totalement vrai....)

voici donc un interpreteur brainfuck en mysql. le code suivant prouve que mysql est turing complete.

pour lancer la source, lancez mysql en console, selectionnez une database, puis copiez la source.
 

Source

  • delimiter |
  • CREATE DATABASE `test`;|
  • USE `test`;|
  • DROP FUNCTION IF EXISTS CHARAT;|
  • CREATE FUNCTION CHARAT(str TEXT, i INT) RETURNS CHAR
  • BEGIN
  • RETURN SUBSTRING(str,i,1);
  • END;|
  • DROP TABLE IF EXISTS `memory`;|
  • CREATE TABLE IF NOT EXISTS `memory`( `indice` INT, `valeur` INT);|
  • DROP FUNCTION IF EXISTS GETMEM;|
  • CREATE FUNCTION GETMEM(i INT) RETURNS INT NOT DETERMINISTIC
  • BEGIN
  • DECLARE r INT;
  • SET r = (SELECT valeur FROM `memory` WHERE `indice` = i);
  • IF r IS NULL THEN
  • RETURN 0;
  • END IF;
  • RETURN r;
  • END;|
  • DROP PROCEDURE IF EXISTS SETMEM;|
  • CREATE PROCEDURE SETMEM(i INT, v INT) NOT DETERMINISTIC
  • BEGIN
  • DELETE FROM `memory` WHERE `indice` = i;
  • INSERT INTO `memory`(`indice`, `valeur`) VALUES (i, v mod 256);
  • END;|
  • /*
  • CALL SETMEM(1, 12);|
  • SELECT GETMEM(0), GETMEM(1);|
  • */
  • DROP TABLE IF EXISTS `jmp`;|
  • CREATE TABLE `jmp`(`indice_code` INT, `indice_jmp` INT);|
  • /* parsing des jmp */
  • DROP PROCEDURE IF EXISTS PARSECODE;|
  • CREATE PROCEDURE PARSECODE ( code TEXT )
  • BEGIN
  • DECLARE i_code, len_code, tmp INT;
  • DECLARE char_code CHAR;
  • DELETE FROM `jmp`;
  • SET i_code = 0;
  • SET len_code = LENGTH(code);
  • REPEAT
  • SET char_code = CHARAT(code, i_code);
  • IF char_code = '[' THEN
  • INSERT INTO `jmp` (`indice_code`) VALUES (i_code);
  • ELSE
  • IF char_code = ']' THEN
  • SET tmp = (SELECT `indice_code` FROM `jmp` WHERE `indice_jmp` IS NULL ORDER BY `indice_code` DESC LIMIT 1) ;
  • UPDATE `jmp` SET `indice_jmp` = i_code WHERE `indice_code` = tmp;
  • END IF;
  • END IF;
  • SET i_code = i_code + 1;
  • UNTIL i_code > len_code END REPEAT;
  • END;|
  • /*
  • CALL PARSECODE("[ [ ] [ ] ]");|
  • SELECT * FROM `jmp`;|
  • */
  • DROP FUNCTION IF EXISTS bf;|
  • CREATE FUNCTION bf ( code TEXT, input TEXT) RETURNS TEXT
  • BEGIN
  • DECLARE i_code, len_code INT;
  • DECLARE char_code CHAR;
  • DECLARE stdout TEXT;
  • DECLARE i_input INT;
  • DECLARE i_memory INT;
  • DECLARE i_stack INT;
  • DECLARE tmp INT;
  • CALL PARSECODE(code);
  • DELETE FROM `memory`;
  • SET i_code = 0;
  • SET i_stack = 0;
  • SET len_code = LENGTH(code);
  • SET stdout = "";
  • SET i_memory = 0;
  • SET i_input = 0;
  • REPEAT
  • SET char_code = CHARAT(code, i_code);
  • CASE char_code
  • WHEN '.' THEN
  • SET stdout = CONCAT(stdout, CHAR(GETMEM(i_memory) ));
  • WHEN ',' THEN
  • BEGIN
  • CALL SETMEM(i_memory, CHARAT(input, i_input));
  • SET i_input = i_input + 1;
  • END;
  • WHEN '>' THEN
  • SET i_memory = i_memory + 1;
  • WHEN '<' THEN
  • SET i_memory = i_memory - 1;
  • WHEN '+' THEN
  • CALL SETMEM(i_memory, GETMEM(i_memory) + 1);
  • WHEN '-' THEN
  • CALL SETMEM(i_memory, GETMEM(i_memory) - 1);
  • WHEN '[' THEN
  • BEGIN
  • IF GETMEM(i_memory) = 0 THEN
  • SET i_code = (SELECT `indice_jmp` FROM `jmp` WHERE `indice_code` = i_code);
  • END IF;
  • END;
  • WHEN ']' THEN
  • BEGIN
  • SET i_code = (SELECT `indice_code` FROM `jmp` WHERE `indice_jmp` = i_code);
  • SET i_code = i_code - 1;
  • END;
  • ELSE
  • BEGIN
  • END;
  • END CASE;
  • SET i_code = i_code + 1;
  • UNTIL i_code > len_code END REPEAT;
  • RETURN stdout;
  • END;|
delimiter |

CREATE DATABASE `test`;|
USE `test`;|

DROP FUNCTION IF EXISTS CHARAT;|
CREATE FUNCTION CHARAT(str TEXT, i INT) RETURNS CHAR
BEGIN
  RETURN SUBSTRING(str,i,1);
END;|


DROP TABLE IF EXISTS `memory`;|
CREATE TABLE IF NOT EXISTS `memory`( `indice` INT, `valeur` INT);|

DROP FUNCTION IF EXISTS GETMEM;|
CREATE FUNCTION GETMEM(i INT) RETURNS INT NOT DETERMINISTIC
BEGIN
  DECLARE r INT;
  SET r = (SELECT valeur FROM `memory` WHERE `indice` = i);
  IF r IS NULL THEN
    RETURN 0;
  END IF;
  RETURN r;
END;|


DROP PROCEDURE IF EXISTS SETMEM;|
CREATE PROCEDURE SETMEM(i INT, v INT) NOT DETERMINISTIC
BEGIN
  DELETE FROM `memory` WHERE `indice` = i;
  INSERT INTO `memory`(`indice`, `valeur`) VALUES (i, v mod 256);
END;|
/*
CALL SETMEM(1, 12);|
SELECT GETMEM(0), GETMEM(1);|
*/
DROP TABLE IF EXISTS `jmp`;|
CREATE TABLE `jmp`(`indice_code` INT, `indice_jmp` INT);|

/* parsing des jmp */
DROP PROCEDURE IF EXISTS PARSECODE;|
CREATE PROCEDURE PARSECODE ( code TEXT )
BEGIN
  DECLARE i_code, len_code, tmp INT;
  DECLARE char_code CHAR;
  DELETE FROM `jmp`;
  SET i_code = 0;
  SET len_code = LENGTH(code);
  REPEAT
    SET char_code = CHARAT(code, i_code);
    IF char_code = '[' THEN
      INSERT INTO `jmp` (`indice_code`) VALUES (i_code);
    ELSE
      IF char_code = ']' THEN
        SET tmp = (SELECT `indice_code` FROM `jmp` WHERE `indice_jmp` IS NULL ORDER BY `indice_code` DESC LIMIT 1) ;
        UPDATE `jmp` SET `indice_jmp` = i_code WHERE `indice_code` = tmp;
      END IF;
    END IF;
    SET i_code = i_code + 1;
  UNTIL i_code > len_code END REPEAT;
END;|
/*
CALL PARSECODE("[ [  ] [ ] ]");|
SELECT * FROM `jmp`;|
*/
DROP FUNCTION IF EXISTS bf;|
CREATE FUNCTION bf ( code TEXT, input TEXT) RETURNS TEXT
BEGIN
  DECLARE i_code, len_code INT;
  DECLARE char_code CHAR;
  DECLARE stdout TEXT;
  DECLARE i_input INT;
  DECLARE i_memory INT;
  DECLARE i_stack INT;
  DECLARE tmp INT;
  CALL PARSECODE(code);
  DELETE FROM `memory`;
  SET i_code = 0;
  SET i_stack = 0;
  SET len_code = LENGTH(code);
  SET stdout = "";
  SET i_memory = 0;
  SET i_input = 0;
  REPEAT
    SET char_code = CHARAT(code, i_code);
    CASE char_code
      WHEN '.' THEN
        SET stdout = CONCAT(stdout, CHAR(GETMEM(i_memory) ));
      WHEN ',' THEN
          BEGIN
            CALL SETMEM(i_memory, CHARAT(input, i_input));
            SET i_input = i_input + 1;
          END;
      WHEN '>' THEN
        SET i_memory = i_memory + 1;
      WHEN '<' THEN
        SET i_memory = i_memory - 1;
      WHEN '+' THEN
        CALL SETMEM(i_memory, GETMEM(i_memory) + 1);
      WHEN '-' THEN
        CALL SETMEM(i_memory, GETMEM(i_memory) - 1);
      WHEN '[' THEN
        BEGIN
          IF GETMEM(i_memory) = 0 THEN
            SET i_code = (SELECT `indice_jmp` FROM `jmp` WHERE `indice_code` = i_code);
          END IF;
        END;
      WHEN ']' THEN
        BEGIN
          SET i_code = (SELECT `indice_code` FROM `jmp` WHERE `indice_jmp` = i_code);
          SET i_code = i_code - 1;
        END;
      ELSE
        BEGIN
        END;
    END CASE;
    SET i_code = i_code + 1;
  UNTIL i_code > len_code END REPEAT;
  RETURN stdout;
END;|

Conclusion

pour tester :

CALL SETMEM(1, 12);|
SELECT GETMEM(0), GETMEM(1);|

CALL SETMEM(1, 12);|
SELECT GETMEM(0), GETMEM(1);|

SELECT bf("+++++[->+++++++++++<]>.", "") AS result;| /* affiche 7 */
SELECT bf("++++++++++++++++++++++++++++++++++++++++++++++++.", "") AS result;| /* affiche 2 */
/*hello world*/
SELECT bf("++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.", "") AS result;|

 

Historique

18 août 2008 18:56:51 :
pour le code : [...] j'interpretais : do{ ...}while(*ptr); or, le vrai brainfuck, c'est : while(*ptr){ ... }

Commentaires et avis

signaler à un administrateur
Commentaire de pysco68 le 18/08/2008 09:31:34

Je tire mon chapeau... (en ai pas... v_v) et je me vois quelque peux contraint à retirer mes propos de "SQL n'est pas un langage de programmation"....

je m'en excuse....

d'ailleur un petit conseil à toi coucou747... il y a régulièrement des concours sur le net pour des défis de ce type.... à mon avis tu pourrais gagner un bon prix ^^

Je m'excuse encore ;)

Bonne journée!

signaler à un administrateur
Commentaire de coucou747 le 18/08/2008 15:12:29

pas de probleme :)

Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

Première fonction MySQL [ par RaphAstronome ] Bonjour,Je suis en train de faire ma première fonction MySQL.Elle est sensé traduire un BIGINT en BLOB mais il semble qu'il y est une érreur de sytaxe Somme de champs MySQL [ par dthuler ] Bonjour à tous,Voilà une question de débutant:Je cherche le moyen (fonction?) d'additionner les valeurs d'un champ d'une sélection SQL (voir exemple c VB - requete mysql en utilisant des fonctions intégrées [ par nath_77 ] Bonjour à tous,J'ai un problème dont je ne trouve pas la solution.Je travaille sous access avec un bdd Mysql . Je veux au cours de mon application eff Comment créer une procedure avec mysql [ par gregoire2008 ] Bonjour, ma question est peut être un peu débile mais je n'arrive pas à créer de procédure stockée avec mysql. J'utilise la version 4.1.9 et quand je procedure select [ par abdoulax ] Bonjour,Je suis en train de faire un projet oracle pour mes études. Ce projet mélange du php avec une base oracle. Lors d'un bilan en cours de projet help svp [ par melleweb ] je cherche une fonction de manipulation des chaines de caractères en pl/sql ou sql pareil a cet exemple:fonction_recherchée('salut tout le monde','mon helr please [ par melleweb ] je cherche une fonction de manipulation des chaines de caractères en pl/sql ou sql pareil a cet exemple:fonction_recherchée('salut tout le monde','mon Bdlink oracle vers Mysql [ par rabdou ] Salut tous le mondeje vx Utilise des services d'accès hétérogènes d'ORACLE pour accéder à une base de données mysql(oracle sous windows et mysql aussi Procedure stocker avec toad [ par lightzeus ] <td id="HB_Focus_Element" valign="top" Conversion de dates [ par Chatbour ] Salut à tous je voudrais savoir s'il existe une fonction Access qui convertie les date à l'anglaise (#mois-jour-année#) au format français (#jour-mois


Nos sponsors

Sondage...

CalendriCode

Janvier 2009
LMMJVSD
   1234
567891011
12131415161718
19202122232425
262728293031 

Consulter la suite du CalendriCode



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel BAÏSE, Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,421 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.