104 lines
3.7 KiB
Plaintext
104 lines
3.7 KiB
Plaintext
|
|
|||
|
|
|||
|
|
|||
|
Programmfestspeicher
|
|||
|
====================
|
|||
|
Vorerst einfach auf Festplatte in einem Verzeichnis.
|
|||
|
|
|||
|
|
|||
|
Datenfestspeicher
|
|||
|
=================
|
|||
|
Noch garnicht, sp<73>ter vielleicht auch Festplatte, oder mysql, oder wie auch
|
|||
|
immer.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Datenarbeitsspeicher
|
|||
|
====================
|
|||
|
Doppelt verkettete Liste, jedes Element kann zus<75>tzlich einen Namen haben.
|
|||
|
Zugriff entweder durch push/pop bzw. shift/unshift, <20>ber eine Nummer wie bei
|
|||
|
einem Array oder <20>ber seinen Namen wie bei einem Hash.
|
|||
|
Es ist aber auch m<>glich, direkt <20>ber einen Pointer zuzugreifen. Pointer
|
|||
|
lassen sich jedoch nicht vom Benutzer direkt erstellen, sondern nur von
|
|||
|
entsprechend priviligierten Programmen.
|
|||
|
|
|||
|
Im ersten Entwurf w<>rde man Elemente, auf die per Nummer oder Namen
|
|||
|
zugegriffen wird, durch naive Suche finden. Sp<53>ter kann man ja noch einen
|
|||
|
Index oder <20>hnliches drauf setzen.
|
|||
|
|
|||
|
Diese Speicherstruktur nenne ich "vector".
|
|||
|
|
|||
|
Datentypen:
|
|||
|
Nach Au<41>en hin sollen nur wenige verschiedene Datentypen sichtbar sein:
|
|||
|
- Wert (integer, string, was auch immer)
|
|||
|
- Vector
|
|||
|
|
|||
|
Wert wird intern in mehrere subtypen unterteilt, die jedoch automatisch
|
|||
|
bei Bedarf konvertiert werden:
|
|||
|
- int
|
|||
|
- float
|
|||
|
- string, bzw. pointer auf string
|
|||
|
- pointer auf Elemente eines Vektors
|
|||
|
|
|||
|
Aus technischer Sicht gibt es nach Au<41>en hin eigentlich auch nicht die
|
|||
|
Unterscheidung zwischen Wert und vector. Auch hier kann und wird bei Bedarf
|
|||
|
eine automatische Konvertierung vorgenommen. Im Normalfall wird jedoch der
|
|||
|
Anwender dies nicht tun, und in der Dokumentation wird auch immer ein klarer
|
|||
|
Unterschied zwischen normalen Werten und Vektoren gemacht.
|
|||
|
|
|||
|
Ein Sonderfall ist der Pointer auf Elemente eines Vektors: Weder kann von
|
|||
|
einem Wert in diesen Typ konvertiert werden, noch anders herum (bzw. doch,
|
|||
|
aber dann k<>me nur ein String "pointer" oder 0 bei heraus).
|
|||
|
|
|||
|
Die einzelnen Elemente eines Vektors werden in einem union gespeichert. Der
|
|||
|
Union enth<74>lt die verschiedenen m<>glichen Auspr<70>gungen der Werte, also int,
|
|||
|
float, und pointer. Zudem gibt es ein Feld, in dem gespeichert wird, welche
|
|||
|
Auspr<EFBFBD>gung gerade "aktiv" ist.
|
|||
|
|
|||
|
Ein zus<75>tzlicher Typ, den man sp<73>ter noch hinzuf<75>gen k<>nnte w<>re "array".
|
|||
|
Dieser Typ w<>rde sich zum Speichern gr<67><72>erer Datenmengen eignen, da er
|
|||
|
gegen<EFBFBD>ber einem Vektor keinen Overhead pro Element h<>tte.
|
|||
|
|
|||
|
Programmarbeitsspeicher
|
|||
|
=======================
|
|||
|
Der Programmspeicher ist nichts anderes als normaler Datenspeicher. Dies
|
|||
|
macht es m<>glich, Compilererweiterungen selbst in botforth zu schreiben.
|
|||
|
|
|||
|
|
|||
|
minibotforth
|
|||
|
============
|
|||
|
Folgende Befehle m<>ssen implementiert werden:
|
|||
|
- swap
|
|||
|
- +
|
|||
|
...
|
|||
|
|
|||
|
minibotforth sollte so extrem simpel sein, da<64> man es sp<73>ter vielleicht
|
|||
|
sogar ganz weg lassen kann, um direkt nach Maschinensprache zu kompilieren.
|
|||
|
|
|||
|
Compiler von botforth nach minibotforth
|
|||
|
========================================
|
|||
|
|
|||
|
1. Schritt: lexikalische analyse, also erkennen der einzelnen
|
|||
|
schluesselworte usw.
|
|||
|
Hier wird zwar erkannt, was ein Befehl ist, aber noch nicht, ob der Befehl
|
|||
|
intern oder extern vorliegt. Jeder Befehl wird als Node vom Typ
|
|||
|
BF_TYPE_C_TEXT gespeichert, wobei der Befehlsname in Klartext als String
|
|||
|
abgelegt wird.
|
|||
|
|
|||
|
2. Schritt: Compiler. Hier wird botforth nach minibotforth gewandelt. Auch
|
|||
|
hier werden jedoch Befehlsnamen als BF_TYPE_C_TEXT abgelegt.
|
|||
|
|
|||
|
3. Ausf<73>hrung: Erst w<>hrend der Programmausf<73>hrung, also wenn wir uns schon
|
|||
|
l<EFBFBD>ngst nicht mehr im Compilermodus befinden, werden Befehle vom Typ
|
|||
|
BF_TYPE_C_TEXT, sobald sie ausgef<65>hrt werden sollen, in BF_TYPE_C_INT bzw.
|
|||
|
BF_TYPE_C_EXT gewandelt.
|
|||
|
|
|||
|
Dies dient dazu, den Compiler vom User erweiterbar zu halten. Er kann so
|
|||
|
leicht Befehle einf<6E>gen, ohne mit Pointern etc. rumspielen zu m<>ssen. Somit
|
|||
|
wird auch kein Sicherheitsloch erzeugt. Aus der Sicht eines Anwenders, der
|
|||
|
den Compiler durch das Programmieren von Compilezeitverhaltens von Befehlen
|
|||
|
erweitern will, sind Befehle quasi wie Strings zu handhaben.
|
|||
|
|
|||
|
|
|||
|
|