Home Up Intro Contents Chapter 1 2 3 4 5 6 7 8 9 10 Design Assert Timing EBNF Report Pas Last Changed: Nov. 19, 1997
This is a conversion from Oberon text to HTML. The converter software is still under development, and some features or information may be missing in this converted version. HTML hypertext facilities are not yet active in this document. To exploit the interactive facilities, use Oberon System 3 and the source of this text, available as ASCII-coded Oberon System 3 documents. A previous version is also available for Oberon V4. To access this and other additional material use ftp.
For the convenience of our students, most of this information and the related material is in German. Sorry if this is not one of your languages.

Einführung in die Programmiersprache Oberon.

G. Sawitzki <gs@statlab.uni-heidelberg.de>



10 Das Oberon-Laufzeitsystem

Programme, oder genauer Module, können in Oberon auf Dienste anderer Module zurückgreifen, zum Beispiel auf die Dienste der Module

System  System-Information und Steuerung
Texts  Grundlagen der Textverarbeitung
Builder  Compiler-Oberfläche und Fehlerdiagnostik
Compiler  Compiler für Oberon-Programme

Wir haben bisher die Ein- und Ausgabe stiefmütterlich behandelt. Ein- und Ausgabe sind nicht Bestandteil der Sprache selbst, sondern Dienste, die von Prozeduren erbracht werden. Für diese Prozeduren gibt es keine Ausnahmeregeln. Sie folgen den allgemeinen Regeln der Sprache Oberon. In der Referenz-Implementierung des Oberon-Systems sind die grundlegenden Prozeduren für Texteingabe bzw. -ausgabe im Modul Texts zu finden.

Oberon ist modular und erweiterbar. Deshalb kann auf jedem Gerät das Oberon-System angepasst sein und zusätzliche Leistungen erbringen oder den Zugriff auf Leistungen beschränken oder die Leistungen in veränderter Art erbringen. Der aktuelle Leistungsumfang eines Systems kann nicht statisch beschrieben werden, sondern nur - etwa mit Hilfe des Moduls System - dynamisch bestimmt werden. Als Orientierung kann dabei das Referenz-Modell des Oberon-Systems dienen. Seine Funktionen und Nutzung sind in Reiser (1993) beschrieben. Design und Implemetierung, und damit der gesamte innere Aufbau, sind in Wirth und Gutknecht (1992) dokumentiert. Das Referenz-Modell kann jedoch nur eine Orientierung sein - konkrete Implementierungen weichen davon ab.

Oberon repräsentiert eine Weiterentwicklung in der Informatik. Bequeme Vorurteile und Vereinfachungen müssen über Bord geworfen werden, wenn es auf diese Reise geht. Nicht zum erstem Mal muss man sich von Ballast befreien. Frühe Ansätze in der Informatik liessen im wesentlichen nur sequentielle Programme zu, mit (bedingten) Sprüngen als einzige Ausnahme. Die bequeme lineare Struktur, in der man hier dachte, wurde durchbrochen mit Programmiersprachen wie Algol. Programme konnten nun als strukturiert betrachtet werden, als grosse Kontrollstruktur mit Blöcken (oder Module) als Elementen. Die vorherrschende Betrachtung war immer noch die eines Hauptprogramms, das eine Hierarchie von Unterprogrammen aufruft. Die typische Struktur war die eines Baumes (wenn auch Algol schon Rekursionen zuliess). Ein Baum ist eine einfachere Struktur als ein allgemeiner Graph, aber es gibt keine sachliche Notwendigkeit, sich auf die geordnete Struktur eines Baumes zu beschränken. In Oberon wird diese Baum-Struktur nicht mehr vorausgesetzt.

Oberon sollte als allgemeiner Graph betrachtet werden. Je nach Aspekt der Betrachtung wird man in diesem Graphen Bäume erkennen können. Es gibt jedoch nicht die ausgezeichnete Wurzel des Baumes. Bei jeder Analyse des Oberon-Systems muss festgelegt werden, unter welchem Aspekt diese Analyse steht. Dies bestimmt in der Regel, welches Modul zum Ausgangspunkt der Analyse dient.

Einen Überblick über das aktive System erhält man mit
  System.ShowModules
In dieser Übersicht sind jedoch nur die aktiven Module enthalten. Daneben gibt es noch Module, die erfolgreich compiliert und damit verfügbar, aber noch nicht geladen sind. Konventionell sind diese Module in Dateien mit der Namens-Endung .Obj gespeichert. Eine Liste dieser Module erhält man mit
  System.Directory *.Obj

Eine erste Information über die Module enthält man anhand der Kommandos, die in diesen Module definiert sind. Ist der Name eines Moduls selektiert, so gibt
  System.ShowCommands ^ ,
z.B.
  System.ShowCommands Oberon
eine Liste der Kommandos. Eine weitergehendes Bild erhält man, indem man die gesamte exportierte Information auflisten lässt. Dies geschieht mit dem Kommando
  Browser.ShowDef ^
z.B.
  Browser.ShowDef Oberon


Im nächsten Schritt erhält man weitergehende Abhängigkeiten, die man mit Browser.ShowDef ^ untersuchen kann.


In diesem Diagramm sind Files und Display als Endpunkte erkennbar. Von ihnen gehen keine Rufe zu tieferliegenden Modulen.

In einem erweiterbaren modularen System ist die Konsistenz nicht automatisch gesichert. Man kann nicht von einem einheitlich installierten System ohne Veränderungen ausgehen. Deshalb muss zur Laufzeit überprüft werden, ob das System hinreichend konsistent ist. Die Überprüfung erfolgt in Oberon dann, wenn ein Modul geladen wird und hat zwei Schritte. Zunächst wird überprüft, ob das gerufene Modul als Datei vorhanden ist und ob diese Datei tatsächlich ein Modul enthält. Tritt dabei ein Fehler auf, so ist eine typische Fehlermeldung
  Call error: xxxx not found
Ist das Modul gefunden, so wird überprüft, ob die exportierte Information des Moduls den Deklarationen entspricht, die das rufende Modul erwartet. Tritt dabei ein Fehler auf, so ist eine typische Fehlermeldung
Call error: yyyy imports xxxxx with bad key

Am Beispiel der Ein-/Ausgabe untersuchen wir nun das Zusammenspiel verschiedener Module. "Files" ist das Modul, das einen Basis-Datentyp zur Speicherung von Daten unterstützt, den Typ File. Jedes Computersystem braucht eine Möglichkeit, Daten gesichert für längere Zeit zu speichern und gespeicherte Daten wiederzugewinnen. Diese Funktion wird in Oberon vom Modul Files übernommen. Das Basis-Modell, repräsentiert vom Typ File, ist dabei eine endliche Folge von Bytes. Damit dieses Basis-Modell universell eingesetzt werden kann, müssen Daten mit anderer Struktur auf eine sequentielle Byte-Struktur übersetzt und von dort rückübersetzt werden können.
Ein File in Oberon ist zunächst nur eine Folge von Bytes mit einer wohldefinierten Länge. Der Zugriff geschieht sequentiell über einen Reiter (Rider); dieser notiert u.a. die aktuelle Zugriffsposition.

Mehrere Rider können auf denselben File verweisen. Auf diese Weise kann mit voller Synchronisation an mehreren Position gearbeitet werden.
Sie erhalten eine Übersicht über Ihre aktuelle Implementation von Files mit
  Browser.ShowDef Files
Files enthält eine kleine Gruppe von Prozeduren, die Dateien verwalten und Rider in Beziehung zu Dateien setzen, sowie eine ganze Sammlung von Schreib- oder Lese-Prozeduren.

Die Aufgabe des Moduls Display ist es, Daten für den Benutzer darzustellen. Das Grundmodell ist dafür nicht eine Sequenz von Bytes, sondern ein zweidimensionales Raster, in dem Punkte mit unterschiedlicher Qualität markiert werden können. Damit können Texte in Schriftform dargestellt werden, aber auch Muster und Grafiken repräsentiert werden.
Sie erhalten eine Übersicht über Ihre aktuelle Implementation von Display mit
  Browser.ShowDef Display
Am Modul Display können einige typische Oberon-Techniken illustriert werden. Wir untersuchen dieses Modul am Beispiel der Macintosh-Implementierung genauer. Sie können dieser Untersuchung schrittweise folgen. Die Untersuchung ist in einzelne Abschnitte gegliedert, die mit markiert sind. Die Markierungen können Sie in der üblichen Weise aktivieren. Dadurch wird zusätzliche Information präsentiert, oder präsentierte Information wird kondensiert.
Aktivieren Sie diese Markierung: ==>
DEFINITION Display;

  IMPORT
    Objects, Files;
  CONST Definition von numerischen Konstanten für symbolische Namen. Leider erlaubt Oberon keine rein symbolischen Konstanten. Mit dem Trick, numerische Konstanten für symbolische Namen einzuführen, kann zumindest eine gleichartige Schreibweise erreicht werden.

  TYPE  Datentypen. Aufbauend auf den Basis_Datentypen können neue Datentypen definiert werden. Variablen sind durch ihre Deklaration immer an Datentypen gebunden. Dadurch ist es für den Compiler möglich, die Typenverträglichkeit zu untersuchen und Verstösse dagegen bereits während der Entwicklungsphase eines Programms zu erkennen.
Diese Prüfung der Typenverträglichkeit findet auch bei den Parametern von Prozeduren statt. Durch die Datentypen wird eine Grundlage für die Kommunikation gelegt. Da in Oberon Typen erweitert werden können ist es auch möglich, generische Prozeduren zu schreiben, die eine ganze Familie von Typen als Parameter unterstützen.
Die Sichtbarkeit von Typen und der Details von Typen_Deklarationen ist vom Programmierer kontrolliert. Der Programmierer legt fest, welche Typen oder welche Details von Typen exportiert werden. Dadurch ist es möglich, abstrakte Typen zu definieren. Ein abstrakter Typ ist ein Typ, dessen Implementierung nicht ausserhalb des definierenden Moduls bekannt ist. So ist sichergestellt, dass die Implementierung geändert werden kann, ohne dass es Störungen bei anderen Modulen gibt.
Soll auf Komponenten eines abstrakten Typs von aussen zugegriffen werden können, so müssen dafür Prozeduren bereitgestellt werden

  VARVariablen_Deklarationen. Durch die Variablen_Deklarationen wird Platz für die Variablen bereitgestellt. Jede Variable wird durch die Deklaration an einen Typ gebunden. Die Freigabe der Variablen, und damit des Platzes, wird automatisch von Oberon verwaltet. Durch die Werte der Variablen wird der aktuelle Zustand eines Moduls definiert. Der sichtbare Teil dieses Zustands wird mit
  System.State Modul
berichtet, z.B. mit
  System.State Display

  Grundlegende Prozeduren.

END Display.


Kommentierte Definition des Moduls Display

Die Module Display und Files sind im Oberon-System bereitgestellte Module, die die Ein- und Ausgabe unterstützen. Ein- und Ausgabe sind notorische Problembereiche bei allen Programmiersprachen. Eine Programmiersprache soll Möglichkeiten liefern, Verfahren abstrakt zu beschreiben. Ein- und Ausgabe müssen sich immer auf konkrete Realisierungen beziehen. Zwischen beiden Aufgaben besteht ein Spannungsfeld. Allgemein akzeptierte Lösungen dieser Spannung gibt es noch nicht. Deshalb sind Ein- und Ausgabe nicht als Bestandteile der Sprache Oberon aufgenommen. Jedoch wird jede Implementierung von Oberon diese Funktionen unterstützen. Eine Modell-Implementierung ist in "Project Oberon" (Wirth & Gutknecht, 1992) beschrieben. Dies ist die allgemeine Referenz-Implementierung, und die meisten Implementierung können im Bezug auf "Project Oberon" beschrieben werden. Files und Display sind Module, die in dieser Referenz-Implementierung beschrieben werden.

Die Modell-Implementierung zeigt eine Möglichkeit, Ein- und Ausgabe zu kontrollieren. Die Modell-Implementierung versucht, ein möglichst universelles Modell anzugeben, das jedoch effektiv implementierbar ist. Andere Möglichkeiten bestehen daneben.

Wir betrachten ein Beispiel. In Reiser&Wirth (1992) werden Modelle angegeben, die vom Konzept her besonders übersichtlich sind. Die Implementierung dieser Modelle wird mit
  Desktops.OpenDoc Kurs/PIO/In.Mod
  Desktops.OpenDoc Kurs/PIO/Out.Mod
  Desktops.OpenDoc Kurs/PIO/xyPlane.Mod
geöffnet. In einigen Oberon-Implementierungen sind diese Module bereits enthalten. Falls sie nicht vorhanden sind, können sie jetzt compiliert werden. Wie üblich erhalten wir, nachdem wir die Module compiliert haben, gezielt Information über die exportierten Schnittstellen mit
z.B.
  Browser.ShowDef In

Die Implementierung von In.Mod zeigt die Oberon-Standardtechnik, auf externe Information zuzugreifen. Wir wir bereits wissen, kann jede parameterlose Prozedur, die exportiert ist, als Kommando aufgerufen werden. Nicht-exportierte Prozeduren sind nach aussen gar nicht sichtbar. Exportierte Prozeduren mit Parametern können in anderen Module aufgerufen werden, aber nicht als Kommandos. Um Kommandos dennoch mit weiteren Parametern zu versorgen, hält das Modul Oberon Information über den Systemzustand bereit. Die Prozedur In.Open greift zunächst auf die unmittelbar nach dem Kommando folgende Eingabe zu. Wo diese Information zu finden ist, sagen Oberon.Par.text und Oberon.Par.pos. In.Open entschlüsselt auch gleich, ob diese Information ein Verweis entsprechend den Oberon-Konventionen ist. Folgt ein Pfeil oder ein Stern, so wird die Eingabe an anderer Stelle gesucht: ein Pfeil verweist auf die letzte aktuelle Textselektion. Wo diese Selection zu finden ist, sagt die Prozedur Oberon.GetSelection. Ein Stern verweist auf einen markierten VIewer. Oberon.MarkedViewer liefert den entsprechenden VIewer. Folgt keines dieser speziellen Symbole, so beginnt die Eingabe unmittelbar nach dem Kommando. Diese Entschlüsselung ist in der Prozedur In.Open versteckt. Beginnt nun irgendein Kommando seine Ausführung mit dem Aufruf der Prozedur In.Open, so wird die Eingabe entsprechend den Oberon-Konventionen vorbereitet und die weiteren Eingaben können mit den von In.Mod bereitgestellten Prozeduren gelesen werden.

Für die Text-Ausgabe haben wir bereits die Prozeduren in Texts kennengelernt. Für graphische Ausgabe sind die Primitiv-Elemente in Display bereitgestellt. Auch hier greift man in der Regel auf Prozeduren zurück, die eine Reihe von Konventionen abdecken, zum Beispiel die aus xyPlane.Mod. Die exportierten Definitionen erhält man mit
  Browser.ShowDef xyPlane
Die Konstanten draw und erase sind vordefinierte Werte für den formalen Parameter mode in der Prozedur Dot. Position und Grösse der Zeichenfläche werden in H,W,X,Y notiert. Diese Werte sind erst definiert, wenn die Prozedur Open aufgerufen ist. Open initialisiert eine Zeichenfläche, die die gesamte Benutzer-Spur überdeckt. Draw markiert oder löscht einen Punkt an der Position x,y. IsDot gibt den Status eines Punktes zurück. Key verwaltet die Tastatur. Wenn eine Taste gedrückt worden ist, so gibt Key den entsprechenden Zeichenwert zurück. Ist keine Taste gedrückt worden, so wird ein Zeichen mit dem Wert 0X zurück geliefert. Clear löscht den Zeichenbereich.

Untersuchen Sie den Text xyPlane.Mod. Welche Prozeduren können Sie mit der bislang bekannten Information vollständig entschlüsseln? Markieren Sie diese Prozeduren, und geben Sie eine vollständige Beschreibung ihrer Funktion. Für welche Funktionen können Sie mit einiger Sicherheit spekulieren, welche Funktionen diese haben? Fixieren Sie, wie Sie Ihre Vermutungen testen würden. Welche Sprachelemente und Konstruktionen sind Ihnen noch unbekannt? Markieren Sie diese.

Übersetzen Sie die Module

  Kurs/PIO/RandomNumbers.Mod  Kurs/PIO/IFS.Mod ~

Das dadurch erzeugte Programm kann durch einen Tastendruck unterbrochen werden. Sie starten es mit
  IFS.Draw

Wir sind damit am Ende eines ersten Durchgangs durch Oberon angelangt. Der zweite Durchgang untersucht in Fallstudien die Verwendung der bereitgestellten Konzepte. In einem dritten Durchgang schliesslich ist eine Gang durch die formale Definition von Oberon, die die Grundlage für weitere Arbeit ist.


Einführung in die Programmiersprache Oberon. Kurs/Kap10.Text
gs (c) G. Sawitzki, StatLab Heidelberg
<http://statlab.uni-heidelberg.de/projects/oberon/kurs/>

Home Up Intro Contents Chapter 1 2 3 4 5 6 7 8 9 10 Design Assert Timing EBNF Report Pas