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>



04 Modul-Struktur, Compiler und Lader; System-Zustand


Ein Beispiel für ein vollständiges Oberon-Programm können Sie mit
   Desktops.OpenDoc Kurs/Prog01.Mod ~
öffnen. Damit Sie dieses Programm benützen können, muss es compiliert werden. Öffnen Sie die Datei Builder.Tool mit Desktops.OpenDoc Builder.Tool ~ Markieren Sie das Fenster von Prog01.Mod und aktivieren Sie das Kommando Builder.Compile * \s aus dem Builder.Tool. Dies entspricht dem Befehl
  Builder.Compile Kurs/Prog01.Mod \s ~
** Falls die Heidelberger Werkzeuge für Sie verfügbar sind, benutzen Sie bitte jetzt und in der Folge gsBuilder anstelle Builder **
Im System.Log erscheint ein Hinweis darauf, dass die Compilierung erfolgt ist.
Mit
  Prog01.Test
wird das Programm nun gestartet. Im System.Log erscheint nun die Zeit; ein neues Fenster mit dem Namen "Modules" wird in der System-Spur geöffnet, und eine Liste der aktuell verfügbaren Module erscheint darin. Wenn Sie den Befehl.
  Prog01.Test
noch einmal geben, so erscheint ein weiteres Fenster mit dem Namen "Modules" und der Liste der aktuell verfügbaren Module.

Anmerkung: In der ersten Fassung des Oberon-Systems benutzte man
  Compiler.Compile * \s ~
Builder.Compile hat zusätzliche Funktionen, die die Verwaltung von Modul-Gruppen einfacher macht. Bei fehlerfreien Programmen haben beide Kommandos dieselbe Wirkung. Treten Fehler bei der Compilierung auf, so werden sie im System.Log aufgelistet. Wenn man die Fehlerliste selektiert, werden mit Builder.MarkErrors ^ im markierten Text die einzelnen Fehler angezeigt. Wenn Sie gsBuilder benutzen, werden die Fehlermarkierungen automatisch eingefügt.

Eine Übersicht über die Fehlercodes und ihre Erklärungen ist in der Datei OberonErrors.Text zu finden. Hinweise zum Compiler findet man in der Datei Compiler.Tool.

Anmerkung: In älteren Programmiersprachen war es notwendig, ein Programm/Modul nach dem Compilieren mit Bibliotheksprogrammen zu verbinden (link). Dieser Schritt entfällt in Oberon.

Ein Modul ist ein Text, der als Einheit compilierbar ist. Die Bezeichnung "Programm", die oben gebraucht wurde, ist bei Oberon eigentlich nicht angebracht. Mit "Programm" bezeichnet man in älteren Systemen eine getrennt compilierbare, abgeschlossen ausführbare Einheit. Im Oberon-System gibt es keine abgeschlossene Einheit: die Einheiten, in Oberon "Module" genannt, können immer kooperieren. Im Prinzip kann jedes Modul mit jedem anderen kommunizieren. Das Modul "Prog01" zum Beispiel kommuniziert mit dem Modul "System" und benutzt dessen Funktionen ShowModules und Time.
Die Kommunikation und die Zugriffsmöglichkeiten sind jedoch geregelt. Die Grundregel dabei ist, dass jede Kommunikation und Zugriffsmöglichkeit ausdrücklich freigegeben sein muss. Was nicht erlaubt ist, ist verboten. In jedem Modul können Objekte (Typen, Variablen, Funktionen) definiert werden. Jedes definierte Objekt hat einen Namen, der innerhalb des Moduls eindeutig ist. Wenn auf ein Objekt von ausserhalb zugegriffen werden soll, so muss es exportiert werden. Ein Objekt wird exportiert, indem bei der Definition hinter dem Namen ein Stern (*) nachgestellt wird. Im Beispiel Prog01.Mod wird eine Prozedur Test definiert und exportiert. Deshalb kann sie mit Prog01.Test aufgerufen werden. Folgt bei der Definition auf den Namen ein Minus (-), so kann die mit dem Objekt verbundene Information zwar von ausserhalb gelesen, aber nicht verändert werden. Sie ist damit gegen unbeabsichtigte Veränderung gesichert.

Syntax einer Namensdeklaration:

  Oberon-Name [*|-]

Exportierte Objekte können in anderen Modulen benutzt werden. Eine Veränderung an exportierten Objekten kann deshalb weitreichende Konsequenzen haben. Dies kann erwünscht sein, etwa wenn durch eine Veränderung die Funktionalität verbessert wird. Dies kann aber auch andere Module ungültig machen, etwa wenn die Aufrufstruktur geändert wird. Zum Schutz vor unbeabsichtigten Veränderungen muss deshalb beim Compilieren ausdrücklich vermerkt werden, wenn sich die Export-Bedingungen ändern dürfen. Dies geschieht durch eine nachgestellte Spezifikation \s, etwa in
  Builder.Compile * \s
oder
  Builder.Compile Kurs/Prog01.Mod \s ~

Prozedur-Syntax:
  PROCEDURE [*] [Ziel] Prozedur-Name
      [formale Parameter];
    Deklarations-Folge
  [BEGIN
    Anweisungs-Folge  ]
  END
Prozedur-Name;

Wir kommen noch auf die Details dieser Definition zurück. In unserem Beispiel ist die Definition der Prozedur Test besonders einfach: die meisten Komponenten entfallen, die Anweisungs-Folge besteht nur aus einer einzigen Anweisung, dem Aufruf von System.Modules.

Das gesamte Modul hat die Struktur
Modul-Syntax:
  MODULE modul-name;
    [Import-Liste]
    Deklarations-Folge
  [BEGIN
    Anweisungs-Folge ]
  END
modul-name.

Der Modul-Name ist eine Identifikation, unter der das Modul angesprochen werden kann. Die Import-Liste führt diejenigen Module an, auf deren Dienste unser Modul zugreifen will. Im Beispiel ist dies das Modul System.

Importliste:
  IMPORT
    [name := ] modul-name { , [name := ] modul-name } ;

Der in der Importliste möglicherweise vorangestellte Name dient dazu, Abkürzungen und Umbenennungen einzuführen. So kann etwa nach der Importliste
  IMPORT sys:=System;
das Modul System unter dem Namen sys angesprochen werden, die Zeit also zum Beispiel mit sys.Time abgefragt werden.

Die Deklarations-Folge enthält Deklarationen von Typen, Variablen und Prozeduren. Die Anweisungsfolge enthält die Anweisungen, die beim Laden des Moduls ausgeführt werden sollen. In unserem Beispiel ist dies nur die Anweisung System.Time.
Ein Modul wird in Oberon geladen. sobald das erste Mal auf eines seiner Elemente zugegriffen wird. Ein Modul bleibt geladen, bis Oberon neu gestartet wird, oder es explizit mit dem Befehl
  System.Free modul-name
entladen wird. Deshalb wird die Anweisungsfolge in unserem Beispiel nur bei der ersten Aktivierung von Prog01.Test ausgeführt, das heisst die Zeit wird nur einmal im System-Log gemeldet. Wird während des Aktivierens eines Kommandos "Positionieren" gedrückt, so wird auf jeden Fall das entsprechende Modul neu geladen. Dies ist eine hilfreiche Abkürzung, wenn sich ein Modul noch in der Programm-Entwicklung befindet.

Die Anweisungsfolgen in unserem Beispiel sind einfach. Sie bestehen nur aus einer Anweisung. Die allgemeine Syntax ist
Anweisungsfolge:
  Anweisung
{; Anweisung}

Modul und Prozedur haben einen sehr änhlichen Aufbau. Ein Modul ist gewissermassen die "Verpackungseinheit" in Oberon, eine Prozedur ist die ausführbare Einheit. Mehrere Prozeduren können ein einem Modul gebündelt werden. Neben exportierten Prozeduren kann ein Modul auch Prozeduren enthalten, die nur für den internen Gebrauch innerhalb dieses Moduls bestimmt sind. Module sind immer von aussen sichtbar, Prozeduren nur dann, wenn sie ausdrücklich exportiert sind.
Der Anweisungsteil eines Moduls wird nur einmal ausgeführt, wenn das Modul geladen wird. Die Information des Moduls bleibt erhalten, solange das Modul geladen ist. Der Anweisungsteil einer Prozedur wird jedes mal ausgeführt, wenn die Prozedur aufgerufen wird. Interne Information einer Prozedur geht verloren, sobald die Prozedur abgearbeitet ist.



Übungen:

Geben Sie das Modul Prog01 frei, indem Sie den Befehl
  System.Free Prog01 ~
aktivieren.
Legen Sie eine Kopie von Prog01.Mod mit Hilfe des Befehls
  System.CopyFiles Kurs/Prog01.Mod => Kurs/Test01.Mod
an. Öffnen Sie die Kopie mit
  Desktops.OpenDoc Kurs/Test01.Mod ~
Machen Sie aus der Anweisung in der Prozedur Test eine echte Anweisungsfolge, indem Sie
  System.ShowModules
ersetzen durch
  System.ShowModules;
  System.Time
Sichern Sie die veränderte Datei mit Desktops.StoreDoc (Menubalken!). Compilieren Sie die Datei mit
  Builder.Compile Kurs/Test01.Mod \s ~
und aktivieren Sie nun wiederholt
  Test01.Test




Ein geladenes Modul in Oberon erweitert das System. Es ist in gleicher Weise verfügbar wie alle Systemfunktionen. Dadurch kann das Oberon-System dynamisch verändert werden.

Neben der Sprachbeschreibung, die den Grundumfang der Sprache definiert, brauchen wir deshalb auch Werkzeuge, um den dynamischen Umfang zu bestimmen. Das Modul System bietet Funktionen, um den aktuellen Systemzustand abzufragen. Mit
  System.ShowModules
erhält man eine Liste der aktuell geladenen Module. Mit
  System.ShowCommands modul-name
erhält man eine Liste aller Kommandos, das heisst aller parameterlosen Prozeduren im angegebenen Modul. Insbesondere auch für das Modul System selbst:
  System.ShowCommands System
Die aktuellen Werte der Variablen eines geladenen Moduls erhält man mit
  System.State modul-name
zum Beispiel
  System.State System

Für den Programmierer bietet das Modul Browser ein weiteres Werkzeug. Mit
  Browser.ShowDef modul-name
erhält man eine vollständige Rekonstruktion aller exportierten Objekte eines Moduls, zum Beispiel
  Browser.ShowDef System
Während die System-Kommandos den dynamischen Zustand des gerade geladenen Moduls zeigen, gibt der Browser die statische Definition wieder, zeigt aber in der Regel mehr Details als die Systeminformation.

Unter Oberon System 3 steht als übergeordnetes Werkzeug Watson zur Verfügung.
  Watson.ShowDef modul-name
liefert eine vollständige Information eines Moduls als Hypertext, zum Beispiel
  Watson.ShowDef System
Im Gegensatz zu System und Browser, die auf die ausführbaren Module selbst zugreifen, versucht Watson verschiedene Informationspfade in einer vom Benutzer festlegbaren Reihenfolge. Wenn diese Information verlässlich ist, kann Watson die ausführlichste Information liefern.



Übungen:
Beschaffen Sie sich mit den Kommandos
  System.ShowCommands System
  System.State System
  Browser.ShowDef System
  Watson.ShowDef System

Information über das Modul System und vergleichen Sie die Information.

Beschaffen Sie sich mit den Kommandos
  System.ShowCommands Math
  System.State Math
  Browser.ShowDef Math
  Watson.ShowDef Math

Information über das Modul Math und vergleichen Sie die Information.



Die einzelnen Kommandos des Moduls System sind in
  N. Wirth, J. Gutknecht: Project Oberon. Addison-Wesley 1992
beschrieben.

Einführung in die Programmiersprache Oberon. Kurs/Kap04.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