Die Programmiersprache Oberon
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, daß 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, daß 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.
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, daß 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.
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.
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.
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üßte 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.
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.
Zeilen werden in Oberon mit dem Semikolon abgeschlossen.
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.
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.
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
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.
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
Zur Wiederholung einer Anweisungsfolge in Abhängigkeit von einer Bedingung sind die folgenden vier Wiederholungsanweisungen vorgesehen:
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.
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, daß die Repeat-Schleife mindestens einmal
durchlaufen wird, bevor die Bedingung zum ersten Mal geprüft wird. Sie wird
daher Durchlaufschleife genannt.
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 muß oder wenn mehrere Bedingungen verteilt vorkommen.
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.
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.
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 <Name>;
VAR <Name>: <Typ>;
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.
Const a = 8;
Wie bei der Deklaration von Variablen können
mehrere Konstanten durch Zeilenendezeichen getrennt hintereinander geschrieben
werden, ohne daß das Schlüsselwort "Const" wiederholt werden muß.
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.
Procedure <Name>;
Begin
(Anweisungsfolge);
end;
Liefert die Prozedur ein Ergebnis zurück, muß es einen Typ besitzen. Er wird vor dem Zeilenendezeichen hinter einem Doppelpunkt angegeben. Das Ergebnis muß 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.
IMPORT <Name>;
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.
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.
Ein Record ist eine Sammlung von Elementen verschiedenen Typs. Siehe auch 2.2
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.
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.
Oberon ist modular aufgebaut. Die kleinste ausführbare Einheit ist von daher nicht mehr ein Programm, sondern ein Modul
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, daß Objekte als exportierbar markiert werden. Es findet kein aktiver Export statt. Siehe auch 3.5
Eine eher unangenehme Besonderheit ist, daß 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
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.
Der Programmierer kann eigene, zusätzliche Typen deklarieren. Auch sie können exportiert werden.
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/
Haupt | Fügen Sie Referat | Kontakt | Impressum | Nutzungsbedingungen