Whitespace Programmiersprache / Interpreter
Kategorisierung: | Esoterische Programmiersprache |
Herkunft / Verwendung: | Whitespace ist eine esoterischen Programmiersprache, die Ende 2002 von Edwin Brady und Chris Morris entworfen wurde.
Die Befehle und Steueranweisungen bestehen im Gegensatz zu üblichen Programmiersprachen aus definierten Folgen von Leerzeichen, Tabs und Zeilenumbrüchen (engl. Whitespaces). Auch Daten werden damit dargestellt (binär mittels Tab (=1) und Leerzeichen (=0), Endezeichen Zeilenumbruch). Whitespace ist so gut wie nicht lesbar und umständlich zu programmieren. Die Sprache ist eher ein Scherz und trifft den Nerd-Humor. So geben die Erfinder an, dass man bei Ausdrucken von Whitespace-Quelltexten massenhaft Tinte spare und Spione, die Quelltextausdrucke entwendeten, nichts damit anfangen könnten. Allerdings gäbe es noch Probleme damit, den Code von Ausdrucken wieder einzugeben ;) Da Whitespace nicht auf den ersten Blick sichtbar ist, sondern erst, wenn man z. B. den Gesamttext markiert, geht die Sprache auch einen Schritt in Richtung Steganografie. |
Spezifikation
Ein Whitespace-Programm besteht aus dem Leerzeichen (l), Tabzeichen (t) und Zeilen-Umbrüchen (u). Im folgenden werden für die Lesbarkeit die entsprechenden Abkürzungen verwendet. Alles was nicht den drei Whitespace-Zeichen entspricht, wird nicht interpretiert und kann für Kommentare benutzt werden.Der Interpreter muss verfügen über:
- Stack-Speicher - auf diesen Stapelspeicher werden Daten abgelegt, wie Karten auf einen Kartenstapel. Nach dem Printip "zuletzt rein - zuerst raus" (LIFO, last in, first out). Jedesmal, wenn etwas wieder vom Stack genommen wird, wird es vernichtet.
- Heap-Speicher - zur Speicherung von Variablen. Daten können vom Stack auf den Heap gelegt werden.
- Sprungadressen-Speicher - Es können Sprungmarken definiert werden. Für diese werden die Adressen (Zeichenposition im Whitespace-Code) gespeichert.
- Call-Stack - Wenn Unterprogramme aufgerufen werden, wird hier die Rücksprungadresse abgelegt.
Befehle
Stack Manipulation (Befehl: l)
Stack Verarbeitung ist eine der häufigsten Operationen, daher die Kürze des Befehl l. Es gibt vier Stackanweisungen.
Befehl Parameter Bedeutung
l Zahl Schiebt eine Zahl auf den Stack
u l - Dupliziert das oberste Element auf dem Stack
u t - Tauscht die beiden oberen Elemente auf dem Stack
u u - Verwirft das oberste Element auf dem Stack
t u Anzahl Entfernt Anzahl Elemente vom Stack, behält das oberste
Arithmetik (Befehl: t l)
Arithmetische Befehle arbeiten mit den oberen beiden Elementen auf dem Stack und ersetzen sie durch das Ergebnis der Operation. Das als erstes auf den Stack geschobene Element steht links des Operators.
Befehl Parameter Bedeutung
l l - Addition
l t - Subtraktion
l u - Multiplikation
t l - Integer Division
t t - Modulo
Heap Zugriff (Befehl: t t)
Heap-Zugriffsbefehle sehen den Stack an, um die Adresse der zu speichernden oder abgerufenen Elemente zu finden. Um ein Element zu speichern, schieben Sie zuerst die Adresse, dann den Wert auf den Stack und führen dann den Speicherbefehl aus. Um ein Element abzurufen, schieben Sie die Adresse auf den Stack und führen dann den Abrufbefehl aus, der den Wert an der Stelle als oberstes Element des Stacks platziert.
Befehl Parameter Bedeutung
l - Speichern
t - Abrufen
Sprünge (Befehl: u)
Sprungbefehle sind ebenfalls üblich. Unterroutinen sind durch Spungmarken markiert, wie auch die Ziele der bedingten und bedingungslosen Sprünge, mit denen Schleifen umgesetzt werden können. Die Programme müssen mit 'u u u' beendet werden, damit der Interpreter sauber beendet werden kann.
Befehl Parameter Bedeutung
l l Spungmarke Markiert eine Position im Programm als Spungmarke
l t Spungmarke Ruft eine Unterroutine auf
l u Spungmarke Springt bedingungslos auf ein Spungmarke
t l Spungmarke Springt zu einer Spungmarke, wenn der Stacks null ist
t t Spungmarke Springt zu einer Spungmarke, wenn der Stacks negativ ist
t u - Beendet eine Unterroutine und kehrt zur Aufrufstelle zurück
u u - Beendet das Programm
Ein / Ausgabe (Befehl: t u)
Schließlich müssen wir noch mit dem Benutzer interagieren können. Es gibt Anweisungen zum Lesen und Schreiben von Zahlen und einzelnen Zeichen. Mit diesen können Stringmanipulationsroutinen geschrieben werden.
Befehl Parameter Bedeutung
l l - Gibt das Zeichen auf dem Stack aus
l t - Gibt die Zahl auf dem Stack aus
t l - Liest ein Zeichen und speichert es im Heap-Speicher an der dessen Adresse, die im Stack steht
t t - Liest eine Zahl und speichert es im Heap-Speicher an der dessen Adresse, die im Stack steht
Beispiel
Klartext: | kryptografie.de |
Whitespace lesbar: | lllttltlttutullllltttlltlutulllllttttlltutullllltttllllutullllltttltllutulllllttlttttutulllllttlltttutullllltttlltlutull lllttlllltutulllllttllttlutulllllttltlltutulllllttlltltutullllltltttlutulllllttlltllutulllllttlltltutulluuu |
Whitespace original: | (Markieren, um Whitespaces sichtbar zu machen)
|
Whitespace Anweisungen: |
00001 lllttltlttu push 107 (k)
00012 tull print char k
00016 llltttlltlu push 114 (r)
00027 tull print char r
00031 lllttttlltu push 121 (y)
00042 tull print char y
00046 llltttllllu push 112 (p)
00057 tull print char p
00061 llltttltllu push 116 (t)
00072 tull print char t
00076 lllttlttttu push 111 (o)
00087 tull print char o
00091 lllttlltttu push 103 (g)
00102 tull print char g
00106 llltttlltlu push 114 (r)
00117 tull print char r
00121 lllttlllltu push 97 (a)
00132 tull print char a
00136 lllttllttlu push 102 (f)
00147 tull print char f
00151 lllttltlltu push 105 (i)
00162 tull print char i
00166 lllttlltltu push 101 (e)
00177 tull print char e
00181 llltltttlu push 46 (.)
00191 tull print char .
00195 lllttlltllu push 100 (d)
00206 tull print char d
00210 lllttlltltu push 101 (e)
00221 tull print char e
00225 uuu END.
|