Die Programmiersprache Oberon

2. Einführung


2.1 Oberon - Das Betriebssystem

Zu Beginn der achtziger Jahre dieses Jahrhunderts warf die Computerindustrie Mikrocomputer auf den Markt. Die Zielgruppe waren Einzelpersonen, die unabhängig von den damals vorherrschenden Großrechnern arbeiten sollten oder wollten und die sich so ihre Zeit am Computer selbst einteilen konnten. Nur alzuschnell wurde offenbar, dass diese Benutzer deutlich sowohl eine breite Quer - als auch eine lange Abwärtskompatibilität verlangten, um ohne Probleme Dateien und Programme mit anderen Benutzer austauschen und alte Programme weiterbenutzen zu können. So kam es zu Betriebssystemen, die weite Verbreitung fanden und die zur Abwärtskompatibilität neue Funktionen über die alten stülpten. Als Beispiel sei hier MS - DOS 6.22, von 1993, genannt, das, wie PC - DOS 1.0 von 1981, ohne erweiternde Programme nur 1Mb Arbeitsspeicher verwalten kann, wovon es Programmen 640Kb zur Verfügung stellt.
Im Laufe weniger Jahre wuchsen sowohl die Leistungsfähigkeit der Mikrocomputer als auch der Leistungsverbrauch der Betriebssysteme, die vermehrte Leistung wurde zunehmend von den stetig mehr verbrauchenden Betriebssystemen kompensiert.
So begab es sich 1985, dass Niklaus Wirth und Jürg Gutknecht im Palo Alto Research Center (PARC), dem bekannten Forschungszentrum der Xerox Corp., ein Forschungsprojekt mit einem ehrgeizigen Ziel begannen: Die komplette Neuentwicklung eines Betriebssystems für Arbeitsplatzrechner, das so einfach wie möglich sein sollte[1]. Nebenbei sollte es auch noch überzeugend beschrieben und erklärt werden können und wenig Leistung verbrauchen.
Das Forschungsprojekt wurde als äußerst interessant angesehen, da noch nie Betriebssysteme unter diesem Gesichtspunkt entwickelt worden waren und keinerlei Anleitungen zur Planung und Programmierung von Betriebssystemen existierten.
Ein weiterer Auslöser für dieses Forschungsprojekt waren tiefe persönliche Abscheu der Forschenden gegen gängige Arbeitsweisen bei der Erstellung von Betriebssystemen. Es wurden Aufgeblähtheit, Undurchschaubarkeit und fehlende Wiederverwendbarkeit von Funktionen kritisiert, alles sichere Anzeichen von Gigantomanie.
Bei Oberon wollte man also alles ganz, ganz anders machen. Der Erfolg und die Merkmale von Oberon:
    Der kompillierte Quellcode von Oberon nur 200Kb groß und somit kürzer als der von PC - DOS 2.0. Der Kernel von Oberon ist kompakter als der von Betriebssystemen mit vergleichbarem oder sogar geringerem Funktionsumfang. Oberon ist streng modular aufgebaut. Die Module lassen sich ohne Probleme erweitern, austauschen und administrieren.

Oberon wurde an der Eidgenössischen technischen Hochschule (ETH) in Zürich entwickelt und sollte ursprünglich nur auf dort selbst hergestellten Computern eingesetzt werden. Inzwischen existieren aber Portierungen für nahezu jede Computerhardware.

2.2 Oberon - Die Programmiersprache

Das Betriebssystem Oberon sollte eigentlich in Modula - 2 programmiert werden. Doch diese Programmiersprache war den Forschenden aus folgenden Gründen nicht gut genug:
    Modula - 2 hatte einen großen Sprachumfang. Modula - 2 erlaubte keine Erweiterung von Record - Typen.

Zum ersten Grund: Modula - 2 besitzt zahllose Funktionen, die viele Programmierer von seinen Vorgängern PASCAL und ALGOL 60 kennen und lieben. Man war sich sicher, solche Konstrukte weglassen zu können, ohne die Ausdruckskraft einzuschränken. Dies führte dazu, dass die Sprachbeschreibung von Oberon mit 16 Seiten um etwa zwei Drittel kleiner ist als die von Modula - 2 (45 Seiten). Dennoch beeilte man sich, direkt in der zweiten Version von Oberon einige dieser Konstrukte wieder einzuführen. Dies führt zu ernsten Problemen bei der Abwärtskompatibilität.
Zum zweiten Grund: Viele Programmierer wollten in Modula - 2 die Erweiterbarkeit von Record - Typen gerne benutzen, obwohl sie nicht vorgesehen war. Also nutzten sie die maschinennahen Sprachkonzepte von Modula - 2 aus, um Record - Typen dennoch erweitern zu können. Dieser Mißbrauch war den Entwicklern von Oberon ein Dorn im Auge, und um dies zu unterbinden, wurde Oberon die entsprechende Funktionalität eingebaut.

2.2.1 Was ist ein Record - Typ?

Der Datentyp Record ist eine Sammlung mehrerer Variablen verschiedenen Typs. So können in einem Record beispielsweise Vor - und Zuname eines Angestellten als Text und seine Personalnummer, seine Steuerklasse und seine Sozialversicherungsnummer als Zahl gespeichert werden.

2.2.2 Wie kann ein Record - Typ erweitert werden?

Von diesem Record - Typ wird ein neuer Record - Typ abgeleitet, der neben den zusätzlichen Variablen genau dieselben Variablen wie der zugrunde liegende Record - Typ besitzt.

2.2.3 Welchen Vorteil hat die Erweiterbarkeit von Record - Typen?

Es können beim Programmlauf beliebig weitere Informationen im Record gespeichert werden. Wird dasselbe Record mehrfach verwendet, kann es an Einzelbedürfnisse speziell angepaßt werden. Zum Beispiel müsste für einen einzigen von mehreren hundert Angestellten zusätzliche Informationen gespeichert werden. Ist das Record erweiterbar, kann es für ihn angepaßt werden. Ist es nicht erweiterbar, so müssen in den Records aller anderen Angestellten Variablen für diese zusätzlichen Informationen geführt werden, obwohl sie nicht benutzt werden. Dies stellt eine hochgradige Verschwendung von Speicherplatz dar, was der Zielsetzung der Entwickler von Oberon zuwider läuft.

2.3 Wieso eigentlich "Oberon"?

In der Anfangsphase des Forschungsprojekts waren alle Medien voll mit Meldungen von und über der Mission der von der National Aeronautics Space Agency (NASA) gestarteten Raumsonde Voyager2. Voyager2 beeindruckte die Menschen weltweit durch seine bisher ungekannte Zuverlässigkeit, Eleganz und Effizienz, auch Niklaus Wirth. So wurde also auf sein Bestreben das Forschungsprojekt nach einem bis damals unbekannten und somit unbenannten Mond des Planeten Uranus benannt, welchen Voyager2 in einem relativ nahen Vorbeiflug gleichzeitig entdeckt, fotografiert und analysiert hatte. Diese Wahl scheint nicht ganz so unglücklich zu sein: Voyager2 hat unser Sonnensystem vor etwa sieben Jahren verlassen.



Abb. 01: Ein Foto von Oberon

3. Wichtige Sprachkonzepte


3.1 Abschluß einer Zeile

Zeilen werden in Oberon mit dem Semikolon abgeschlossen.

3.2 Zuweisung

a := b * c
Wie von anderen Programmiersprachen bekannt, enthält die Zuweisung ein Zuweisungszeichen, hier ist es ":=". Rechts von dem Zeichen steht ein Ausdruck, der ausgewertet wird. Das Ergebnis dieser Auswertung wird der Variablen auf der linken Seite des Zeichen zugewiesen.

3.3 Bedingte Anweisungen

Die bedingte Ausführung von Anweisungen wurde in Oberon mit folgenden Konstrukten ermöglicht. Bedingte Anweisungen müssen mit boolschen Ausdrücken gefüllt sein.

3.3.1 Boolsche Ausdrücke

Die Bestandteile von boolschen Ausdrücken sind die Konstanten True (wahr) und False (Falsch), Variablen und Konstanten vom Typ Boolean, relationale Ausdrücke und die folgenden Operatoren:
    OR logisches Oder & logisches Und ~ logische Verneinung
Siehe auch 4.2

3.3.2 Die If - Anweisung

If (a < b) then c := a
else if (b> a) then c := b
else c := 0
end;
Sprachlich ausgedrückt würde die If - Anweisung wie folgt lauten:
Wenn (Kaffee da ist) dann trinke ich Kaffee
sonst wenn (Tee da ist) dann trinke ich Tee
sonst trinke ich Wasser.

3.3.3 Die Case - Anweisung

CASE a OF
0: a := 3
| 1: a := 9
| 2: a := 2
| 3: a := 4
| 4: a := 8
end;
Die If - Anweisung kann beliebig verlängert werden, indem immer weitere mit "else if" beginnende Zeilen eingefügt werden. Dies wird schnell sehr umfangreich und unübersichtlich. Vereinfachend kann die Case - Anweisung verwendet werden.
Sprachlich ausgedrückt entspricht der Case - Anweisung:
Im Falle das ich dies finde:
Kaffe: Ich trinke Kaffee
Tee: Ich trinke Tee
Cola: Ich trinke Cola

3.4 Wiederholungsanweisungen

Zur Wiederholung einer Anweisungsfolge in Abhängigkeit von einer Bedingung sind die folgenden vier Wiederholungsanweisungen vorgesehen:

3.4.1 While

While j < n Do
...(Anweisungsfolge);
j := j + 1
end;
Die While - Schleife wird solange durchlaufen, wie j kleiner als n ist.
Da j bis n - 1 zählt, nennt man diese Schleife eine Zählschleife. Die While - Schleife kann aber auch genutzt werden, wenn nicht von vornherein klar ist, wie oft die Schleife ausgeführt werden soll.
Die While - Schleife ist eine kopfgesteuerte Schleife, weil die Bedingung sich in der ersten Zeile der Schleife befindet.

3.4.2 Repeat

Repeat
...(Anweisungsfolge);
j := j + 1
until j = n;
Die Repeat - Schleife wird solange durchlaufen, bis j gleich n ist.
Die Bedingung wird erst in der letzten Zeile der Repeat - Schleife geprüft. Sie heißt daher fußgesteuerte Schleife.
Die Fußsteuerung führt dazu, dass die Repeat - Schleife mindestens einmal durchlaufen wird, bevor die Bedingung zum ersten Mal geprüft wird. Sie wird daher Durchlaufschleife genannt.

3.4.3 Loop

Loop
...(Anweisungsfolge);
if a = b then EXIT end;
...(Anweisungsfolge);
if a> b then EXIT end;
...(Anweisungsfolge);
end;
Die Loop - Schleife wird solange durchlaufen, bis eine der Bedingungen erfüllt ist. Da diese mitten in der Schleife stehen, wird die Loop - Schleife als rumpfgesteuerte Schleife bezeichnet. Es empfiehlt sich wegen der besseren Übersichtlichkeit, die Loop - Schleife nur zu benutzen, wenn die Bedingung mitten in der Schleife stehen muss oder wenn mehrere Bedingungen verteilt vorkommen.

3.4.4 For

For i := 1 to 5 do
...(Anweisungsfolge);
end;
Die For - Schleife ist eine Zählschleife, die eine feste Anzahl von Wiederholungen einer Anweisungsfolge beschreibt. Die For - Schleife wurde in Oberon - 2 wiedereingeführt, Programme, die sie enthalten, sind nicht abwärtskompatibel.

3.5 Deklarationen

Bei Oberon wird unterschieden, ob Prozeduren, Variablen und Konstanten von anderen Modulen importiert werden können. Dies wird bei der jeweiligen Deklaration festgelegt, indem hinter dem Namen ein Sternchen ("*") angegeben wird.

3.5.1 Deklaration von Programmen (Modulen)

Wie bereits erwähnt, ist Oberon streng modular aufgebaut. Ein Programm, die kleinste ausführbare Einheit, gibt es daher nicht mehr, an seine Stelle ist das Modul getreten. Die Deklaration und gleichzeitig die erste Zeile eines jeden Moduls lautet:
Module ;

3.5.2 Deklaration von Variablen

VAR : ;
Mehrere Variablen desselben Typs können gleichzeitig deklariert werden, indem ihre Namen durch Kommata getrennt hintereinander geschrieben werden. Nach Abschluß mit dem Zeilenendezeichen kann die nächste Deklaration von Variablen eines anderen Typs angeschlossen werden, ohne das Schlüsselwort "VAR" zu wiederholen.

3.5.3 Deklaration von Konstanten

Const a = 8;
Wie bei der Deklaration von Variablen können mehrere Konstanten durch Zeilenendezeichen getrennt hintereinander geschrieben werden, ohne dass das Schlüsselwort "Const" wiederholt werden muss.
Der Wert einer Konstanten kann nur geändert werden, indem ein Programmierer den Wert im Quellcode verändert und dann das Programm neu kompiliert. Dies ist sehr nützlich, wenn im Programm ein gleichbleibender Wert mehrfach verwendet wird. Er kann bei Bedarf einfachst angepaßt werden.

3.5.4 Deklaration von Prozeduren

Procedure ;
Begin
...(Anweisungsfolge);
end;
Liefert die Prozedur ein Ergebnis zurück, muss es einen Typ besitzen. Er wird vor dem Zeilenendezeichen hinter einem Doppelpunkt angegeben. Das Ergebnis muss mit der Anweisung "Return" festgelegt werden. Diese Anweisung steht als letzte in der Prozedur.
Der Prozedur können Parameter übergeben werden, beispielsweise zur Verrechnung oder zur Bildschirmdarstellung. Die Prozedur nennt sich dann Funktionsprozedur. Die Parameter müssen als Liste mit der Prozedur deklariert werden. Dies geschieht wie eine Variablendeklaration (ohne das Schlüsselwort "VAR") in runden Klammern zwischen dem Namen und dem Typ bzw. dem Zeilenendezeichen.
Unter den mit Oberon gelieferten vordeklarierten Funktionen finden sich zahlreiche Funktionsprozeduren.

3.6 Import von Modulen

IMPORT ;
Diese Zeile steht bei Bedarf als zweite hinter der Deklaration des Programms (Moduls). Es können mehrere Module angegeben werden, ihre Namen werden durch Kommata getrennt. Alle in diesen Modulen zum Export vorgesehenen Variablen, Konstanten und Prozeduren können dann verwendet werden.

3.7 Mengen von Elementen

3.7.1 Array (Tabelle)

Eine Tabelle nennt sich in Oberon, wie bei seinen Vorgängern, Array. Es handelt sich um eine Menge von Elementen desselben Typs. Arrays können verschachtelt werden und so mehrdimensionale Arrays bilden.

3.7.2 Record

Ein Record ist eine Sammlung von Elementen verschiedenen Typs. Siehe auch 2.2

3.8 Zeiger

Es ist bei einer Variablen nicht möglich, ihren Platz im Speicher zu kontrollieren. Dies wird durch den Zeigertyp beseitigt. Wenn man einen Zeiger in einem Record mit Variablen deklariert, ist es möglich, lange Ketten von Variablen, z.B. Listen oder Bäume, zu erzeugen und effektiv zu verwalten.

4. Besonderheiten


4.1 Besonderheiten des Betriebssystems

Neben den in der Einführung erwähnten Leistungsfähigkeit und dem streng modularen Aufbau zeichnet sich Oberon durch die Abschaffung der Textmodi aus. Das bedeutet, das ein Text editierbar, speicherbar druckbar sowie Kommando sein kann.
Oberon - 2 bietet einige Erweiterungen an. Neben der bereits erwähnten For - Schleife ist folgende Eigenschaft besonders hervorzuheben:
Variablen können schreibgeschützt exportiert werden. Dies wird markiert, indem bei der Deklaration anstelle des Sternchens ("*") ein Minuszeichen (" - ") eingegeben wird.

4.2 Besonderheiten der Programmiersprache

Oberon ist modular aufgebaut. Die kleinste ausführbare Einheit ist von daher nicht mehr ein Programm, sondern ein Modul

4.2.1 Import oder Export?

Wie bereits erwähnt, ist es in Oberon äußerst einfach, Prozeduren, Variablen und Konstanten von anderen Modulen zu importieren bzw. von anderen Modulen importieren zu lassen. Es mag für Einsteiger verwirrend sein, wenn wechselnd von Import und Export die Rede ist. Tatsächlich findet nur der Import aktiv statt. Die einzige Aktion, die zum Export vorgenommen wird, ist, dass Objekte als exportierbar markiert werden. Es findet kein aktiver Export statt. Siehe auch 3.5

4.2.2 Auswertung boolscher Ausdrücke

Eine eher unangenehme Besonderheit ist, dass die Auswertung boolscher Ausdrücke abgebrochen wird, wenn das Ergebnis schon nach Auswertung des ersten Arguments bzw. weiterer Argumente feststeht. Diese Vorgehensweise unterscheidet sich von der mathematischen Definition, die boolsche Ausdrücke immer vollständig auswertet. Es ist also unbedingt nötig, auf die Reihenfolge der Argumente zu achten. Siehe auch 3.3.1

4.2.3 Vordeklarierte Funktionen, Typkonversion

Oberon stellt dreiundzwanzig vordeklarierte Funktionen zur Verfügung, auf die der Programmierer zurückgreifen kann. Besonders hervorzuheben sind die Typkonversionsprozeduren, welche eine Variable in einen anderen Typ überführen.

4.2.4 Typdeklaration

Der Programmierer kann eigene, zusätzliche Typen deklarieren. Auch sie können exportiert werden.

5. Quellen

Martin Reiser & Niklaus Wirth "Programmieren in Oberon", Addison Wesley Verlag, erster Nachdruck 1995
ETH Zürich / Oberon Homepage: http://www.oberon.ethz.ch
http://photojournal.jpl.nasa.gov/

[1] Albert Einstein: "Mach es so einfach wie möglich, aber nicht einfacher." diente als Leitsatz

2184 Worte in "deutsch"  als "hilfreich"  bewertet