dc : La calculatrice en tant que langage de programmation pour développeurs
dc est une calculatrice Unix classique, plus ancienne que le langage C, incluse dans les distributions standard de la plupart des systèmes, y compris macOS. Derrière sa façade simple se cache un véritable langage de programmation à pile avec registres, macros, structures conditionnelles et récursivité. Le modèle central est la pile : les nombres et les chaînes sont empilés via des commandes, les opérateurs dépilent les éléments du sommet, effectuent une action et renvoient le résultat.
Premier calcul : pour additionner 2 + 2, saisissez 2 2 + p. Ici, 2 2 empile les nombres ligne par ligne, + additionne les deux éléments du sommet, et p affiche le résultat.
2 2 +
p
4
La pile est l'élément clé : tout littéral (nombre ou [chaîne]) empile une valeur au sommet. Les commentaires commencent par #.
Travailler avec les registres et les variables
dc fournit 256 registres (a-z, 0-9 et autres caractères) qui stockent des nombres ou des chaînes. Les commandes sR sauvegardent le sommet de la pile dans le registre R, et lR le recharge. Les registres maintiennent un état indépendant de la pile principale.
Exemple de sauvegarde et de restauration d'une chaîne :
[Bonjour le monde !] sx
lx
p
Bonjour le monde !
Les registres conviennent aux variables globales. Les nombres dans les registres sont manipulés de manière similaire à la pile : li charge i sur la pile.
Les macros comme fonctions
Les fonctions dans dc sont des macros : des chaînes stockées dans des registres, exécutées avec la commande lRx, où x est le registre. Les macros sont définies comme [code] sR.
Exemple d'une fonction pour additionner les registres a et b :
[la lb +] sS
1 sa
2 sb
lSx
p
3
Les macros prennent en charge la récursivité et peuvent s'appeler mutuellement, formant des sous-routines.
Structures conditionnelles
Les branchements sont basés sur la comparaison des deux éléments du sommet de la pile. Les opérateurs incluent =, >, <, !=, et d'autres. Si la condition est vraie, la macro du registre spécifié est exécutée.
[[Égal] p] sE
[[Non égal] p] sN
1 0
=E
1 0
!=N
Non égal
Les comparaisons consomment deux éléments de la pile, laissant le résultat (0 ou 1).
Boucles récursives
Il n'y a pas de boucles, mais la récursivité est implémentée via des auto-appels de macro. Exemple d'affichage des nombres de 1 à 10 :
[
li p
1 + si
li 11 >C
] sC
1 si
lCx
La macro C affiche i, l'incrémente et s'appelle récursivement tant que i < 11. Le i actuel est déjà sur la pile à l'entrée.
- Avantages de la récursivité dans dc : simplicité, pas de boucles explicites.
- Limitations : risque de débordement de pile avec une récursivité profonde.
- Alternatives : la récursivité terminale minimise l'utilisation de la pile.
FizzBuzz en dc
L'implémentation de FizzBuzz jusqu'à 100 démontre une combinaison de macros, de conditions et de récursivité. Commandes clés : P (affichage sans saut de ligne), c (vider la pile).
Code complet :
[[Fizz] P 0 sd] sF
[[Buzz] P 0 sd] sB
[li 3 % 0 =F li 5 % 0 =B] sW
[10 P] sP
[li p c] sD
[
1 sd
lWx
ld 0 =P
ld 1 =D
li 1 + si
li 101 >M
] sM
1 si
lMx
Logique : le drapeau d détermine s'il faut afficher le nombre. La macro W vérifie la divisibilité par 3/5, définissant Fizz/Buzz. P avec 10 (LF) pour un saut de ligne.
Applications avancées : Solitaire des pions
dc permet de résoudre des tâches complexes, comme le Solitaire des pions — un casse-tête avec des sauts de pions sur un plateau. L'état du plateau est encodé comme un nombre binaire, avec des manipulations via des opérations arithmétiques et bit à bit (les décalages et masques sont disponibles).
Les formules de validation des mouvements en NPI semblent complexes en raison des vérifications bit à bit mais permettent un jeu complet : de la configuration initiale au pion final.
Cette approche montre dc comme un outil de prototypage d'algorithmes sans compilation.
Points clés à retenir
- La pile est la base de toutes les opérations : les littéraux empilent, les opérateurs dépilent/empilent les résultats.
- Registres (256 au total) pour l'état, macros pour les sous-routines avec
lRx. - Les conditions consomment la pile, la récursivité remplace les boucles.
p/Ppour la sortie,cpour le nettoyage,%pour le modulo.- Adapté au scripting, au prototypage et à l'apprentissage de la NPI.
— Editorial Team
Aucun commentaire pour le moment.