\chapter{Entwicklungsumgebung {\tlmin}}
\label{cha_envtlmin}

Ausgehend von einem idealen Modell eines "Ubersetzers werden in diesem
Kapitel der Aufbau und die Architektur des {\tlmin} ({\itshape Tycoon
  Language minimal}) Systems und die Werkzeuge zur Softwareentwicklung
bzw.\ die vom {\tlmin} System f"ur deren Realisierung bereitgestellten
Basisdienste vorgestellt.  Dabei wird auf die besonderen Implikationen
dieses Systems bei der Realisierung der in Kapitel
\ref{cha_strukturierung_tlmin} vorgestellten
Strukturierungsmechanismen eingegangen.

Voraussetzung f"ur die Realisierung der Modulverwaltung ist die in das
{\tlmin} System integrierte reflektive Compilerschnittstelle, die es
erm"oglicht, wiederverwendbare Softwarekomponenten zu entwickeln, die
auf der Anwendungsebene der Tycoon Architektur angesiedelt sind und
auf das darunterliegende Tycoon System zugreifen.  Die
Compilerschnittstelle kann als ein Hilfsmittel zur Realisierung von
Komponenten einer Entwicklungsumgebung bzw. von Werkzeugen, die direkt
auf das System zugreifen m"ussen, wie z.B.\ die Modulverwaltung,
dienen.  Diese Werkzeuge k"onnen zur Laufzeit des {\tlmin} Systems
angebunden werden, da sie nicht in den Compiler selbst integriert
sind.

\section{Begriffsverwendung}

Die folgenden Begriffe bilden die Diskussionsgrundlage f"ur dieses Kapitel.

\begin{description}
\item[Tycoon Architektur:] Hierunter werden die f"ur Tycoon Systeme
  charakteristische Schichtenbildung und die Verteilung verschiedener
  Komponenten auf diese Schichten verstanden (s. Abbildung
  \ref{abb_tycoon_arch}).  Die genaue Anordnung der einzelnen
  Komponenten auch im Hinblick auf die Einordnung in verschiedene
  Schichten kann zwischen unterschiedlichen Tycoon Systemen variieren.
  Die Tycoon Architektur legt weiterhin fest, welche Operationen und
  Repr"asentationen an den Schnittstellen zwischen den Schichten
  Verwendung finden.

\item[Tycoon System (Familie):] Ein Tycoon System bezeichnet eine
  konkret existierende Implementierung der Tycoon Architektur.  Diese
  konkret existierenden Implementierungen unterscheiden sich im
  wesentlichen durch die im Compiler Front\-end (Sprachebene)
  realisierte Programmiersprache, k"onnen aber auch in anderen
  Aspekten wie der Objektspeicherimplementierung differieren.

  Die Gesamtheit aller Implementierungen der Tycoon Architektur wird
  Tycoon System Familie genannt.  Die Tycoon System Familie ist weiter
  in (Unter)familien aufgeteilt, die in bezug auf die Tycoon
  Architektur Gemeinsamkeiten aufweisen.

  Der Begriff Tycoon System (im Singular) wird in dieser Arbeit dann
  gebraucht, wenn ein beliebiger Vertreter aus der Familie der Tycoon
  Systeme gemeint ist.  Abweichend zu \cite{tycoon_po} ist mit Tycoon
  System also nicht ein bestimmtes System gemeint, welches {\tl}
  ({\itshape Tycoon Language}) als Programmiersprache besitzt.  Es
  wird versucht, eine klare Trennung zwischen Programmiersprache
  einerseits und implementierendem System andererseits vorzunehmen.

\item[{\tl} System:] Dieser Begriff benennt ein Mitglied aus der
  Familie der Tycoon Systeme, genauer ein Mitglied der Unterfamilie
  der Systeme, die die Programmiersprache {\tl} implementieren.

  Alle Auspr"agungen der Unterfamilie der {\tl} Systeme besitzen die
  gleiche Sprachebene, k"onnen aber in anderen Schichten variieren.
  Dies verdeutlicht auch Abbildung \ref{abb_tycoon_systeme}.

\item[{\tlmin} System:] Weitere Mitglieder in der Familie der Tycoon
  Systeme sind die {\tlmin} Systeme.  Analog zur Unterfamilie der
  {\tl} Systeme existiert eine Unterfamilie von {\tlmin} Systemen.
  Jedes einzelne Element dieser Unterfamilie wird seinerseits {\tlmin}
  System genannt.  Alle {\tlmin} Systeme haben ebenfalls die
  Eigenschaft, sich untereinander in der Sprachebene zu gleichen.

  Ein {\tlmin} System realisiert die Programmiersprache {\tlmin}.  In
  {\tlmin} Systemen werden "ahnliche Konzepte wie in {\tl} Systemen
  verwendet.  Aus diesem Grund ist es m"oglich, da"s die unter der
  Sprachebene liegenden Schichten eines {\tl} und eines {\tlmin}
  Systems gleich sind.  Dies gilt z.B.\ f"ur die Implementation der
  Objektspeicherschicht.  Zus"atzlich zur Sprachebene umfa"st ein
  {\tlmin} System auch eine andere Auspr"agung der Schicht der
  Arbeitsumgebung ({\tlmin} Arbeitsumgebung).

\item[{\tl}:] Unter diesem Begriff versteht man die durch ein {\tl}
  System angebotene Programmiersprache, die definiert ist durch eine
  Beschreibung der Syntax und der statischen und dynamischen Semantik
  in \cite{tycoon_po}.  Synonym werden die Begriffe {\tl} Sprache oder
  Sprache {\tl} angewendet.

\item[{\tlmin}:] Analog der Definition f"ur {\tl} versteht man
  hierunter die durch ein {\tlmin} System angebotene
  Programmiersprache, deren abstrakte und konkrete Syntax sowie die
  statische Semantik in Form der Typregeln in \cite{schroeder} bzw.\ 
  \cite{bremer} angegeben sind.  Die dynamische Semantik entspricht der
  Semantik der Sprache {\tl}.  Im Unterschied zu {\tl} beschr"ankt
  sich {\tlmin} auf einen schmaleren Sprachkern.

  Synonym zu {\tlmin} werden die Begriffe {\tlmin} Sprache oder Sprache
  {\tlmin} angewandt.
\end{description}

%\afterpage{\clearpage
\begin{figure}[H]
\centering\mbox{\epsfig{file=../Zeichnung/tycoon_arch.eps}}
\caption{"Uberblick "uber die Tycoon Architektur.}
\label{abb_tycoon_arch}
\end{figure}
%}

Der Begriff Tycoon System steht also f"ur eine Menge von Systemen, die wiederum
zu unterschiedlichen Gruppen (Unterfamilien) zusammengefa"st werden k"onnen.
In Abbildung \ref{abb_tycoon_systeme} sind die Tycoon Systeme nach der
implementierten Programmiersprache, der verwendeten
Objektspeicherimplementierung und der ausf"uhrenden Tycoon Maschine
partitioniert.  Hervorgehoben ist die Menge der {\tlmin} Systeme, die eine
m"ogliche Zusammenfassung einer Untermenge der Tycoon Systeme bildet.

Tycoon Systeme k"onnen nicht nur anhand ihrer unterschiedlichen
Schichtenimplementierungen partitioniert werden.  Auch 
andere Aufteilungen lassen sich finden, wie z.B.\ die F"ahigkeit,
nativen Maschinencode zu erzeugen.  Im Rahmen dieser Arbeit wird diese
Unterteilung herangezogen, um zwischen den Familien der {\tl} und
der {\tlmin} Systeme zu differenzieren und um zu betonen, da"s die anderen
Unterschiede f"ur diese Arbeit nicht relevant sind.

%\afterpage{\clearpage
\begin{figure}[H]
\centering\mbox{\epsfig{file=../Zeichnung/tycoon_systeme.eps}}
\caption{M"ogliche Partitionierung der Tycoon Systeme.}
\label{abb_tycoon_systeme}
\end{figure}
%}

\section{{\tlmin} System}
In diesem Abschnitt wird das in \cite{aho} beschriebene Phasenmodell eines
Compilers pr"asentiert (vgl.\ \cite{schroeder}).  Anhand dieses Modells werden
Bez"uge zum Compiler des
{\tlmin} Systems hergestellt.  Der "Ubersetzungsvorgang ist danach in Phasen
unterteilt, die nacheinander ablaufen und auf den Repr"asentationen der
entsprechend vorgelagerten Phase aufbauen.  Abbildung \ref{abb_compilerphasen}
verdeutlicht dies.  Phasen und Repr"asentationen des Modells finden eine 
Entsprechung in der in Abschnitt \ref{sec_compilerschnittstelle} behandelten
Compilerschnittstelle bzw.\ in deren Funktionen und Datentypen.

%\afterpage{\clearpage
\begin{figure}[H]
\centering\mbox{\epsfig{file=../Zeichnung/compilerphasen.eps}}
\caption{Idealisierte Darstellung der Compilerphasen und der
Zwischenrepr"asentationen.}
\label{abb_compilerphasen}
\end{figure}
%}

\subsection{Lexikalische Analyse}
In der ersten Phase wird das als Zeichenstrom vorliegende Quellprogramm in
eine Folge von Symbolen umgeformt (\textit{scanning}).  Zeichen bzw.\ 
Zeichenfolgen, die keine Bedeutung tragen, wie z.B.\ Tabulatorzeichen,
Kommentare usw.\ werden bei der lexikalischen Analyse entfernt.

Die Vorschrift, nach der Zeichenfolgen zu Symbolen gruppiert werden, liegt
"ublicherweise in Form von regul"aren Ausdr"ucken vor.  Mit Hilfe von
Generatoren ({\itshape scanner generator}) ist die automatische Erstellung von
Programmen zur lexikalischen Analyse nach vorgegebenen regul"aren Ausdr"ucken
m"oglich.

Im {\tlmin} System wird ein ausprogrammierter Scanner verwendet, der mit einer  
festen Menge von Symbolen und deren Repr"asentation arbeitet.  Die Menge der 
Schl"usselw"orter ist nicht festgelegt und kann sowohl erweitert als auch
eingeschr"ankt werden \cite{schroeder}.

\subsection{Syntaxanalyse}
Die Syntaxanalyse (\textit{parsing}) pr"uft, ob die von der lexikalischen
Analyse gelieferte Folge von Symbolen der durch eine Grammatik beschriebenen
Programmiersprache gen"ugt, d.h.\ ob mit der Grammatik die vorgegebene Folge
von Symbolen erzeugt werden kann.  Die Syntax einer Programmiersprache liegt
oftmals als kontextfreie Grammatik vor, wobei nur eine bestimmte Menge der
kontextfreien Grammatiken von existierenden Syntaxanalyseprogrammen effizient
erkannt werden kann.  Dabei handelt es sich um Grammatiken in LL- und LR-Form.
Im {\tlmin} System wird eine LL(1)-Grammatik verwendet (LL-Form mit einem
Zeichen Look-ahead) \cite{schroeder}.

Auch f"ur die Syntaxanalyse existieren Generatoren, die Programme zur
Erkennung einer bestimmten Sprache automatisch erstellen ({\itshape
  parser generator}).

Im {\tlmin} System wird mit einer fest eingebauten Kerngrammatik
gearbeitet, die jedoch "uber entsprechende Mechanismen erweitert
werden kann.  Ein inkrementeller Parsergenerator wird mit dieser
Grammatik parametrisiert und erzeugt einen Parser, der die der Grammatik
entsprechenden Ausdr"ucke akzeptiert. 

\subsection{Semantische Analyse}
Die semantische Analyse verarbeitet die aus der Syntaxanalyse gewonnene
Datenstruktur ({\itshape parse tree}) und reichert sie mit zus"atzlicher
Information an.  Die folgenden vier Teilaufgaben sind Bestandteil der
semantischen Analyse \cite{aho}:

\begin{description}
\item[Typ"uberpr"ufung:] Der Compiler pr"uft die Typen der verwendeten
Operatoren, Variablen und Funktionen und sichert nach erfolgreicher Pr"ufung
die Kompatibilit"at bei Zuweisungen, Vergleichen und Parameter"ubergabe zu.

\item["Uberpr"ufung des Kontrollflusses:] F"ur Operationen, die den
Kontrollflu"s des Programms ver\-"andern, mu"s sichergestellt werden, da"s das
Ziel der Kontrollflu"s"anderungen existiert.

\item["Uberpr"ufung auf Eindeutigkeit:] Hier wird die Eindeutigkeit der
verwendeten Bezeichner, die Disjunktheit von Fallunterscheidungsmarken und
Aufz"ahlungstypelementen sichergestellt.

\item[Auf Namen bezogene "Uberpr"ufungen:] In einigen
Programmiersprachenkonstrukten mu"s der gleiche Name mehrmals auftreten, z.B.\
Blocknamen in Ada.  Diese Pr"ufung sichert die korrekte Verwendung dieser
Namen zu.

\end{description}

Die wichtigste der aufgef"uhrten "Uberpr"ufungen ist die Typ"uberpr"ufung.  Bei
den anderen Aufgaben handelt es sich "uberwiegend um routinem"a"sige
Abpr"ufungen \cite{aho}.

In {\tlmin} wird eine weitreichende semantische Analyse durchgef"uhrt, die
insbesondere die folgenden Zusicherungen f"ur ein Programm gibt
\cite{tycoon_po}:

\begin{itemize}
\item keine inkompatible Funktionsparameteranzahl oder inkompatiblen
  Funktionsparametertypen

\item keine inkompatiblen Funktionsergebnistypen

\item keine inkompatiblen Wertbindungen lokaler oder globaler
Objektspeichervariablen

\item kein Zugriff auf undefinierte oder uninitialisierte Variablen

\item keine Zuweisungen an unver"anderliche Objekte

\item kein Zugriff auf nichtexistierende Tupel-, Rekord- oder
Ausnahmekomponenten

\item vollst"andige Fallmarken bei der vollst"andigen Fallunterscheidung

\item keine \textit{exit} Anweisung ohne passende \textit{loop}

\item keine \textit{reraise} Anweisung ohne korrespondierendes \textit{try}

\end{itemize}

\subsection{Zwischencode-Generierung}
\label{subsec_zwischencode}
Um den Compiler m"oglichst unabh"angig von der erzeugten Zielsprache zu halten,
erzeugt das Frontend (s.\ Abbildung \ref{abb_compilerphasen}) zun"achst einen
Zwischencode.  Dieser wird anschlie"send vom Backend in Maschinensprache
transformiert.  Die Verwendung eines Zwischencodes hat im wesentlichen zwei
Vorteile \cite{aho}:

\begin{itemize}

\item Durch Austausch des Backends kann der Compiler f"ur eine andere
  Zielsprache verwendet werden.  Im Tycoon System liegt ein weiterer Vorteil in
  der Austauschbarkeit des Frontends.  In Abbildung \ref{abb_tycoon_systeme}
  auf Seite \pageref{abb_tycoon_systeme} sind drei verschiedene
  Programmiersprachen (Frontends) dargestellt, die jeweils auf eine von zwei
  verf"ugbaren Tycoon Maschinen (Backends) aufsetzen k"onnen.  Die Darstellung
  macht die freie Kombinierbarkeit verschiedener Frontends mit verschiedenen
  Backends deutlich.  Z.B.\ l"a"st sich das {\tl} Frontend mit dem
  \textit{tm1}-Backend betreiben, ebenso kann es mit dem \textit{tm2}-Backend
  zusammenarbeiten.

\item Auf dem Zwischencode kann ein von der Ziel- und Quellsprache
  unabh"angiger Optimierer arbeiten.
\end{itemize}

Die Einf"uhrung eines zus"atzlichen Verarbeitungsschrittes und einer weiteren
Repr"asentation in die Compilerphasen hat neben architektonischen
Gesichtspunkten haupts"achlich softwaretechnische Gr"unde.  Die Komponenten des
Front- bzw.\ Backends k"onnen jeweils mehrfach verwendet werden.

In {\tlmin} wird als Zwischencode Tycoon Maschinen Code eingesetzt,
der in der Tycoon Machine Language (TML) formuliert ist.  Es handelt
sich hierbei um eine abstrakte persistente
Zwischencoderepr"asentation, die, wie im folgenden Abschnitt
erl"autert wird, sowohl f"ur lokale als auch f"ur globale
Optimierungen eingesetzt werden kann.  TML ist eng verwandt mit der
Darstellung des Lambdakalk"uls im Fortsetzungsstil ({\itshape
  continuation passing style (CPS)}).  TML kann als
wertaufrufbasiertes Lambdakalk"ul mit Speichersemantik bezeichnet
werden \cite{tml}.  Der Hauptvorteil von TML gegen"uber anderen
Zwischencoderepr"asentationen, wie z.B.\ dem Drei-Adre"s-Code, liegt
in der geringen Anzahl von Konstrukten, die zur Formulierung verwendet
werden.  Abbildung \ref{abb_tml} zeigt die gesamte TML-Syntax und
unterstreicht damit die Einfachheit und Kompaktheit dieser
Darstellung.

%\afterpage{\clearpage
\begin{figure}[H]
\hrule
\vskip \baselineskip
\vbox{
\begin{tabular}{ll}
$lit \in Lit$ &Literale, Konstanten und Objektidentifikatoren \\
$t \in Temp $ &Tempor"are Variablen \\
$c \in Cont $ &Fortsetzungsvariablen \\
$v \in Var  $ &Variablen (Bezeichner) \\
$prim \in Prim $ &Primitive Operationen
\end{tabular}
$
\begin{array}{llll}
v   &::= &t \mid\ c         &$ Variablen$ \\
val &::= &lit \mid\ v \mid\ abs &$ Werte$ \\
abs &::= &\lambda (v_{1}\ldots v_{n})app &$ Abstraktion$, n \geq 0 \\
app &::= &(val_{0} val_{1}\ldots val_{n})
               \mid\ (prim\ val_{1}\ldots val_{n}) &$ Applikationen$, n \geq 0 \\
\end{array}$
}
\hrule
\caption{Abstrakte Syntax der Zwischensprache TML (aus \protect \cite{tml}).}
\label{abb_tml}
\end{figure}
%}

Wie die Sprache {\tlmin} unterst"utzt auch TML Funktionen h"oherer
Ordnung und eignet sich daher besonders als Zwischenrepr"asentation in
einem "Ubersetzer.

\subsection{Code-Optimierung}
"Ubersetzer, die den Code in bezug auf sein Laufzeitverhalten oder seinen
Speicherplatzbedarf verbessern, werden optimierend genannt.  Die
Code-Optimierung ist dabei lediglich eine Transformation des urspr"unglichen
Codes in eine "aquivalente Darstellung.

Bei der Code-Optimierung lassen sich zwei grunds"atzliche Arten
unterscheiden.  Das sind zum einen Optimierungen, die direkten Bezug
auf die unterliegende Hardwareplattform nehmen und z.B.\ besondere vom
Prozessor schnell ausgef"uhrte Befehlsfolgen gegen"uber anderen
bevorzugen oder die Vergabe von Registern unter plattformspezifischen
Gesichtspunkten vornehmen.  In die zweite Kategorie fallen
Optimierungen, die auf dem in Abschnitt \ref{subsec_zwischencode}
eingef"uhrten Zwischencode arbeiten.  Derartige Optimierungen k"onnen
vom Optimierer des {\tlmin} Systems durchgef"uhrt werden.

In \cite{kiradjiev} wird ein Optimierer f"ur TML vorgestellt.  Das
Grundprinzip besteht in der Anwendung der Reduktionsregeln des
Lambdakalk"uls.  Diese Regeln formalisieren die Mechanismen der
Bindung von Bezeichnern, der Substitution von gebundenen Werten und
der Applikation von Lambda-Termen \cite{pakendorf}.

\subsection{Code-Erzeugung}
Der letzte Schritt des "Ubersetzungsvorganges beinhaltet die Code-Erzeugung.
Er transformiert den Zwischencode in eine "aquivalente Darstellung der
Zielsprache.  Die Zielsprache ist bei den meisten Compilern
plattformabh"angig.  Im Tycoon System besteht die Besonderheit, da"s auch der
Code der Zielsprache unabh"angig von der zugrundeliegenden Plattform ist.
Vielmehr "ubersetzt die Code-Erzeugung die TML-Repr"asentation in die
Darstellung als Bytecode, der von der virtuellen Maschine der Tycoon
Architektur (Tycoon Virtual Machine) ausgef"uhrt werden kann.

\section{Compilerschnittstelle}
\label{sec_compilerschnittstelle}
Die Compilerschnittstelle des {\tlmin} Systems bietet Funktionen, Typen und
Daten des (laufenden) "Ubersetzers bzw.\ darunterliegender Schichten an.  Sie
erm"oglichen das "Ubersetzen von {\tlmin} Ausdr"ucken und den Zugriff auf
interne Strukturen.  Der Entwickler hat "uber die Compilerschnittstelle die
M"oglichkeit, direkt gegen den Compiler zu programmieren.  Au"serdem wird durch
die Bereitstellung schon vom Compiler benutzter Module\footnote{Hierunter fallen
  Module zur Behandlung von Massendatenstrukturen (list, hashtable usw.),
  Bildschirmausgaben (print) und Dateibehandlung (reader).} verhindert, da"s der
Programmierer diese Module in einer anderen Version benutzt und damit die
Korrektheit der Schnittstelle verletzt.  Module m"ussen weiterhin nicht erneut
in den Objektspeicher geladen werden.

Die hier vorgestellte Compilerschnittstelle dient nicht der direkten Benutzung
durch den Anwendungsprogrammierer.  Vielmehr bietet sie die Dienste des
"Ubersetzers Programmen an, die im Anwendungsbereich angesiedelt sind und als
Programmierwerkzeuge fungieren.  Es lassen sich zahlreiche Werkzeuge vorstellen,
die Gebrauch von einer Compilerschnittstelle machen k"onnen:

\begin{itemize}
\item Ein Debugger kann mit Hilfe der vom "Ubersetzer angebotenen
  Operationen und Daten Programme schrittweise oder bis zu einem
  bestimmten Punkt ausf"uhren und aktuelle Variablenwerte ausgeben.

\item Browser gehen "uber die Funktionalit"at eines Debuggers in bezug
  auf die verf"ugbaren Informationen hinaus, indem sie auch die vom
  Compiler generierten Zwischenrepr"asentationen, wie z.B. den
  abstrakten Syntaxbaum, anzeigen k"onnen.

\item Ein Profiler auf Sprachebene kann "ahnlich einem Debugger die
  Ausf"uhrung eines Programms nach beliebigen Schritten anhalten und
  z.B.\ Informationen "uber die verbrauchte Prozessorzeit sammeln.
  Auch der "Ubersetzungsvorgang selbst kann auf diese Weise analysiert
  werden und z.B. die f"ur jede "Ubersetzungsphase ben"otigte Zeit
  betrachtet werden.

\item Mit Hilfe einer Modulverwaltung, wie sie in Abschnitt
  \ref{sec_modulverwaltung} eingef"uhrt wird, lassen sich die
  programmiertechnischen Einheiten wie z.B.\ Module, Schnittstellen, Klassen
  usw.\ organisieren.  Die Modulverwaltung sorgt insbesondere daf"ur, da"s die
  erw"ahnten Einheiten getrennt voneinander und in bezug auf deren
  Abh"angigkeiten in der korrekten Reihenfolge "ubersetzt werden und
  anschlie"send zur Ausf"uhrung gebracht werden k"onnen.  Letzteres impliziert
  die Aufl"osung externer Referenzen.

\item Eine grafisch orientierte Programmierwerkbank, wie sie in
  \cite{basisdienste} vorgestellt wird, kann o.g.\ Werkzeuge
  integrieren und dem Programmierer eine komfortable Bedienoberfl"a\-che
  bieten.
\end{itemize}

In dieser Arbeit wird mit der Realisierung der Compilerschnittstelle ein
strikter add-on-Ansatz in der Anbindung von Programmierwerkzeugen verfolgt.
Keines der in obiger Aufz"ah\-lung erw"ahnten Werkzeuge wird, wenn es konform
zur Compilerschnittstelle programmiert ist, in das {\tlmin} System integriert.
Analog zur Diskussion in \cite{addon} ergeben sich daraus mehrere Vorteile:

\begin{itemize}
\item Auf die ver"anderten Anforderungen an Werkzeuge kann ohne "Anderung des
  {\tlmin} Systems und damit schnell reagiert werden.

\item Die Wartbarkeit solcher Werkzeuge wird aufgrund der losen Kopplung
  erh"oht.

\item Das {\tlmin} System beh"alt seine schlanke Struktur und erh"alt sich
  dadurch seine Wartbarkeit.

\item Es besteht keine Beschr"ankung in der Zahl, G"ute und Verf"ugbarkeit von
  Werkzeugen.  Neue Werkzeuge k"onnen jederzeit ohne "Anderung des {\tlmin}
  System hinzugef"ugt werden.
\end{itemize}

\subsection{Anforderungen}
Die Aufgabe einer Schnittstelle ist es, Typen, Operationen und Daten
bereitzustellen, die es dem Benutzer der Schnittstelle erlauben, die
angebotene Funktionalit"at einfach und effizient zu verwenden.  Dabei soll die
Schnittstelle von implementierungsabh"angigen Dingen abstrahieren.  Dies ist
um so schwieriger, je breiter das Spektrum der Benutzeranforderungen ist, da
"offentliche Strukturen, die von einer Benutzergruppe verwendet werden, f"ur
eine andere uninteressant sind.

Mit der Compilerschnittstelle wird das Ziel verfolgt, dem Programmierer eine
weitreichendere Kontrolle "uber das System zu geben.  Insbesondere hat er durch
die "uber die Schnittstelle angebotenen Umgebungen die M"oglichkeit, den
"Ubersetzungsvorgang zu parametrisieren.  Ausdr"ucke lassen sich durch die
Verwendung mehrerer Umgebungen in unterschiedlichen Kontexten "ubersetzen.
Auch die Verwendung verschiedener Compilereinstellungen, wie z.B.\ Optimierer
ein-/ausgeschaltet, beeinflu"st die "Ubersetzung.

Dem Programmierer soll "uber die Compilerschnittstelle weiterhin die
M"oglichkeit gegeben werden, die einzelnen "Ubersetzerphasen klar voneinander
zu trennen und die Ausf"uhrung nach jedem Schritt anhalten zu k"onnen.  Die
nach jedem Schritt erzeugten Zwischenrepr"asentationen k"onnen persistent
abgelegt werden und z.B.\ durch Werkzeuge analysiert werden.

Aus diesem Szenario ergeben sich zusammenfassend folgende Anforderungen:

\begin{itemize}
\item unterschiedlich abstrakte, aber dennoch kompatible Schnittstellen

\item Bereitstellen von Zwischenrepr"asentationen

\item parametrisierbarer "Ubersetzungsvorgang

\item Offenlegung der "Ubersetzerphasen

\end{itemize}

\noindent
Um der Anforderung nach unterschiedlichen Abstraktionsgraden gerecht zu werden,
wurden zwei Module entworfen.  Beide Varianten unterst"utzen alle "ubrigen
Anforderungen. 

\subsection{Vereinfachte Compilerschnittstelle}
Die vereinfachte Schnittstelle arbeitet ausschlie"slich mit abstrakten
Datentypen f"ur die Zwischenrepr"asentationen und die Hilfsstrukturen.  Es kann
deshalb nur "uber entsprechende Funktionen darauf zugegriffen werden.  Die
"Ubersetzung und Ausf"uhrung eines Ausdruckes l"a"st sich folgenderma"sen
beschreiben:

\begin{quote}
\begin{alltt}
execute(context
  generateCode(context
    translate(context
      typecheck(context
        parse(context sourceFromString("let a = 42"))))))
\end{alltt}
\end{quote}

\noindent
Da der Compiler weitere Parameter als die Zwischenrepr"asentationen ben"otigt,
erh"alt man nicht die idealisierte Darstellung wie in \cite{bremer} oder
\cite{basisdienste}.  Um die Verwendung der Schnittstelle jedoch m"oglichst
einfach zu halten, sind alle "ubrigen Parameter in einem weiteren Datentyp nach
dem Vorbild des Grafikkontextes ({\itshape graphic context}) der \textit{Xlib}
Bibliothek zusammengefa"st \cite{xlib1,xlib2}.

Der Kontext umfa"st die Gr"o"sen, mit denen der "Ubersetzer parametrisierbar
ist:

\begin{itemize}
\item Schalter, die den "Ubersetzungsvorgang steuern, wie z.B.\ ein
  Boole'scher Wert, der angibt, ob beim Typ"uberpr"ufen ein Cache f"ur
  bereits gepr"ufte Ausdr"ucke angelegt werden soll.

\item Quelltext

\item Abstraktion des Fehlerkanals, der Meldungen des Compilers aufnimmt.

\item Grammatik

\item Parser

\item Initiale Umgebung

\item Umgebung, die die Zwischenrepr"asentationen der bereits
  "ubersetzten Ausdr"ucke enth"alt
\end{itemize}

\noindent
In Anhang \ref{cha_compiler} ist die gesamte Schnittstelle aufgef"uhrt.

\subsection{Detaillierte Compilerschnittstelle}
Eine zweite Schnittstelle, die parallel zur oben beschriebenen aktiv sein
kann, bietet eine detaillierte Sicht auf den Compiler.  Der erweiterte
Funktionsumfang gestattet einen weitreichenderen Zugriff auf den Compiler
und dessen Datenstrukturen.  Anhang \ref{cha_tlcompiler} gibt die
Schnittstelle wieder.

"Ahnlich der einfachen Compilerschnittstelle m"ussen vor Benutzung der
Schnittstelle einige elementare Datenstrukturen, wie z.B.\ der Fehlerkanal,
die Grammatik oder der Parser initialisiert bzw.\ erzeugt werden.  Die
folgenden Operationen erledigen dies:

\begin{quote}
\begin{alltt}
\textbf{let} switches = tlCompiler.newSwitches()
\textbf{let} log = tlCompiler.newLog()
\textbf{let var} gram = tlCompiler.newGrammar()
\textbf{let var} parser = tlCompiler.newParser(gram)
\textbf{let} initEnv = tlCompiler.newInitialEnvironment()
\textbf{let} env = environment.new()
\end{alltt}
\end{quote}

Einige Komponenten werden als
ver"anderliche Bindung angelegt.  Bei der Grammatik \textit{gram} ist dies
erforderlich, da diese zur Laufzeit erweitert werden kann.  Der Parser
\textit{parser} ist zum Zeitpunkt dieser Anweisung noch nicht mit der konkreten
Grammatik parametrisiert worden.  Dies geschieht in einem weiteren, hier nicht
gezeigten, Schritt.  Die Umgebung \textit{env} enth"alt die Repr"asentationen
bereits "ubersetzter Bezeichner (vgl. Abschnitt \ref{sec_umgebung}).

Ein typischer "Ubersetzungsvorgang\footnote{F"ur diese Anweisungen wird
  angenommen, da"s der Parser mit einer Grammatik parametrisiert wurde, die die
  Ausdr"ucke der Sprache {\tlmin} erkennt.}, bei dem alle
Zwischenrepr"asentationen persistent gespeichert werden, kann wie folgt
ausgef"uhrt werden.  An dieser Stelle wird ein Vorgriff auf die Abschnitt
\ref{sec_umgebung} vorgestellten Umgebungen gemacht.  Es werden die Funktionen
beschrieben, die zur Benutzung der Compilerschnittstelle notwendig sind.  Die
auf den Aspekt der Strukturierung fokussierten Eigenschaften werden in Abschnitt
\ref{sec_umgebung} behandelt.

\begin{quote}
\begin{alltt}
\textbf{let} s = tlCompiler.sourceFromString("let a=42;")
\textbf{let} b = tlCompiler.parse(parser gram s log)
\textbf{let} t = tlCompiler.typeCheck(switches initEnv 
                             env b log)
\textbf{let} env1 = environment.insertSyntaxTree(env t)
\textbf{let} c = tlCompiler.translate(switches initEnv 
                             env1 t log)
\textbf{let} env2 = environment.insertTMLCode(env1 c)
\textbf{let} g = tlCompiler.generateCode(switches env2 c log)
\textbf{let} r = tlCompiler.execute(switches env2 g log)
\textbf{let} env3 = environment.insertRuntimeValue(env2 r)
tlCompiler.printResult(switches r log)
tlCompiler.printLogClear(log)
\end{alltt}
\end{quote}

Die Funktionen der detaillierten Compilerschnittstelle sind so angelegt, da"s
sie nur mit den tats"achlich ben"otigten Parametern versorgt werden m"ussen.  In
obigen Beispiel wird zun"achst f"ur den als String vorliegenden Ausdruck ein vom
Compiler zu verarbeitender Zeichenstrom \textit{s} erzeugt.  Dieser wird
anschlie"send anhand der Grammatik vom Parser in den Symbolstrom \textit{b}
umgewandelt.  Die semantische Analyse (\textit{tlCompiler.typeCheck}) liefert
den attribuierten Syntaxbaum \textit{t}, der als Parameter f"ur die
Zwischencode-Generierung dient.  Die Umgebung \textit{env} wird um den
attribuierten Syntaxbaum mit der Funktion \textit{environment.insertSyntaxTree}
erweitert und als Umgebung \textit{env2} zur"uckgegeben.  Sie steht damit
weiteren Ausdr"ucken bei der semantischen Analyse zur Verf"ugung.  Die neue
Umgebung \textit{env2}, die im Gegensatz zu \textit{env1} zus"atzlich
Typinformation f"ur den Bezeichner \textit{a} enth"alt, wird zusammen mit dem
attribuierten Syntaxbaum von der nachfolgenden Funktion verwendet.  Auch die
urspr"unglich verwendete Umgebung \textit{env} steht weiterhin zur Verf"ugung,
da keine der beteiligten Funktionen Seiteneffekte auf Umgebungen ausf"uhren.

Die Zwischencode-Generierung (\textit{tlCompiler.translate}) f"ugt
Zugriffsinformation zu den in der Umgebung \textit{env2} abgelegten Objekten des
attribuierten Syntaxbaums f"ur den zu "ubersetzenden Ausdruck hinzu und gibt den
erzeugten TML-Code \textit{c} zur"uck.  Dieser dient der Erweiterung der
Umgebung \textit{env1} zur Umgebung \textit{env2} mit der Funktion
\textit{environment.insertTMLCode)}.  Auch hier steht die urspr"ungliche
Umgebung \textit{env} weiterhin zur Verf"ugung.

Die letzten beiden Schritte bestehen in der Generierung des TVM Codes \textit{g}
mittels der Funktion \textit{tlCompiler.generateCode} und in der Ausf"uhrung
dieses TVM Codes durch die virtuelle Maschine mit der Funktion
\textit{tlCompiler.execute}.  Der evaluierte Wert \textit{r} wird ebenfalls zur
Erweiterung der Umgebung \textit{env2} zur Umgebung \textit{env3} benutzt.

Tritt in einer der Phasen ein "Ubersetzungsfehler auf, so wird ein Ausnahmepaket
ausgel"ost.  Die Meldungen des Compilers werden nicht direkt auf der Konsole
ausgegeben, sondern in einen Fehlerkanal geschrieben.  Dies erleichtert die
Programmierung von Entwicklungsumgebungen, die die Fehlerinformation z.B.\ in
einem Fenster ausgeben.

Einige Hilfsfunktionen unterst"utzen den Programmierer in der Untersuchung der
erzeugten Zwischenwerte.  So kann z.B.\ mit \textit{tlCompiler.printEnvironment}
eine Liste aller aktuell in der Umgebung befindlichen Bezeichner ausgegeben
werden.  Weiterhin k"onnen die Regeln der Grammatik, der Syntaxbaum, der TML
Code und in Zusammenhang mit den Schnittstellen zu den Umgebungen die Signaturen
einzelner Bindungen angezeigt werden.

%Einfuehrung der Funktion compileFile/compileString fuer spaetere Kapitel 
%(environments)

\section{Modulverwaltung}
\label{sec_modulverwaltung}
In den verschiedenen konkreten Auspr"agungen des Tycoon Systems lassen sich
unterschiedliche Ans"atze zur Verwaltung von Softwareeinheiten wie z.B.\ 
Module, Klassen oder Bibliotheken identifizieren.  In den in dieser Arbeit
vorgestellten Systemen der {\tlmin} Familie wird keine Festlegung auf eine
bestimmte Verwaltungskomponente getroffen.  Vielmehr ist es dem Programmierer
"uberlassen, eine seinen W"unschen entsprechende Implementierung auszuw"ahlen. 
Dieser generische Ansatz wird weiter unterst"utzt durch die in Kapitel
\ref{cha_strukturierung_tlmin} vorgestellte flexible Methode, neue
Strukturierungsmechanismen aus vorhandenen Basisdiensten aufzubauen.

Im Gegensatz zur allgemeinen Tycoon Architektur, wie sie in Abbildung
\ref{abb_tycoon_arch} auf Seite \pageref{abb_tycoon_arch} dargestellt ist,
unterscheidet sich die konkrete Architektur des {\tlmin} Systems in den
obersten Schichten.  In Abbildung \ref{abb_modul_arch} sind die betreffenden
"Anderungen eingearbeitet.

Die Modulverwaltung befindet sich auf der Anwendungsebene und interagiert mit
dem Compiler "uber die bereitgestellten Komponenten Compilerschnittstelle,
Umgebungen und erweiterbare Grammatik.  Durch die Realisierung der
Modulverwaltung, stellvertretend f"ur andere Werkzeuge, als Anwendungsprogramm
wird erreicht, da"s sowohl die Entwicklung und Implementierung als auch die Wahl
und der Einsatz eines Werkzeuges ohne "Anderung des Compilers vorgenommen werden
kann.

%\afterpage{\clearpage
\begin{figure}[H]
\centering\mbox{\epsfig{file=../Zeichnung/modul_arch.eps}}
\caption{"Uberblick "uber die spezielle Architektur der {\tlmin} Systeme.}
\label{abb_modul_arch}
\end{figure}
%}

Die Aufgaben der Modulverwaltung bestehen darin, die Abh"angigkeiten von
Softwareeinheiten zu ermitteln und deren Systemgenerierung vorzunehmen.  Mit
Softwareeinheiten k"onnen hier z.B.\ Module und Schnittstellen gemeint sein.
Durch die Kombination der in Kapitel \ref{cha_strukturierung_tlmin}
vorgestellten Basisprimitive zur Systemstrukturierung k"onnen auch andere
Konstrukte aufgebaut und von der Modulverwaltung verwaltet werden.  Dazu mu"s
lediglich sichergestellt werden, da"s die Modulverwaltung "uber die folgenden
Punkte Kenntnis hat:

\begin{itemize}
\item Die Art und Weise, mit der die abh"angigen Komponenten ermittelt werden.

\item Die Methode, mit der die Bindung der Softwareeinheiten vorgenommen wird.

\item Die Reihenfolge, in der die Bindung der Softwareeinheiten erfolgt.
\end{itemize}

\noindent
Aus dem letzten Punkt der Aufz"ahlung ergibt sich bereits eine weitere Aufgabe.
Die Modulverwaltung mu"s nicht nur den "Ubersetzungsvorgang der
Softwareeinheiten aufgrund der Abh"an\-gigkeiten steuern, sondern auch die
Reihenfolge der Bindung bestimmen.  Diese Reihenfolge richtet sich meist
ebenfalls nach den Abh"angigkeiten der Softwareeinheiten.

Im Kern st"utzt sich die Modulverwaltung auf die Verwaltung von
Abh"angigkeiten.  In der zu dieser Arbeit angefertigten Implementierung wird
dazu das in \cite{studienarbeit} entwickelte generische Werkzeug zur
Modellierung von Abh"angigkeitsgraphen verwendet.  Es werden die in Abschnitt
\ref{subsec_schnittstellen} und \ref{subsec_module} vorgestellten Module und
Schnittstellen unterst"utzt.  Die Bindung der Komponenten wird auf Namensbasis
durchgef"uhrt.  Damit werden nicht alle in Abschnitt \ref{subsec_binden}
genannten M"oglichkeiten ausgesch"opft.  Die Implementierung selbst ist so
flexibel gehalten, da"s sie leicht an andere Verh"altnisse, z.B.\ andere
Strukturierungskonstrukte, angepa"st werden kann.

