dc: Der Taschenrechner als Programmiersprache für Entwickler
dc ist ein klassischer Unix-Taschenrechner, älter als die Programmiersprache C, und in den Standarddistributionen der meisten Systeme enthalten, einschließlich macOS. Hinter seiner einfachen Fassade verbirgt sich eine vollwertige stapelbasierte Programmiersprache mit Registern, Makros, bedingten Konstrukten und Rekursion. Das Kernmodell ist der Stapel: Zahlen und Zeichenketten werden über Befehle auf den Stapel gelegt, Operatoren entnehmen die obersten Elemente, führen eine Aktion aus und geben das Ergebnis zurück.
Erste Berechnung: Um 2 + 2 zu addieren, geben Sie 2 2 + p ein. Hier schieben 2 2 die Zahlen zeilenweise auf den Stapel, + addiert die beiden obersten Elemente, und p gibt das Ergebnis aus.
2 2 +
p
4
Der Stapel ist das Schlüsselelement: Jedes Literal (Zahl oder [Zeichenkette]) legt einen Wert oben drauf. Kommentare beginnen mit #.
Arbeiten mit Registern und Variablen
dc bietet 256 Register (a-z, 0-9 und andere Zeichen), die Zahlen oder Zeichenketten speichern. Die Befehle sR speichern das oberste Element des Stapels in Register R, und lR laden es zurück. Register behalten ihren Zustand unabhängig vom Hauptstapel bei.
Beispiel für das Speichern und Wiederherstellen einer Zeichenkette:
[Hallo Welt!] sx
lx
p
Hallo Welt!
Register eignen sich für globale Variablen. Zahlen in Registern werden ähnlich wie auf dem Stapel manipuliert: li lädt i auf den Stapel.
Makros als Funktionen
Funktionen in dc sind Makros: Zeichenketten, die in Registern gespeichert und mit dem Befehl lRx ausgeführt werden, wobei x das Register ist. Makros werden als [Code] sR definiert.
Beispiel einer Funktion zur Addition der Register a und b:
[la lb +] sS
1 sa
2 sb
lSx
p
3
Makros unterstützen Rekursion und können sich gegenseitig aufrufen, wodurch Unterprogramme entstehen.
Bedingte Konstrukte
Verzweigungen basieren auf dem Vergleich der beiden obersten Elemente des Stapels. Operatoren umfassen =, >, <, != und andere. Wenn die Bedingung wahr ist, wird das Makro aus dem angegebenen Register ausgeführt.
[[Gleich] p] sE
[[Ungleich] p] sN
1 0
=E
1 0
!=N
Ungleich
Vergleiche verbrauchen zwei Elemente vom Stapel und hinterlassen das Ergebnis (0 oder 1).
Rekursive Schleifen
Es gibt keine Schleifen, aber Rekursion wird über Selbstaufrufe von Makros implementiert. Beispiel für die Ausgabe der Zahlen von 1 bis 10:
[
li p
1 + si
li 11 >C
] sC
1 si
lCx
Makro C gibt i aus, erhöht es und ruft sich selbst rekursiv auf, solange i < 11 ist. Das aktuelle i ist beim Eintritt bereits auf dem Stapel.
- Vorteile der Rekursion in dc: Einfachheit, keine expliziten Schleifen.
- Einschränkungen: Risiko eines Stapelüberlaufs bei tiefer Rekursion.
- Alternativen: Endrekursion minimiert die Stapelnutzung.
FizzBuzz in dc
Die Implementierung von FizzBuzz bis 100 demonstriert eine Kombination aus Makros, Bedingungen und Rekursion. Wichtige Befehle: P (Ausgabe ohne Zeilenumbruch), c (Stapel leeren).
Vollständiger Code:
[[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
Logik: Flag d bestimmt, ob die Zahl ausgegeben wird. Makro W prüft die Teilbarkeit durch 3/5 und setzt Fizz/Buzz. P mit 10 (LF) für einen Zeilenumbruch.
Fortgeschrittene Anwendungen: Peg Solitaire
dc ermöglicht das Lösen komplexer Aufgaben, wie Peg Solitaire – ein Puzzle mit Sprüngen von Stiften auf einem Brett. Der Brettzustand wird als Binärzahl kodiert, mit Manipulationen über arithmetische und bitweise Operationen (Verschiebungen und Masken sind verfügbar).
Bewegungsvalidierungsformeln in RPN sehen aufgrund bitweiser Prüfungen komplex aus, ermöglichen aber ein vollständiges Spiel: von der Anfangskonfiguration bis zum letzten Stift.
Dieser Ansatz zeigt dc als Werkzeug für Algorithmenprototyping ohne Kompilierung.
Wichtige Erkenntnisse
- Der Stapel ist die Grundlage aller Operationen: Literale legen drauf, Operatoren entnehmen/legen Ergebnisse.
- Register (insgesamt 256) für Zustände, Makros für Unterprogramme mit
lRx. - Bedingungen verbrauchen den Stapel, Rekursion ersetzt Schleifen.
p/Pfür Ausgabe,czum Leeren,%für Modulo.- Geeignet für Skripting, Prototyping und das Erlernen von RPN.
— Editorial Team
Noch keine Kommentare.