Programmation Brainfuck/Les 8 instructions du langage

Un livre de Wikilivres.
Sauter à la navigation Sauter à la recherche

Les 8 instructions du langage, chacune codée par un caractère, 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.

Remarques :

  • 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 que [ 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".

Commentaires[modifier | modifier le wikicode]

Tout autre caractère que les 8 correspondant aux instructions est ignoré et considéré comme un commentaire, ce qui inclut les lettres et les chiffres.

Compilation en C[modifier | modifier le wikicode]

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) {
] }

Le programme en C ci-dessous génère un code source en C à partir d'un programme source en Brainfuck. Cependant, le programme généré a une limite de taille mémoire, et le débordement de pointeur n'est pas vérifié.

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

#define DEFAULT_DATA_SIZE 1024

void printHeader(unsigned int data_size)
{
	printf("#include <stdio.h>\n");
	printf("#include <stdlib.h>\n\n");
	printf("unsigned char octets[%d];\n", data_size);
	printf("unsigned char *ptr;\n\n");
	printf("int main()\n");
	printf("{\n");
	printf("\tptr = octets + %d;\n", data_size/2); /* Pointeur au milieu */
	return;
}

void printFooter()
{
	printf("\n\treturn 0;\n}\n");
	return;
}

int main()
{
	unsigned int data_size = DEFAULT_DATA_SIZE;
	int c;
	printHeader(data_size);
	while ((c = getchar()) != EOF)
	{
		switch(c)
		{
			case '>': printf("\tptr++;\n"); break;
			case '<': printf("\tptr--;\n"); break;
			case '+': printf("\t(*ptr)++;\n"); break;
			case '-': printf("\t(*ptr)--;\n"); break;
			case '.': printf("\tputchar(*ptr);\n"); break;
			case ',': printf("\t*ptr = getchar();\n"); break;
			case '[': printf("\twhile (*ptr)\n{\n"); break;
			case ']': printf("\t}\n"); break;
		}
	}
	printFooter();
	return 0;
}