Bibliotheken für Basic: Libraries in Omikron-Basic entwickeln, Teil 2

Bereits kurz nachdem Omikron-Basic zusammen mit den STs zur Auslieferung gelangte, waren zum Entwicklungssystem sogenannte Libraries erhältlich: nützliche Prozedur- und Funktions-Sammlungen, welche die Programmierung erheblich einfacher und komfortabler gestalten.

Der Basic-Interpreter lädt Libraries mit einem speziellen Befehl. Diese treten im Quelltext nur als Einzeiler in Erscheinung. Zudem kürzt der Compiler nicht benötigte Prozeduren und Funktionen aus der Library heraus. Beim Laden des Quelltextes fügt der Interpreter die Library automatisch hinzu, so daß sie keinen weiteren Speicherplatz auf der Diskette verbraucht. Früher mußte man stattdessen eine Sammlung von Funktionen als ASCII hinzuladen (mergen). Dies dauert zum einen sehr lange, zum anderen steht dann die gesamte Funktionssammlung als riesiger »Rattenschwanz« am Ende des Programms. Will man nun noch vor dem Compilieren überflüssige Teile entfernen, ist es erforderlich, den Quelltext als ASCII-Datei zu speichern und ein zusätzliches Programm zur weiteren Verarbeitung zu bemühen. Nachdem der Interpreter das Ganze zugeladen und als Tokencode gespeichert hat, darf der Compiler in Aktion treten. Diesen Vorgang erspart Ihnen eine Library. Diese hat allerdings ein spezielles Dateiformat und läßt sich nicht mit Omikron-Basic erzeugen. Den Library-Maker - einschließlich einiger Beispiele - finden Sie auf der nächsten TOS-Diskette. Das Programm erzeugt Libraries, die bis zu 100 verschiedene Bezeichner enthalten dürfen.

Zunächst etwas zum Aufbau einer Library und ihrer Behandlung durch den Interpreter. Das Datei-Format einer Library sieht folgendermaßen aus: zunächst eine »magische« Konstante: $611A. Dieses Wort muß zu Beginn einer jeden Library stehen, sonst lehnt der Interpreter jede Zusammenarbeit ab. Es folgt ein Langwort »Länge der Bezeichnertabelle«, die »Bezeichnertabelle« selbst, ein Langwort »Länge des Codesegmentes« und schließlich das »Codesegment«.

Die Bezeichnertabelle hat folgenden Aufbau:

1 Byte Länge des Bezeichners
n Bytes Bezeichner
evtl. 1 Füllbyte (gerade Adresse)
1 Byte Typ des Bezeichners (PROC, FN, LONGINT)
1 Byte Anzahl der Dimensionen bzw. Parameter

Das Codesegment besteht aus zusammengefaßtem Tokencode, der mit der Library-typischen Sequenz »LIBRARY CODE XXX: UNLIST« beginnt. Das spezielle Token »UNLIST« verhindert, daß mehr als der Header der Library im Listing erscheint. Dieses Token kann der Interpreter selbst nicht erzeugen und ist speziell für Libraries reserviert. Lädt der Interpreter eine Library, baut er zunächst alle Bezeichner der Reihe nach in die VARPTR-Tabelle ein. Dies geschieht ganz genauso, als hätten Sie die neue Variable oder Prozedur selbst eingegeben. Dabei erweitert der Interpreter die bereits vorhandene Tabelle des Hauptprogramms und korrigiert automatisch die sich dadurch ergebende Verschiebung der Referenzen im Codesegment der Library. Ein Beispiel: Im Quelltext der Library wird ein bestimmter Bezeichner mit dem Tabellenplatz 20 assoziiert. Da nun im Hauptprogramm dieser Platz schon besetzt ist, trägt der Interpreter den neuen »Library«-Bezeichner auf dem nächsten freien Tabellenplatz ein. Alle alten Referenzen in der Library werden von 20 auf die neue Nummer korrigiert. Anschließend wandert das gesamte Codesegment der Library an das Ende des Programms und erscheint als Einzeiler mit Nummer. Die so entstandene »LIBRARY CODE«-Zeile kann anschließend zwar durch den Lister angezeigt, aber nicht mehr verändert werden. Sie enthält Tokens, die der Befehlsumwandler (Tokenizer) nicht kennt, so daß eine Rückübersetzung der Zeile in Tokencode fehl schlägt. Der Compiler kann ein Basic-Programm mit Library ganz normal übersetzen, da äußerlich kein Unterschied besteht. Die Library erkennt der Compiler an der speziellen Zeilennummer und kürzt die nicht benötigten Funktionen.

Die Erzeugung der Library ist im Wesentlichen ein Kopieren des Codesegments. Ein »normales« Basic-Programm besteht normalerweise aus vier Segmenten:

  1. Die Zeilennummerntabelle - hier sind Nummer und Beginn einer jeden Zeile vermerkt.
  2. Das Codesegment - das Programm im Tokencode
  3. Die VARPTR-Tabelle - ein Feld von Zeigern für alle Variablen, Prozeduren, Felder usw, des Basic-Programms
  4. Das Variablensegment - hier sind die Namen der Variablen usw. zu finden

Das Generatorprogramm - der Library-Maker - analysiert nun das gesamte Codesegment und entfernt alle kritischen Konstruktionen (dazu mehr im zweiten Teil) bzw. gibt eine Warnmeldung aus. Es verschwinden sämtliche Kommentare, Zeilenenden und Einrückungen. Ausnahme: Ein doppelter Kommentar verbleibt im Library-Code. Beispiel:

...
Tu_Dies_Tu_Das	!  Dieser Kommentar wird gekürzt
Magic = $31415	!! Dieser Kommentar (z.B. Copyright) bleibt
...

Das so zusammengefaßte Codesegment bildet direkt das neue Codesegment der Library. Anschließend bildet der Library-Maker aus VARPTR-Tabelle und Variablensegment die Bezeichnertabelle (s.o.). Die Zeilennummern des zugrundeliegenden Basic-Programms spielen keine Rolle. Es ist daher auch nicht möglich, in einer Library mit Zeilennummern zu arbeiten. Als Abfallprodukt der Quelltextanalyse erzeugt der Library-Maker auf Wunsch eine zusätzliche Protokoll-Datei, die eine Art Crossreferenzliste der Library darstellt. Sie enthält alle Prozedur- und Funktionsaufrufe, sowie alle verwendeten globalen Größen. So kann man leicht überprüfen, ob vielleicht irgendwo eine »LOCAL«-Anweisung fehlt. Im zweiten Teil gehen wir genau auf die Anforderungen an den Quelltext sowie auf die Bedienung des Programms selbst ein. (ah)


Stefan Rinke
Aus: TOS 03 / 1991, Seite 96

Links

Copyright-Bestimmungen: siehe Über diese Seite