Brainfuck Article, Signification, Explication
Brainfuck est un langage de programmation minimaliste, inventé par Urban Müller en 1993. Le nom est anglais, il vient de la contraction de brain, cerveau, et fuck, niquer. Il a d'ailleurs d'autres noms comme Brainf*ck, Brainf*** ou encore BF. Auraient-ils honte ?
L'objectif de Müller était de créer un langage de programmation simple pour une machine de Turing qu'il pourrait implémenter avec le compilateur le plus petit possible. Le langage consiste en 8 instructions. La version 2 de son compilateur original, écrit pour l'Amiga, faisait 240 octets en taille.
Comme son nom ne le suggère pas pour un anglophobe, les programmes Brainfuck sont difficiles à comprendre, peut-être même dangereux pour la santé mentale des programmeurs. Le Brainfuck est un langage Turing-complet. Ce qui signifie que, malgré les apparences, il est théoriquement possible d'écrire n'importe quel programme informatique en Brainfuck.
Le langage est basé sur un modèle de machine simple consistant en un tableau d'octets initialisés à 0, d'un pointeur sur le tableau (pointant sur le premier octet du tableau) et de 2 files d'octets pour les entrées et les sorties.
Les 8 instructions du langage, chacune codée par une lettre, sont les suivantes :
| Caract. | Signification
|
|---|---|
| > | incrémente (augmente de 1) le pointeur.
|
| < | décrémente (diminue de 1) le pointeur.
|
| + | incrémente l'octet du tableau pointé par le pointeur (l'octet pointé).
|
| - | décrémente l'octet pointé. |
| . | sortie de l'octet pointé (valeur ASCII).
|
| , | entrée d'un octet dans le tableau à l'endroit du pointeur (valeur ASCII).
|
| [ | saute à l'instruction après le ] correspondant si l'octet pointé est à 0.
|
| ] | retourne à l'instruction après le [ si l'octet pointé est différent de 0. |
(Alternativement, ] peut être défini par « retourne au [ correspondant ». C'est plus court, mais moins symétrique et moins efficace en temps. Les deux versions produisent des programmes avec le même comportement.)
(Une troisième version équivalente, quoique moins considérée, est : [ signifie « saute après l'instruction ] correspondante », et ] signifie « retourne à l'instruction après le [ correspondant si l'octet pointé est différent de 0 ».)
Les programmes Brainfuck peuvent être traduits en C en utilisant les substitutions suivantes, en considérant que ptr est du type char*:
| Brainfuck | C
|
|---|---|
| > | ++ptr; |
| < | --ptr; |
| + | ++*ptr; |
| - | --*ptr; |
| . | putchar(*ptr); |
| , | *ptr = getchar(); |
| [ | while (*ptr) { |
| ] | } |
Un programme qui affiche « Hello World! » sur l'écran est :
Brainfuck est intéressant dans ce cas, un programme « Hello World! » n'est pas facile à écrire ! Et à lire !
Tant que l'octet est différent de 0, on le décrémente. On arrête donc la boucle ([]) quand il est à 0.
Prend un caractère du clavier pour l'afficher à l'écran.
Une boucle qui prend une entrée du clavier et l'affiche à l'écran. Notez qu'on s'attend à avoir un 0 pour marquer la fin de l'entrée (les implémentations peuvent être différentes à ce niveau là ).
Une version améliorée de la boucle précédente dans laquelle on stocke les caractères entrés dans le tableau pour une future utilisation, en déplaçant le pointeur à chaque fois.
Soit Tableau[0] = 2 et Tableau[1] = 8, « [ » débute la boucle, « - » et Tableau[0] = 1, « > » on pointe sur l'octet 1, « + » et Tableau[1] = 9, « ] » on recommence.
À la fin, on aura bien Tableau[0] = 0 ce qui arrête la boucle, et Tableau[1] = 10.
Ce programme prend un caractère minuscule en entrée et le met en majuscule. Pour arrêter, on tape la touche entrée (code 10 en Brainfuck dans la plupart des compilos).
Au début, on récupère le premier caractère (,) et on lui soustrait immédiatement 10 (10 fois -). Si l'utilisateur a tapé entrée, on a 0 dans l'octet pointé et l'instruction de boucle ([) sautera à la fin du programme.
Si le caractère entré n'est pas 10, on assume qu'il est en minuscule et on entre dans la boucle, où on va lui soustraire le nombre 22 (22 fois -), ce qui va faire 32 en tout, et 32 est la différence en ASCII entre la lettre minuscule et la même lettre en majuscule.
On va donc l'afficher, puis on en récupère une nouvelle, et à nouveau on lui soustrait 10. Et on repart au début de la boucle. Si le caractère entrée est un Entrée (10), la boucle s'arrêtera comme on l'a déjà vu, sinon on continue.Exemples
Hello World!
++++++++++[>+++++++>++++++++++>+++>+<<<<-] >++.>+.+++++++..+++.>++.<<+++++++++++++++. >.+++.------.--------.>+.>.
Remise à zéro de l'octet pointé
[-]Entrée/Sortie d'un caractère
,.Boucle simple
,[.,]Manipulation de pointeur
>,[.>,]Addition
Ce code ajoute l'octet courant (en le détruisant, il sera à 0 à la fin) à l'octet suivant.[->+<]Instructions conditionnelles
,----------[----------------------.,----------]
| [0] | [1] | [2] | [3] |
| 3 | 2 | 0 | 0 |
1re boucle : >[>+>+<<-]
| |||
| 3 | 1 | 1 | 1 |
| 3 | 0 | 2 | 2 |
2e boucle : >>[<<+>>-]
| |||
| 3 | 1 | 2 | 1 |
| 3 | 2 | 2 | 0 |
Fin boucle princ : <<<-]
| |||
| 2 | 2 | 2 | 0 |
1re boucle : >[>+>+<<-]
| |||
| 2 | 1 | 3 | 1 |
| 2 | 0 | 4 | 2 |
2e boucle : >>[<<+>>-]
| |||
| 2 | 1 | 4 | 1 |
| 2 | 2 | 4 | 0 |
Fin boucle princ : <<<-]
| |||
| 1 | 2 | 4 | 0 |
1re boucle : >[>+>+<<-]
| |||
| 1 | 1 | 5 | 1 |
| 1 | 0 | 6 | 2 |
2e boucle : >>[<<+>>-]
| |||
| 1 | 1 | 6 | 1 |
| 1 | 2 | 6 | 0 |
Fin boucle princ : <<<-]
| |||
| 0 | 2 | 6 | 0 |
Ensuite, il ne reste plus qu'à ajouter 48 au produit, récupérer la touche entrée dans [3], et afficher le produit ASCIIé et l'entrée qu'on vient juste de stocker.
On peut noter que comme chaque cellule du tableau est un octet, l'instruction « - » est superflue et peut-être remplacée par 255 « + ». De la même manière, les 30 000 cellules formant un tableau circulaire, « < » peut-être remplacé par 29 999 « > ». Cela réduirait le langage à 6 instructions.
. C'est un article concernant le Brainfuck. La page contient la signification du Brainfuck , Description et explication au sujet de Brainfuck Commentaire
