fz/entwurf.txt

104 lines
3.7 KiB
Plaintext
Raw Normal View History

2021-11-03 04:29:33 +01:00
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.