Interpreteur brainfuck

Contenu du snippet

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 / Exemple :


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;|

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.