Befunge
# Befunge

Befunge est un langage de programmation exotique réflexif à pile. Il diffère des langages conventionnels par le fait qu'il est arrangé sur une grille à deux dimensions. Des instructions « flèche » dirigent le flux de contrôle à gauche, à droite, en haut, en bas, et des boucles sont construites en envoyant le flux de contrôle dans un cycle.

## Histoire

Le langage a été créé par Chris Pressey en 1993, comme tentative de définir un langage aussi difficile à compiler que possible - la commande p permet le code automodifiant. Toutefois, un certain nombre de compilateurs ont été écrits par la suite. Un certain nombre d'extensions aux spécifications originelles « Befunge-93 » existent également, parmi lesquelles Funge-98, qui étend le concept à un nombre arbitraire de dimensions et peut être multi-threadé, avec des compteurs ordinaux multiples opérant de manière simultanée sur le même espace. Les extensions et variantes de Befunge sont appelées « Fungeoids » ou simplement des Funges.

Les spécifications de Befunge-93 restreignent tout programme valide à une grille de 80 instructions horizontalement à 25 instructions verticalement. Toute exécution du programme excédant ces limites se retrouve de l'autre côté de la grille. Un programme Befunge est de cette manière topologiquement équivalent à un tore. Comme un programme Befunge-93 ne peut avoir qu'une unique pile et que son tableau de stockage est limité, le langage Befunge-93 est, contrairement à la plupart des langages, non Turing-complet. Les spécifications Funge-98 fournissent la complétion Turing en enlevant la restriction de taille sur les programmes. Au lieu d'avoir des bords reliés de part et d'autre, Funge-98 fait en sorte que le compteur ordinal suive un modèle surnommé « Lahey-space » en référence à son créateur, Chris Lahey. Dans ce modèle, la grille se comporte comme un tore de taille finie par rapport à son repliement, tout en lui permettant de s'étendre infiniment.

## Exemple de code Befunge

La technique d'utiliser des flèches pour changer le flux de contrôle est montrée dans le programme générateur de nombre aléatoire ci-dessous. L'instruction ? envoie le compteur ordinal dans une direction aléatoire.

Le « Hello World! » classique

Une version plus idiomatique de « Hello World! » Befunge (en utilisant une 0gnirts)

Ne pas oublier le '0' en début du code pour sortir de la boucle induite par le '_' et le '#'. Dans le cas où la valeur 0 n'est pas présente et dans le cas d'un portage de l'interpréteur Befunge en C par exemple, un risque de segmentation existe. De toute évidence, il reste plus propre de sortir de la boucle ainsi, question de lisibilité (Même s'il est difficile de l'appréhender en Befunge.)

## Liste des instructions

| 0-9 | Empile ce nombre sur la pile |
| - | - |
| + | Addition: dépile a et b, puis empile a+b |
| - | Soustraction: dépile a et b, puis empile b-a |
| * | Multiplication: dépile a et b, puis empile a*b |
| / | Division entière: dépile a et b, puis empile la partie entière de b/a. Si a est nul, demande à l'utilisateur le résultat voulu. |
| % | Modulo: dépile a et b, puis empile le reste de la division entière de b/a. Si a est nul, demande à l'utilisateur le résultat voulu. |
| ! | NON logique: dépile une valeur. Si elle est nulle, empile 1; sinon, empile 0. |
| ` | Plus grand que: Dépile a et b, puis empile 1 si b>a, sinon 0. |
| > | Déplace vers la droite |
| < | Déplace vers la gauche |
| ^ | Déplace vers le haut |
| v | Déplace vers le bas |
| ? | Déplace vers une direction aléatoire |
| _ | Dépile une valeur; déplace à droite si valeur=0, à gauche sinon |
| | | Dépile une valeur; déplace en bas si valeur=0, en haut sinon |
| " | Démarre le mode chaine de caractères : empile chaque valeur ASCII jusqu'au prochain " |
| : | Duplique la valeur en sommet de pile |
| \ | Permute les deux valeurs en sommet de pile |
| $ | Dépile une valeur |
| . | Dépile une valeur et l'affiche en tant qu'entier |
| , | Dépile une valeur et l'affiche en tant que caractère ASCII |
| # | Trampoline: saute la cellule suivante |
| p | Dépile y, x et v, puis change les caractères à la position (x,y) dans le programme en le caractère dont le code ASCII est v |
| g | Dépile y et x, puis empile la valeur ASCII du caractère situé à cette position dans le programme |
| & | Demande un nombre à l'utilisateur et l'empile |
| ~ | Demande un caractère à l'utilisateur et empile son code ASCII |
| @ | Termine le programme |
