SNUSP
Un article de Wikipédia, l'encyclopédie libre.
Cet article fait partie de la série Langages de programmation |
Langages à objets |
4D - C++ - C# - D Delphi - Eiffel - Groovy Java - Python - Ruby Simula - Smalltalk Visual Basic - WinDev |
Langages impératifs |
APL - ASP - Assembleur BASIC - C - Cobol Forth - Fortran - Limbo Logo - Pascal - Perl - PHP |
Langages fonctionnels |
Haskell - ML/OCaml Lisp/Common Lisp Scheme XSLT |
Langages déclaratifs |
Clips - Prolog |
Langages concurrents |
Ada 95 - Erlang |
Langage de balisage |
HTML - SGML - XML S-expressions |
Voir aussi |
Conception - Codage Tests - Optimisations |
SNUSP (un acronyme récursif signifiant SNUSP's Not Unix, but Structured PATH) est un langage de programmation issu de la transformation du Brainfuck en un langage à deux dimensions, inspiré de PATH.
Le jeu d'instructions de SNUSP est plus proche du brainfuck que PATH, en conservant la même syntaxe pour les instructions relatives à la mémoire (+, -, > et <) et aux entrées/sorties (. et ,). Les instructions de contrôle de flot du brainfuck (] et [) sont remplacées par quatre instructions SNUSP nécessaires pour gérer le flot bidimentionnel : /, \, ? et !.
Sommaire |
[modifier] Fonctionnalités
Toutes les instructions sont représentées par un caractère non numérique.
L'exécution d'un programme SNUSP commence au caractère $, ou si absent du code source, au caractère le plus en haut et à gauche du programme, autrement dit le premier caractère du fichier. L'exécution commence vers la droite en ligne droite, un caractère à la fois, jusqu'à ce qu'une instruction de changement de direction modifie le flot d'exécution.
Les deux instructions de base du contrôle de flot, ruld (\) et lurd (/), provoquent un changement de direction de l'exécution par un virage à 90°. Ils peuvent être vus comme des miroirs. Comme en brainfuck, tous les caractères alphanumériques sont ignorés et peuvent être utilisés comme commentaires. En fait, les commentaires peuvent même contenir des instructions valides, du moment que le flot d'exécution n'y passe pas. L'ajout d'instructions valides dans les zones ou le flot d'exécution ne passe pas permet d'écrire du code impénétrable. Dans l'exemple suivant, l'exécution commence au $ et suite le chemin tracé autour du commentaire.
De ce fait, le programme n'affichera rien, malgré la présence d'une instruction de sortie (.). Les caractères = et | sont ignorés lors de l'exécution et permettent au programmeur et à d'éventuels lecteurs de mieux suivre le flot d'exécution.
/============# | Ceci est un $==/ commentaire.
En plus des instructions de changement de direction du flot d'exécution, il existe une instruction de saut inconditionnel (!) qui permet d'ignorer le caractère suivant, et une instruction de saut conditionnel (?) qui ignore le caractère suivant si et seulement si la cellule de mémoire courante contient zéro.
Il est possible de créer des fonctions par les instructions enter (@) et leave (#):
$===avant====@\===après===# | \===la=fonction===#
L'instruction enter 'empile' (mémorise) sa position et la direction du flot d'exécution dans la pile d'appel. Cette information est utilisée par l'instruction leave, qui 'dépile' (reprend les dernières informations) la pile d'appel et revient à l'endroit enregistré. Pour eviter de faire une boucle infinie, le caractères suivant le @ est ignoré . Si la pile est vide, l'instruction leave provoque l'arret du programme.
[modifier] Spécification
Comme l'indique ce document pdf, le langage est compartimenté en 3 langages de puissance croissante , chacun contenant le précédant :
- Core SNUSP
- Équivalent du Brainfuck en puissance avec une sémantique quasi-équivalente.
- Modular SNUSP
- Ajoute les fonctions en introduisant une pile d'appel et les instructions enter (@) et leave (#).
- Bloated SNUSP
- Ajoute la simultanéité et le non-déterminisme.
Cependant, voici l'adresse d'un entretien pour évoluer en un langage SRFI-style extension model plus scalable. [1]
[modifier] Exemple
Ce code SNUSP calcule le quotient et le reste obtenus par la division euclidienne de deux nombres decimaux à un chiffre issus de l'entrée standard :
/==!/============atoi=@@@@=@@=--# | | /==!/====itoa=@@@@=@@=++# | | | | $,@/>,@/@\@/.<@/.# | /-\ \===div=?\<!\?/#!===+<<<\ /-\ \<==@\>@\>>!/?!/=<?\>!\?/<<# | | #\->->+</ \=!\=?!/->>+<<?\# #\?<<+>>-/
Dans le programme ci-dessus, la convertion de chiffres ASCII en nombre entier est faite par les fonctions atoi et itoa, tandis que le calcul réel est exécuté par la fonction div. Au final, le resultat est affiché par la sortie standard.
Un autre exemple implantant la fonction d'Ackermann :
/==!/==atoi=@@@@=@@=--# | | | | [j]{i} -> {A(i,j)}, où A est la fonction d'Ackermann | | /=========\!==\!====\ ** recursive ** $,@/>,@/==ack=!\?\<+# | | | A(0,j) -> j+1 j i \<?\+>-@/# | | A(i,0) -> A(i-1,1) \@\>@\->@/@\<-@/# A(i,j) -> A(i-1,A(i,j-1)) {a}[ ][0] # # | | | {0}[ ][a] /-<<+>>\!=/ \=====|==@\>>>@\<<# {a}[ ][0] (a > 0) ? ? | | | [a]{ }[a] [0][ ]{a} \>>+<<-/!==========/ | | [a][ ]{0} # # | | {a}[ ][0][0] | | [0][ ][ ]{a} {0}[ ][a][a] | | [a][ ][ ]{0} #/?========\!==/ \==!/=======?\# \->>+>+<<</ \>>>+<<<-/
Comme dans l'exemple précédent, ce programme lit deux chiffres ASCII décimaux, les convertit en nombres entiers, et les utilise comme paramètres de la fonction ack.
Cependant, dans ce cas-ci, le résultat de la fonction n'est jamais affiché par la sortie standard; il ne peut être extrait que par l'utilisation d'un débogger. À cause de l'extrême taux de croissance fonction d'Ackermann, le résultat de la majorité des entrées ne tiendrait pas dans un seul nombre décimal à un seul chiffre; ainsi, un simple appel à la fonction itoa ne suffirait pas ici.
Les commentaires ressemblant à {a}[ ][0] commentent l'etat de la pile pour chaque fonction. La disposition de la pile antérieure à l'exécution de la fonction est écrite en premier, tandis que la disposition résultante est écrite au-dessous ou à droite. Chaque cellule est encadrée, et les accolades entourent la cellule courante.
Le programme qui utilise la fonction d'Ackermann démontre une propriété remarquable des langages dérivés de Befunge : le code peut être exécuté dans deux directions. Ceci est utilisé par la boucle qui déplace une valeur de deux cellules vers le haut, tout en pouvant déplacer une valeur de deux cellules vers le bas simplement en s'exécutant dans la direction opposée!
Pour compléter le programe, la fonction suivante peut être utilisée pour afficher le resultat dans un nombre ASCII décimal à plusieurs chiffres :
/recursive\ #/?\ zero ==print10=!\@\>?!\@/<@\.!\-/ | \=/ \==itoa=@@@+@+++++# ! /+ !/+ !/+ !/+ \ mod10 /<+> -\!?-\!?-\!?-\!?-\! \?!\-?!\-?!\-?!\-?!\-?/\ div10 # +/! +/! +/! +/! +/
[modifier] Liens externes
- Voici un interpréteur SNUSP pour différentes plate-formes, un débogueur SNUSP visuel écrit en Perl, et beaucoup d'exemples dans le Portland Pattern Repository Wiki: SnuspLanguage.
- Une spécification formelle incomplète du langage est disponible ici PDF document.
Portail de l'informatique – Accédez aux articles de Wikipédia concernant l’informatique. |