\chapter{Systemstrukturierung in {\tlmin}}
\label{cha_strukturierung_tlmin}

Die Untersuchung von Programmiersprachen und deren Mittel zur
Systemstrukturierung in Kapitel \ref{cha_strukturierung} bildet den
Ausgangspunkt f"ur die Diskussion der Systemstrukturierungsmechanismen
der Sprache {\tlmin} in diesem Kapitel.  Die Aspekte der verschiedenen
Ma"snahmen zur Systemstrukturierung sind bereits in Kapitel
\ref{cha_strukturierung} ausf"uhrlich beschrieben.  In {\tlmin} wird
der Ansatz verfolgt, dem Programmierer nicht ein festgelegtes Konzept zur
Systemstrukturierung, wie z.B. Module oder Klassen, anzubieten.  Stattdessen
werden in {\tlmin} aufbauend auf einem geringen Satz an Basisprimitiven
h"ohere, semantisch reichhaltigere Konzepte zur Systemstrukturierung
realisiert.  Dies gibt dem Programmierer eine gr"o"sere Flexibilit"at und
Freiheit in der Wahl der Strukturierungsmittel.  Die ad"aquate sprachliche
Anbindung kann "uber eine geeignete Syntaxerweiterung erfolgen und mit
Werkzeugen unterst"utzt werden.

In diesem Kapitel werden zun"achst die grundlegenden Mechanismen vorgestellt,  
die direkt in die Sprache {\tlmin} eingebaut sind.  Sie bilden die Grundlage
f"ur h"ohere Strukturierungskonzepte, die in Abschnitt
\ref{sec_hoehere_strukturierungskonzepte} beschrieben werden.
Eine Modulverwaltung, wie sie in Abschnitt \ref{sec_modulverwaltung}
vorgestellt ist, kann die daraus gebildeten Einheiten verwalten.

Abschnitt \ref{sec_umgebung} stellt Umgebungen sowohl als weiteres
Strukturierungsmittel als auch als Hilfsstruktur des Compilers vor.
Der anschlie"sende Abschnitt f"uhrt die vorgestellten Konzepte in
einem Anwendungsszenario zusammen.

\section{Manipulation von Sichtbarkeitsbereichen}
\label{sec_sichtbarkeitsbereiche}
Die wichtige Rolle, die Sichtbarkeitsbereiche und deren Manipulation bei der
Programmierung im Gro"sen spielen, wurde bereits in Kapitel
\ref{cha_strukturierung} dargelegt.  An dieser Stelle sollen zun"achst
grundlegende Anforderungen an Operationen zur Manipulation von
Sichtbarkeitsbereichen aufgestellt werden.  Anschlie"send wird am Beispiel von
{\tlmin} eine Umsetzung vorgestellt.  Das verfolgte Ziel besteht darin, 
grundlegende Operationen zu identifizieren und zu implementieren, die die
Manipulation von Sichtbarkeitsbereichen erlauben.  Diese sollen so gew"ahlt 
werden, da"s sich aus ihnen h"ohere Strukturierungskonzepte aufbauen lassen,
mit denen "ahnliche wie die in Kapitel \ref{cha_strukturierung} beschriebenen 
Konzepte realisiert werden k"onnen.  Im Gegensatz dazu erlaubt die Verwendung
von primitiven, orthogonal kombinierbaren Konstrukten jedoch, die 
Strukturierungsmechanismen individuell anzupassen und neue, bislang unbekannte
Mechanismen nachtr"aglich (add on) einzuf"uhren.

In diesem Abschnitt wird Bezug auf die bereits in Abschnitt \ref{sec_notation}
eingef"uhrte Notation genommen.  Sie dient auch in diesem Kapitel der
Verdeutlichung von Sichtbarkeitskonstruktionen.

\subsection{Anforderungen}
\label{subsec_anforderungen}
Aus der Untersuchung von Sichtbarkeitsbereichsoperationen anderer
Programmiersprachen in Kapitel \ref{cha_strukturierung} lassen sich
f"unf grundlegende Operationen, aus denen sich Sichtbarkeitszenarios aufbauen
lassen, ableiten:

\begin{enumerate}
\item Anlegen eines Sichtbarkeitsbereichs.  In der grafischen Notation
entspricht dies einem neuen Kasten ohne obere Sichtbarkeitsgrenze.  Diese
Operation ist nur in Zusammenhang mit der unter Punkt 3 aufgef"uhrten Operation
sinnvoll.  Sie markiert den Anfang eines Bereichs, in dem neu hinzukommende
Bezeichner durch eine Sichtbarkeitsgrenze unsichtbar gemacht werden.

\item Anlegen eines Sichtbarkeitsbereichs bei gleichzeitiger Verdeckung aller
bislang sichtbaren Bezeichner.  Auch hierbei handelt es sich um eine
Sichtbarkeitsgrenze, die bezogen auf die grafische Notation und im Unterschied
zur vorstehend beschriebenen Operation eine Sichtbarkeitsgrenze an der oberen
Kante eines Sichtbarkeitsbereichs aufweist.

\item Hinzuf"ugen eines Bezeichners in einen Sichtbarkeitsbereich.

\item Beenden eines Sichtbarkeitsbereichs.  Damit verbunden ist das
Unsichtbarmachen aller in diesem Bereich hinzugef"ugten Bezeichner.  Das
Beenden eines Sichtbarkeitsbereichs entspricht der unteren Sichtbarkeitsgrenze  
(s. Abbildung \ref{abb_grnotation}).

\item Selektives Einf"uhren von Bezeichnern aus einem anderen Bereich, nicht
notwendigerweise den direkt umschlie"senden, in den aktuellen
Sichtbarkeitsbereich.
\end{enumerate}

Eine genaue Betrachtung der Operation 5 zeigt, da"s diese nur in
Zusammenhang mit dem Vorhandensein einer Sichtbarkeitsgrenze sinnvoll
ist, da im anderen Fall bereits alle Bezeichner sichtbar sind.
Weiterhin ist ersichtlich, da"s Bezeichner nicht an einer
Sichtbarkeitsgrenze am Ende eines Sichtbarkeitsbereichs eingef"uhrt
werden k"onnen.  Die einzige sinnvolle Verwendung des selektiven
Einf"ugens besteht darin, Bezeichner durch eine Sichtbarkeitsgrenze
hindurch einzuf"uhren.  Da es sich bei {\tlmin} und bei allen anderen
in Kapitel \ref{cha_strukturierung} betrachteten Programmiersprachen
um blockstrukturierte Sprachen handelt, treten Operation 1 und 2 immer
mit einer korrespondierenden Operation 4 auf.

Im folgenden werden die in {\tlmin} bereitstehenden Sprachkonstrukte zur
Manipulation von Sichtbarkeitsbereichen untersucht.  Dabei wird deutlich, da"s
jede Operation einem Sprachkonstrukt oder einer Kombination aus ihnen
entspricht.

\subsection{\textit{begin \ldots\ end} Block}
\label{subsec_block}
Ein einfacher Fall ist der \textit{begin \ldots\ end} Block.  Der am Anfang
des Blocks g"ultige Sichtbarkeitsbereich entspricht dem des
"ubergeordneten. Innerhalb des Blocks kann der Sichtbarkeitsbereich beliebig
erweitert werden.  Am Ende des Blocks wird der urspr"ungliche
Sichtbarkeitsbereich wiederhergestellt.  Bereits im Bereich enthaltene
Bezeichner bzw.\ deren Bindungen werden durch neue Bindungen innerhalb des
\textit{begin \ldots\ end} Blocks, die unter gleichem Namen angelegt werden,
"uberdeckt.  Abbildung \ref{abb_grbegin} verdeutlicht dieses Verhalten.

%\afterpage{\clearpage
\begin{figure}[H]
\centering\mbox{\epsfig{file=../Zeichnung/grbegin.eps}}
\caption{Sichtbarkeitsbereich eines \textit{begin \ldots\ end} Blocks.}
\label{abb_grbegin}
\end{figure}
%}

\textit{Begin \ldots end} Bl"ocke treten in {\tlmin} in verschiedenen Kontexten
und in einigen Varianten auf.  Explizit ist die Verwendung eines
\textit{begin \ldots end} Blocks bei Verwendung der Schl"usselw"orter
\textit{begin} und \textit{end} wie im nachstehenden Beispiel:

\begin{quote}
\begin{alltt}
\textbf{let} a = \textbf{begin}
  \textbf{let} b = 42
  \textbf{let} c = 43
\textbf{end}
\end{alltt}
\end{quote}

\noindent
Die Bezeichner \textit{b} und \textit{c} sind nur innerhalb der \textit{begin
\ldots end} Klammer sichtbar.

Sichtbarkeitsbl"ocke, wie in Abbildung \ref{abb_grbegin} schematisch gezeigt,
k"onnen jedoch auch ohne die Verwendung der Schl"usselw"orter \textit{begin}
und \textit{end} auftauchen, wie zum Beispiel bei Verwendung des folgenden
Konstruktes:

\begin{quote}
\begin{alltt}
\textbf{if} a == 47 \textbf{then}
  \textbf{let} b = 42
  \textbf{let} c = 43
\textbf{else}
  \textbf{let} b = 43
  \textbf{let} c = 42
\textbf{end}
\end{alltt}
\end{quote}

\noindent
In diesem Fall werden analog dem \textit{begin \ldots end} Fall zwei
entsprechende Sichtbarkeitsbereiche, deren Grenzen durch \textit{then \ldots
  else} bzw.\ \textit{else \ldots end} markiert sind, aufgebaut.  "Ahnlich
werden Sichtbarkeitsbereiche in der Sprache {\tlmin} in Fallunterscheidungen
({\itshape case of}), Funktionsdefinitionen (Parametersignaturen),
Tupeldefinitionen usw.\ gebildet.

In {\tlmin} existiert keine Operation, die es erlaubt, Bezeichner durch eine   
Sichtbarkeitsgrenze \glqq nach unten\grqq\ zu exportieren.  Dieses Verhalten
kann jedoch mit den vorhandenen Mitteln simuliert werden.

\begin{quote}
\begin{alltt}
\textbf{let} t = \textbf{begin}
  \textsl{(* Berechnung der exportierten Bezeichner a, b und c *)}
  \textbf{tuple}
    \textbf{let} a = \ldots
    \textbf{let} b = \ldots
    \textbf{let} c = \ldots
  \textbf{end}
\textbf{end}
\textbf{open} t
\end{alltt}
\end{quote}

\noindent
"Ahnlich wie in der gezeigten Sequenz l"a"st sich dieses Verhalten durch
Bindung eines globalen Bezeichners innerhalb des Sichtbarkeitsblockes an ein
lokales Objekt erreichen.  Unabh"angig von der verwendeten Technik, bleibt
festzuhalten, da"s Bezeichner innerhalb eines Sichtbarkeitsblockes nur mit
einem global existierenden Namen "uber die Sichtbarkeitsgrenze hinaus sichtbar
gemacht werden k"onnen.

\subsection{Funktion}
\label{subsec_funktion}
Der Sichtbarkeitsbereich einer Funktion setzt sich, bedingt durch die
Parameter"ubergabe an die Funktion, aus zwei Bl"ocken zusammen (s.\ Abbildung
\ref{abb_grfun}).

%\afterpage{\clearpage
\begin{figure}[H]
\centering\mbox{\epsfig{file=../Zeichnung/grfun.eps}}
\caption{Sichtbarkeitsbereich einer Funktion.}
\label{abb_grfun}
\end{figure}
%}

\begin{itemize}
\item Der Rumpf der Funktion wird durch einen \textit{begin \ldots\ end} Block
  gebildet.  In der Sprache {\tlmin} kann dies durch die Verwendung der
  Schl"usselw"orter \textit{begin} und \textit{end} deutlich gemacht werden.
  Das bedeutet auch, da"s innerhalb des Funktionsrumpfes alle au"serhalb
  definierten Bezeichner sichtbar sind.  Die Schl"usselw"orter \textit{begin}
  und \textit{end} k"onnen weggelassen werden, wenn der Funktionsrumpf nur aus
  einer (geschachtelten) Anweisung besteht.

\item Der "au"sere Sichtbarkeitsbereich sorgt daf"ur, da"s die Parameter in den
  inneren, den Sichtbarkeitsbereich des Rumpfes gelangen, aber nicht au"serhalb
  der Funktion definiert sind.  Die Namen bzw.\ Bindungen der Parameter werden
  an die Aktualparameter gebunden, die aus dem Sichtbarkeitsbereich des
  Funktionsaufrufenden stammen.  Diese dynamische Zuweisung an die
  Aktualparameter ist in Abbildung \ref{abb_grfun} durch die Notation nicht
  explizit dargestellt.

\end{itemize}

\noindent
Beachtenswert ist an dieser Stelle, da"s sich im Sichtbarkeitsbereich der
Funktion alle zur Definitionszeit existierenden Bezeichner befinden, die somit
auch zur Ausf"uhrungszeit referenzierbar sind.  Die Menge der tats"achlich
referenzierten Bezeichner bezeichnet man auch als Funktionsabschlu"s
(\textit{function closure}).

Abbildung \ref{abb_grfun} zeigt weiterhin, da"s der innere Sichtbarkeitsbereich
keine Auswirkung auf die gesamte Sichtbarkeitssituation hat, da nach Abschlu"s
des inneren und des "au"seren Bereichs keine Anweisungen stehen k"onnen.  Er
k"onnte somit entfallen, macht jedoch die durch die Schl"ussel\-w"orter
\textit{begin} und \textit{end} gebildete Klammer deutlich und ist deshalb in
der Darstellung enthalten.

\subsection{Abgeschlossener Sichtbarkeitsbereich}
Sichtbarkeitsbereiche gem"a"s Operation vier aus Abschnitt
\ref{subsec_anforderungen} werden in {\tlmin} durch die folgenden beiden
Konstrukte angelegt:

\begin{quote}
{\itshape scope [with \ldots do] end}
\end{quote}

\noindent
f"ur Werte und 

\begin{quote}
{\itshape Scope [with \ldots do] end}
\end{quote}

\noindent
f"ur Typen.

"Uber die optionale Verwendung von \textit{with \ldots do} gestatten sie sowohl
das Einschr"anken von Sichtbarkeitsbereichen an deren Beginn als auch das
selektive Einf"ugen.  Ein Konstrukt bezieht sich auf die Einschr"ankung der
Sichtbarkeitsbereiche von Werten, das andere Konstrukt auf die
Sichtbarkeitsbereiche von Typen.  Die Unterschiede in der Semantik sind:

\begin{itemize}

\item Das Sichtbarkeitskonstrukt f"ur Werte liefert einen Wert zur"uck.  Es
wird w"ahrend des Typ"uberpr"ufens auf einen Sequenzblock abgebildet, liefert
also den Wert der letzten Bindung zur"uck.

\item Das Sichtbarkeitskonstrukt f"ur Typen liefert einen Typ zur"uck.  Bei
korrekter Typisierung wird der im Sichtbarkeitsblock eingeschlossene Typ
zur"uckgegeben.

\end{itemize}

%\afterpage{\clearpage
\begin{figure}[H]
\centering\mbox{\epsfig{file=../Zeichnung/grscope.eps}}
\caption{Abgeschlossener Sichtbarkeitsbereich.}
\label{abb_grscope}
\end{figure}
%}

\noindent
Abbildung \ref{abb_grscope} zeigt einen abgeschlossenen Sichtbarkeitsbereich.
Die folgende kurze Sequenz von Anweisungen verdeutlicht die Verwendung der
Sichtbarkeitsoperation.  Sie f"uhrt zu einer Fehlermeldung, da sich der
Bezeichner \textit{a} nicht im Sichtbarkeitsbereich, der durch \textit{scope
  \ldots end} angelegt wird, befindet.

\begin{quote}
\begin{alltt}
\textbf{let} a = 3
\textbf{let} b = \textbf{scope} a + 3 \textbf{end}
\begin{math}\Rightarrow\end{math}\textsl{ Unbound identifier a.}
\end{alltt}
\end{quote}

\noindent
Abweichend dazu f"uhrt die nachfolgende Anweisungsfolge nicht zu einer
Fehlermeldung des Compilers, da der Bezeichner \textit{a} explizit in den
Sichtbarkeitsbereich eingef"uhrt wird.

\begin{quote}
\begin{alltt}
\textbf{let} a = 3
\textbf{let} b = \textbf{scope with} a infix+ \textbf{do} a + 3 \textbf{end}
\begin{math}\Rightarrow\end{math}\textsl{ 6 :Int}
\end{alltt}
\end{quote}

F"ur das Sichtbarkeitskonstrukt ist keine Laufzeitunterst"utzung notwendig.
Das ist begr"undet in der Tatsache, da"s es sich hierbei um eine rein statische
Abpr"ufung von Sichtbarkeit bzw. Vorhandensein von Bezeichnern handelt, die zur
"Ubersetzungszeit vollst"andig behandelt werden kann.

\subsubsection{Initiale Bezeichner}
In einem neuen Sichtbarkeitsbereich, der durch {\itshape scope\ldots end}
erzeugt wird, sind per Definition keine Bezeichner sichtbar.  Hierunter fallen 
auch initiale Bezeichner wie elementare Datentypen (z.B.\ \textit{Bool},
\textit{Int} usw.) und elementare Operationen auf diesen (Addition, Subtraktion
usw.), die bereits im Compiler vorhanden sind und nur durch Einrichten eines
entsprechenden Verweises in die Umgebung sichtbar gemacht werden m"ussen. 
% Im Gegensatz dazu werden andere Bezeichner erst zur Laufzeit definiert.

Hier stellt sich nun die generelle Frage, ob es einen Satz vordefinierter
Bezeichner geben soll, der zu jeder Zeit sichtbar ist und der auch durch
Sichtbarkeitsgrenzen nicht unsichtbar gemacht werden kann.  Das ist z.B.\ bei
Modulen in Modula-2 zu beobachten, wo trotz einer Sichtbarkeitsgrenze am Beginn
eines Moduls initiale Bezeichner sichtbar sind.  Weiterhin stellt sich die
Frage, welche Bezeichner in diese Kategorie fallen.  In der Implementierung von
Modula-2 sind alle initialen Bezeichner in allen Sichtbarkeitsbereichen des
Systems verf"ugbar.

Die in der Sprache {\tlmin} gew"ahlte L"osung sieht vor, die initialen
Bezeichner in einem eigenen Modul zu kapseln.  In jedem abgetrennten
Sichtbarkeitsbereich, in dem diese initialen Bezeichner Verwendung finden,
m"ussen sie importiert werden.  Der Vorteil dieser L"osung liegt zum einen
darin, da"s das Konzept der Sichtbarkeitsgrenzen semantisch rein definiert ist.
Eine Sichtbarkeitsgrenze entspricht dem Namen Grenze, da tats"achlich keine
Bezeichner \glqq hindurchkommen\grqq .  Zum anderen kann die Diskussion, welche
Bezeichner initial sind, dem Anwender "uberlassen werden, indem er die Freiheit
erh"alt, das Modul der initialen Bezeichner selbst zu gestalten bzw.\ 
unterschiedliche zu definieren.

\subsection{Selektiv eingef"uhrte Bezeichner}
\label{subsec_import}
Beim Konstrukt zum Konstruieren eines abgeschlossenen Sichtbarkeitsbereichs ist
bereits eine M"oglichkeit zum Importieren von Bezeichnern vorgesehen.  Dar"uber
hinaus kann es sinnvoll sein, Bezeichner innerhalb eines Blockes einzuf"uhren
und diese nicht schon zu Beginn sichtbar zu machen.  In {\tlmin} kann dies mit
der \textit{use} Klausel formuliert werden.

\begin{quote}
\begin{alltt}
\textbf{let} a = 3
\textbf{let} b = \textbf{scope} 
  \textbf{let} c = 42
  \textbf{use} a
  \textbf{let} d = a * c
\textbf{end}
\begin{math}\Rightarrow\end{math}\textsl{ 126 :Int}
\end{alltt}
\end{quote}

\noindent
Im vorstehenden Beispiel wird der Bezeichner \textit{a} erst nach der Bindung
von \textit{c} aus dem umschlies\-senden Sichtbarkeitsbereich eingef"uhrt.  Das
\textit{use} Konstrukt ist die Implementierung der f"unften elementaren
Operation auf Sichtbarkeitsbereichen.  Abbildung \ref{abb_grimport} zeigt die
Umsetzung in der grafischen Notation.

%\afterpage{\clearpage
\begin{figure}[H]
\centering\mbox{\epsfig{file=../Zeichnung/grimport.eps}}
\caption{Selektiv eingef"uhrter Bezeichner.}
\label{abb_grimport}
\end{figure}
%}

Die Umsetzung in {\tlmin} ist so realisiert, da"s sich die \textit{use}
Anweisung jeweils auf die letzte Sichtbarkeitsgrenze bezieht.  Es ist z.B.\
nicht sinnvoll, Bezeichner in einen \textit{begin \ldots\ end} Block
einzuf"uhren, da diese dort ohnehin sichtbar sind.  Die \textit{use} Anweisung
bezieht sich damit nicht auf den direkt umschlie"senden Sichtbarkeitsbereich,
sondern pr"aziser auf den durch eine Sichtbarkeitsgrenze abgeschlossenen
umschlie"senden Sichtbarkeitsbereich.

\section{H"ohere Strukturierungskonzepte}
\label{sec_hoehere_strukturierungskonzepte}
\begin{sloppypar}
In diesem Abschnitt wird gezeigt, wie man mit Hilfe der bereits eingef"uhrten
elementaren Sprachkonstrukte zur Manipulation von Sichtbarkeitsbereichen
h"ohere Strukturierungskonzepte realisieren kann.  Als Beispiel werden Module
und Schnittstellen formuliert, die in modulorientierten Programmiersprachen wie
z.B.\ Modula-2 und {\tl} zur Systemstrukturierung eingesetzt werden.  Diese
h"oheren Konzepte dienen dazu, die unabh"angige Entwicklung und Implementierung
und damit die in Kapitel \ref{cha_einleitung} aufgef"uhrten Prinzipien zu
unterst"utzen.  Dazu m"ussen diese h"oheren Strukturierungseinheiten separat
"ubersetzbar sein, d.h.\ der Entwurf und die Implementierung eines Moduls kann
zeitlich schon dann erfolgen, wenn von den benutzten (importierten) Modulen nur
die Schnittstellen und nicht die Implementierungen vorliegen.  Zum einen wird
damit die Anwendung der Prinzipien Modularisierung und Wiederverwendbarkeit
unterst"utzt, da die Module und Schnittstellen ein Programm bereits in kleinere
Einheiten zerlegen.  Module als abgeschlossene Einheiten k"onnen in anderen
Programmen wiederverwendet werden, alle abh"angigen Teile sind in der
Importliste festgeschrieben.  Zum anderen wird durch die Aufteilung in Module
und Schnittstellen die Entwicklung in einem Programmierteam unterst"utzt, da
die beteiligten Entwickler nach Festlegung der Schnittstellen unabh"angig
voneinander Module entwerfen, ausprogrammieren und testen k"onnen.
\end{sloppypar}

Als weitere Anforderungen an Module und Schnittstellen werden die folgenden
Punkte aufgef"uhrt.

\begin{itemize}
\item Module k"onnen mehreren Schnittstellen gen"ugen, wenn die Schnittstellen
  in einer Subtyp\-beziehung zueinander stehen.

\item Eine Schnittstelle kann von mehreren dem Typ der Schnittstelle
  entsprechenden Modulen implementiert werden.

\item Module sind flexibel konfigurierbar.  D.h.\ bei der Instantiierung eines
  Moduls, also zum Zeitpunkt des Bindens, besitzt der Programmierer die
  Freiheit, das Modul mit beliebigen, dem Typ der importierten Bezeichner
  entsprechenden Einheiten zu parametrisieren.

\item Schnittstellen sind wie Module flexibel konfigurierbar.
\end{itemize}

Die Module und Schnittstellen k"onnen "uber eine Syntaxerweiterung dem
Programmierer "uber Schl"usselworte zur Verf"ugung gestellt werden.  Durch
diesen Ansatz ist es m"oglich, auch andere Konzepte wie z.B.\ Klassen in die
Sprache einzuf"uhren, ohne jedoch die eigentliche Kernsprache {\tlmin} zu
ver"andern und den Compiler modifizieren zu m"ussen.  Lediglich der Parser wird
mit der neuen Grammatik parametrisiert.  In bestimmten Situationen mu"s der
"Ubersetzungsvorgang der Softwareeinheiten werkzeugunterst"utzt erfolgen.  Wie
in Abschnitt \ref{sec_modulverwaltung} gezeigt wurde, ist hierzu jedoch kein
Eingriff in den "Ubersetzer selbst notwendig.  Die erforderlichen Anpassungen
k"onnen komplett auf der Anwendungsebene erfolgen.

Als Vorteil dieses Ansatzes ist auch zu sehen, da"s alle compilerinternen
Repr"asentationen und Algorithmen nicht nur unver"andert bleiben, sondern auch
weiterhin kompatibel sind, d.h., da"s Objekte, die mit einem um Klassen
erweiterten {\tlmin} "Ubersetzer erzeugt wurden, kompatibel zu Objekten eines
um Module und Schnittstellen erweiterten Compilers sind.  Programmierer
k"onnen also nach eigenen Pr"aferenzen Systemstrukturierungskonzepte
ausw"ahlen und dennoch Code und Zwischenrepr"asentationen des "Ubersetzers
austauschen.

\subsection{Schnittstellen}
\label{subsec_schnittstellen}
Schnittstellen werden zwischen Programmen und zwischen abgeschlossenen
Programmteilen (Modulen) definiert \cite{duden}.  Dazu formuliert man alle von
einem Modul auszuf"uhrenden Aufgaben, die erforderlichen Attribute, die
bereitgestellten Funktionen einschlie"slich Parameter, die
Zugriffsm"oglichkeiten auf Daten und die Beziehungen zwischen ihnen
\cite{duden}.  Erg"anzend dazu kommen Angaben zur Reihenfolge der Benutzung
sowie Vor- bzw.\ Nachbedingungen.  Softwaretechnisch erm"oglichen
Schnittstellen den unabh"angigen Entwurf und die unabh"angige Implementierung
von Programmeinheiten dadurch, da"s sie den importierenden Modulen und
Schnittstellen die gew"unschten Bezeichner mit Information "uber ihren Typ zur
Verf"ugung stellen und sichtbar machen. 

Bezogen auf {\tlmin} m"ussen Schnittstellen Module spezifizieren, indem sie die
Signaturen aller exportierten von au"sen nutzbaren Funktionen enthalten.
Weiterhin werden Typen und Werte, die ein Modul exportiert, in der
Schnittstelle aufgef"uhrt.

%\afterpage{\clearpage
\begin{figure}[htb]
\hrule
\vskip \baselineskip
\begin{alltt}
\textbf{Let} Stack =  \textbf{Scope with} StdType StdIde \textbf{do}
\textbf{Oper}(\textbf{Let} StdType = StdType()
     \textbf{Let} StdIde = StdIde(:StdType)  stdIde :StdIde)
  \textbf{Scope with} stdIde \textbf{do}
    \textbf{Tuple}
      T <: \textbf{Oper}(E <:\textbf{Ok}) \textbf{Ok}
      new (E <:\textbf{Ok}) :T(:E)
      empty (E <:\textbf{Ok} stack :T(:E)) :stdIde.Bool
      push (E <:\textbf{Ok} element :E stack :T(:E)) :T(:E)
      pop (E <:\textbf{Ok} stack :T(:E)) :T(:E)
      top (E <:\textbf{Ok} stack :T(:E)) :E
    \textbf{end}
  \textbf{end}
\textbf{end}
\end{alltt}
\hrule
\caption{Schnittstellendefinition f"ur ein Stack-Modul mit Hilfe von {\tlmin} 
Basisprimitiven.}
\label{abb_Stack}
\end{figure}
%}

Abbildung \ref{abb_Stack} zeigt die Definition einer Schnittstelle, die ein
Stack-Modul spezifiziert.  Mit Hilfe eines Tupeltypen werden die exportierten
Bezeichner aggregiert.  Sie stellen die eigentliche Schnittstelle dar.
Innerhalb dieses Tupels werden nun die zuvor importierten Bezeichner benutzt.
Hierbei kann es sich sowohl um Schnittstellen als auch Module handeln, wobei
bei letzteren nicht zugesichert werden kann, da"s diese zum Zeitpunkt der
"Ubersetzung dieser Schnittstelle existieren.  Die angestrebte separate
"Ubersetzung l"a"st es sogar explizit zu, da"s diese Module nicht existieren
m"ussen.  Aus diesem Grund wird die Auswertung dieses Tupeltypen durch einen
Typoperator verz"ogert.  Er wird mit den importierten Bezeichnern
parametrisiert, die in der Parameterliste lokal gebunden werden.  Sie m"ussen
dazu jedoch mit den ihrerseits importierten Bezeichnern parametrisiert werden.
Letztendlich werden in der Parameterliste des Typoperatoren somit alle
transitiv erreichbaren Bezeichner aufgef"uhrt.

Die Sichtbarkeit des Schnittstellenrumpfes wird durch zwei Scope-Konstrukte
determiniert, Abbildung \ref{abb_grinterface} verdeutlicht dies anhand der
eingef"uhrten Notation.  Diese stellen folgendes sicher:

\begin{itemize}
\item Das "au"sere Scope-Konstrukt sorgt daf"ur, da"s alle Typen, die direkt
  oder indirekt (transitiv) importiert werden, in den Sichtbarkeitsbereich der
  Typoperatordefinition gelangen.  Modulbezeichner werden nicht zum Zeitpunkt
  der Definition in den Sichtbarkeitsbereich des Typoperators gebracht, sondern
  bei der Instantiierung als Parameter "ubergeben\footnote{Im Gegensatz zu
    {\tl} ist es in {\tlmin} m"oglich, Typoperatoren mit Wertparametern zu
    formulieren und zu instantiieren.  Dies ist eine Voraussetzung, um diese
    Abbildung realisieren zu k"onnen.}. Das Beispiel in Abschnitt
  \ref{subsec_rautenimport} macht dies deutlich.

\item Das innere Scope-Konstrukt bringt diejenigen Bezeichner in den
  Sichtbarkeitsbereich des Schnittstellenrumpfes, die dort tats"achlich
  referenziert werden.  Bei der Formulierung mit Hilfe einer Syntaxerweiterung
  wie in Abbildung \ref{abb_StackI} sind dies die in der Import-Klausel
  aufgef"uhrten Bezeichner.  Hier treten nun sowohl Typ- als auch Wertbezeichner
  auf.
\end{itemize}

%\afterpage{\clearpage
\begin{figure}[H]
\centering\mbox{\epsfig{file=../Zeichnung/grinterface.eps}}
\caption{Sichtbarkeitsszenario einer Schnittstelle.}
\label{abb_grinterface}
\end{figure}
%}

\noindent
Alle in der Schnittstelle verwendeten, jedoch nicht importierten, Bezeichner
f"uhren dazu, da"s die Schnittstellendefinition vom Typ"uberpr"ufer
zur"uckgewiesen wird.  Dies ist insbesondere durch das innere Scope-Konstrukt
gew"ahrleistet, dessen Abwesenheit es erm"oglichen w"urde, alle auch transitiv
erreichbaren Bezeichner zu referenzieren, ohne diese in der Import-Klausel
aufzuf"uhren.  Die Scope-Konstrukte dienen damit der Unterscheidung von
Bezeichnern in zwei Gruppen:

\begin{itemize}
\item Bezeichner, die zum Instantiieren der Schnittstelle (Typoperator)
  notwendig sind.

\item Bezeichner, die zum Typ"uberpr"ufen des Schnittstellenrumpfes notwendig
  sind.
\end{itemize}

Da eine Schnittstelle Typinformation repr"asentiert und Module Werte dieses
Typs darstellen (s.\ Abschnitt \ref{subsec_module}), k"onnen zu einer
Schnittstelle verschiedene Modulauspr"agungen existieren, so wie zu einem
Typen mehrere Werte existieren k"onnen.

%\afterpage{\clearpage
\begin{figure}[htb]
\hrule
\vskip \baselineskip
\begin{alltt}
\textbf{Let} Stack2 = \textbf{Scope with} StdType \textbf{do}
\textbf{Oper}(\textbf{Let} StdType = StdType())
     \textbf{Let} StdIde = StdIde(:StdType)  stdIde :StdIde)
  \textbf{Scope with} stdIde \textbf{do}
    \textbf{Tuple}
      T <: \textbf{Oper}(E <:\textbf{Ok}) \textbf{Ok}
      new (E <:\textbf{Ok}) :T(:E)
      empty (E <:\textbf{Ok} stack :T(:E)) :stdIde.Bool
      push (E <:\textbf{Ok} element :E stack :T(:E)) :T(:E)
      pop (E <:\textbf{Ok} stack :T(:E)) :T(:E)
    \textbf{end}
  \textbf{end}
\textbf{end}
\end{alltt}
\hrule
\caption{Generalisierte Schnittstellendefinition f"ur ein Stack-Modul.}
\label{abb_Stack2}
\end{figure}
%}

Schnittstellendefinitionen bzw.\ die ausgewerteten Typoperatoren k"onnen 
gem"a"s der Subtyp\-regeln f"ur Tupeltypen in Beziehung
zueinander stehen.  So ist z.B.\ die in Abbildung \ref{abb_Stack2}
dargestellte Schnittstelle \textit{Stack2} ein Supertyp der Schnittstelle
\textit{Stack}, da sie weniger Komponenten enth"alt, die verbleibenden aber
denen aus \textit{Stack} entsprechen.  Somit k"onnen Module der Schnittstelle
\textit{Stack} dort auftreten, wo Module der Schnittstelle \textit{Stack2}
gefordert sind, wobei durch den "Ubersetzer nur die syntaktische und
typm"a"sige Korrektheit zugesichert wird.  Zusicherungen, da"s ein Modul auch
von der implementierten Funktionalit"at her der Schnittstelle bzw.\ den
Erwartungen an sie entsprechen, k"onnen nicht gegeben werden.  Allgemein ist
die Generalisierung von Schnittstellen nicht auf das Weglassen von Bezeichnern
bzw.\ Signaturen beschr"ankt.  Es kommen vielmehr die in \cite{tycoon_po} und
\cite{bremer} ausgef"uhrten Typregeln f"ur Tupeltypen zur Anwendung.

Schnittstellen beziehen sich bei ihrer Definition auf andere Bezeichner
(Import).  Von diesen Bezeichnern wird ausschlie"slich die Typinformation
genutzt.  Es reicht somit aus, Schnittstellen und Module mit der Typinformation
importierter Bezeichner zu versorgen.  Diese steht jedoch nicht ausschlie"slich
in anderen Schnittstellen, sondern im Falle von abstrakten Datentypen in den
Modulen, die Datentyp und Funktionen auf Objekten dieses Typs aggregieren und 
die in der Schnittstelle die Typinformation nicht offenlegen.

Die Schnittstellen repr"asentierenden Typoperatoren m"ussen deshalb explizit
mit den Modulwerten der importierten Bezeichner instantiiert werden.  Nur
auf diese Weise ist eine Kompatibilit"at von Objekten abstrakter Datentypen
gew"ahrleistet.

\begin{quote}
\begin{alltt}
\textbf{Let} Stack = Stack(:StdType :StdIde stdIde);
\end{alltt}
\end{quote}

\noindent
Dieser Aspekt wird in Abschnitt \ref{subsec_binden} wieder aufgegriffen.

%\afterpage{\clearpage
\begin{figure}[htb]
\hrule
\vskip \baselineskip
\begin{alltt}
\textbf{interface} Stack
\textbf{import}
  stdIde
\textbf{export}
  T <: \textbf{Oper}(E <:\textbf{Ok}) \textbf{Ok}
  new (E <:\textbf{Ok}) :T(:E)
  empty (E <:\textbf{Ok} stack :T(:E)) :stdIde.Bool
  push (E <:\textbf{Ok} element :E stack :T(:E)) :T(:E)
  pop (E <:\textbf{Ok} stack :T(:E)) :T(:E)
  top (E <:\textbf{Ok} stack :T(:E)) :E
\textbf{end}
\end{alltt}
\hrule
\caption{Schnittstellendefinition f"ur ein Stack-Modul mit Hilfe von 
Syntaxerweiterung.}
\label{abb_StackI}
\end{figure}
%}

Durch die Verwendung des Scope-Konstruktes sind alle Bezeichner, die nicht in
der dem Schl"usselwort \textit{with} folgenden Liste aufgef"uhrt sind,
verdeckt.  Dies gilt auch f"ur die Standardtypen und -operationen, wie Int,
Bool usw.  Sollen diese in der von Sprachen wie Modula-2 gewohnten Weise zur
Verf"ugung stehen, ist es notwendig, die in den Schnittstellen \textit{StdType}
und \textit{StdIde} befindlichen Bezeichner explizit sichtbar zu machen.
\footnote{Das f"uhrt jedoch dazu, da"s "uber diese Schnittstelle alle diese
  Bezeichner exportiert werden und auch im entsprechenden Modul aufgef"uhrt
  werden m"ussen.  Die Schnittstelle wird dadurch nicht nur besonders gro"s,
  sondern f"uhrt zus"atzliche Bezeichner f"ur die Standardtypen ein, wie z.B.
  \textit{Stack.int\_T} durch die Schnittstelle \textit{Stack}.  Der
  Typ"uberpr"ufer erkennt jedoch die Gleichheit aller auf diese Weise erzeugten
  Typen.  So ist \textit{Stack.int\_T} gleich \textit{Stack2.int\_T} und diese
  gleich \textit{stdType.Int}.}

Um dem Programmierer die fehlertr"achtige Schreibweise, wie sie in Abbildung
\ref{abb_Stack} und \ref{abb_Stack2} verwendet wird, zu ersparen, kann mittels
Syntaxerweiterung eine intuitive Schreibweise gew"ahlt werden.  Ein Beispiel
hierf"ur ist in Abbildung \ref{abb_StackI} gegeben.  Die Darstellung in
Abbildung \ref{abb_Stack} kann jedoch nicht durch rein textuelle Umformungen
aus der Formulierung in Abbildung \ref{abb_StackI} gewonnen werden, da die
Information "uber transitiv importierte Bezeichner aus der Darstellung in
Abbildung \ref{abb_StackI} nicht hervorgeht.  Diese mu"s durch ein Werkzeug
bereitgestellt werden (s. Abschnitt \ref{sec_modulverwaltung}), das die
Abh"angigkeitsinformation w"ahrend des "Ubersetzungsvorganges, meist w"ahrend
des Parsens, sammelt.


\subsection{Module}
\label{subsec_module}
Ein Modul ist nach \cite{duden} die Zusammenfassung von Konstanten,
Datentypen, Variablen und Prozeduren zu einer Einheit.  Soll ein Modul von
einem anderen benutzt werden, so mu"s angegeben werden, welche Teile des
Moduls von au"sen sichtbar sein sollen und welche nicht.  Dies festzulegen ist
Aufgabe der Schnittstellen (s. Abschnitt \ref{subsec_schnittstellen}).  Die
konkrete Realisierung insbesondere der Datentypen und der Prozeduren soll
jedoch verborgen bleiben.  Daraus ergeben sich Anforderungen an die
Sichtbarkeitsszenarios von Modulen:

%\afterpage{\clearpage
\begin{figure}[H]
\hrule
\vskip \baselineskip
\begin{alltt}
\textbf{let} stackLINK =  
\textbf{scope with} List StdType Stack StdIde \textbf{do}
  \textbf{fun}(\textbf{Let} StdType = StdType()  stdType :StdType
      \textbf{Let} StdIde = StdIde(:StdType)  stdIde :StdIde
      \textbf{Let} List = List(:StdType :StdIde stdIde)  list :List  
      \textbf{Let} Stack = Stack(:StdType :StdIde stdIde)) :Stack
  \textbf{scope with} list stdType Stack \textbf{do}
    \textbf{Let} T(E <:\textbf{Ok}) = list.T(:E)
    \textbf{let} new (E <:\textbf{Ok}) :T(:E) = 
      list.new (:E)
    \textbf{let} empty (E <:\textbf{Ok} stack :T(:E)) :stdIde.Bool = 
      list.empty (stack)
    \textbf{let} push (E <:\textbf{Ok} element :E stack :T(:E)) :T(:E) =
      list.cons (element stack)
    \textbf{let} pop (E <:\textbf{Ok} stack :T(:E)) :T(:E) =
      list.tail (stack)
    \textbf{let} top (E <:\textbf{Ok} stack :T(:E)) :E =
      list.head (stack)
    \textbf{let} result :Stack = \textbf{tuple}
      \textbf{Let} T = T
      \textbf{let} new = new
      \textbf{let} empty = empty
      \textbf{let} push = push
      \textbf{let} pop = pop
      \textbf{let} top = top
    \textbf{end} 
    result
  \textbf{end}
\textbf{end}
\end{alltt}
\hrule
\caption{Modulimplementierung gem"a"s der Schnittstelle \textit{Stack}.}
\label{abb_stackLINK}
\end{figure}
%}

\begin{itemize}
\item Ein Modul kann ein anderes benutzen und mu"s folglich Zugriff auf
  entsprechende Typ- und Wertinformation haben.

\item Die Implementationen von Datentypen und Prozeduren sind gem"a"s der
  Schnittstelle sichtbar; d.h., da"s Typen, die in der Schnittstelle abstrakt
  definiert wurden, durch das Modul, in dem eine konkrete Ausformulierung
  erfolgen mu"s, nicht ihre Implementierungsdetails preisgeben d"urfen.  Die
  Sichtbarkeitsregeln f"ur Funktionen sorgen bereits daf"ur, da"s im Rumpf
  definierte Bezeichner nicht nach au"sen sichtbar werden (s. Abschnitt
  \ref{subsec_funktion}).

\item Alle nicht in der Schnittstelle aufgef"uhrten Bezeichner sind au"serhalb
  des Moduls nicht sichtbar.
\end{itemize}

Dar"uber hinaus mu"s ein Modul, wie in Abschnitt
\ref{sec_hoehere_strukturierungskonzepte} ausgef"uhrt, separat "ubersetzbar
sein, um unabh"angige Entwicklung und Implementierung zu unterst"utzen.

Ein Modul soll nach M"oglichkeit mehreren Schnittstellen gen"ugen k"onnen, z.B.
wenn die Schnittstellen unterschiedlich viele Bezeichner exportieren, wie die
Schnittstellen \textit{Stack} und \textit{Stack2}.  Das Modul \textit{stack}
entspricht nach den Subtypregeln beiden Schnittstellen.  Der von der
entsprechenden Funktion evaluierte Wert, das Modul, gen"ugt sowohl
\textit{Stack} als auch \textit{Stack2}.  Um dies zu erreichen, wird hier der
maximale Typ angegeben, also der Typ, der die spezialisiertesten Angaben macht
(\textit{Stack}).  Alle Schnittstellen, denen das Modul ebenfalls gen"ugt, sind
Supertypen dieses Typs.

%\afterpage{\clearpage
\begin{figure}[H]
\hrule
\vskip \baselineskip
\begin{alltt}
\textbf{module} stack :Stack
\textbf{import}
  list
  stdIde
\textbf{export}
  \textbf{Let} T(E <:\textbf{Ok}) = list.T(:E)
  \textbf{let} new (E <:\textbf{Ok}) :T(E:) = 
    list.new (:E)
  \textbf{let} empty (E <:\textbf{Ok} stack :T(:E)) :stdIde.Bool = 
    list.empty (stack)
  \textbf{let} push (E <:\textbf{Ok} element :E stack :T(:E)) :T(:E) =
    list.cons (element stack)
  \textbf{let} pop (E <:\textbf{Ok} stack :T(:E)) :T(:E) =
    list.tail (stack)
  \textbf{let} top (E <:\textbf{Ok} stack :T(:E)) :E =
    list.head (stack)
\textbf{end}
\end{alltt}
\hrule
\caption{Modulformulierung mittels Syntaxerweiterung.}
\label{abb_stackLINKM}
\end{figure}
%}

In {\tlmin} kann ein Modul wie in Abbildung \ref{abb_stackLINK} formuliert
werden.  Analog zu Schnittstellen wird die eigentlich gew"unschte Information,
das Modul, mit Hilfe eines Tupels aggregiert.  Bei einem Modul verfolgt man mit
der expliziten Bindung an ein Tupel weiterhin, da"s die Reihenfolge der zuvor
aufgef"uhrten Bezeichner keinen Einflu"s auf den Modulwert nimmt.  Durch die
Verwendung von Schnittstelle und Modulen in der Importliste entsteht auch bei
einem Modul die Notwendigkeit, die Auswertung des Moduls (die Evaluierung des
Tupelwertes) zu verz"ogern, weil die referenzierten Module zum
Definitionszeitpunkt noch nicht vorliegen m"ussen.  Es wird bei der
Formulierung eines Moduls ein "ahnliches Konstrukt wie bei Schnittstellen in
Abschnitt \ref{subsec_schnittstellen} benutzt, da es sich bei dem Modul jedoch
um einen Wert handelt, wird zur Verz"ogerung der Auswertung eine Funktion
verwendet.

Wie bei Schnittstellen bedienen sich Module ebenfalls zweier
geschachtelter Scope-Kon\-strukte.  Auch hier verfolgen sie den Zweck,
einerseits die transitiv erreichbaren Schnittstellen in den
Sichtbarkeitsbereich der Funktion zu bringen und andererseits
diejenigen Bezeichner, die innerhalb des Moduls tats"achlich
referenziert werden, f"ur den Modulrumpf bereitzustellen.  Innerhalb
des Funktionskopfes werden sowohl die direkt als auch die indirekt
importierten Schnittstellen und Module angegeben.  Die transitiv
erreichbaren Typen m"ussen in der Funktionssignatur angegeben werden,
da diese zum Definitionszeitpunkt des Moduls noch nicht instantiiert
sein m"ussen.  Durch die besondere Schreibweise der Typparameter bzw.
deren Signaturen sind diese f"ur nachfolgend aufgef"uhrte Signaturen
sichbar.  So sind z.B. in Abbildung \ref{abb_stackLINK} die
Typbezeichner \textit{StdType} und \textit{StdIde} sowie der Wert
\textit{stdIde} f"ur den Ausdruck \textit{Stack(:StdType :StdIde
  stdIde)} sichtbar.

%\afterpage{\clearpage
\begin{figure}[htb]
\centering\mbox{\epsfig{file=../Zeichnung/grmodul.eps}}
\caption{Sichtbarkeitsbereich eines Moduls.}
\label{abb_grmodul}
\end{figure}
%}

Um beim Bindevorgang nicht auf Module angewiesen zu sein, die exakt
dem in der Importliste angegebenen Namen entsprechen, hat die
Link-Funktion \textit{stackLINK} Parameter gem"a"s ihrer transitiven
Importe.  Alternativ h"atten die Namen nur in der Scope-Anweisung
auftreten k"onnen, und die Funktion \textit{stackLINK} an sich w"are
parameterlos gewesen.  Das Problem, da"s abstrakte Datentypen genau
"uber den Pfad angesprochen werden m"ussen, "uber den sie definiert
sind, k"onnte damit nicht gel"ost werden.  Konkret hei"st das, da"s
bei der Verwendung eines abstrakten Datentyps, der in einem Modul
definiert ist, der Modulbezeichner angegeben werden mu"s.  Auch das
ist durch die Verwendung von Funktionsparametern gew"ahrleistet.

Damit die Reihenfolge der Funktionsdefinitionen nicht der Reihenfolge der
Schnittstellenbeschreibung entsprechen mu"s, sondern dem Programmierer
gr"o"stm"ogliche Freiheit gegeben werden kann, wird der R"uckgabewert
(\textit{result}) der Funktion \textit{stackLINK} explizit gebunden.

Bei der Formulierung von Modulen wird die M"oglichkeit der expliziten
Einschr"ankung des Sichtbarkeitsbereichs genutzt, um den Funktionsabschlu"s
auf die tats"achlich importierten Bezeichner zu beschr"anken.  Durch die
Beschr"ankung auf Typen im "au"sersten Scope-Konstrukt kann ein Modul separat,
d.h.\ ohne das Vorhandensein anderer Module, "ubersetzt werden.  Weiterhin
wird eine Funktion eingesetzt, die eine verz"ogerte Bindung an importierte
Module erlaubt.  Abbildung \ref{abb_grmodul} zeigt die grafische
Repr"asentation der Sichtbarkeitsbereiche eines Moduls.  Dabei wird die
Formulierung mittels Syntaxerweiterung der Beschreibung mit {\tlmin}
Sprachprimitiven gegen"ubergestellt.

\subsection{Binden}
\label{subsec_binden}
Das Modell der in Abschnitt \ref{subsec_schnittstellen} und \ref{subsec_module}
vorgestellten Schnittstellen und Module sieht vor, da"s sowohl die
Schnittstellen als auch die Module instantiiert werden m"ussen, wenn die
referenzierten (importierten) Bezeichner gebunden sind, um zum Zeitpunkt der
semantischen Analyse nicht auf die Anwesenheit der Modulwerte angewiesen zu
sein.  Genau dies ist die Bedingung f"ur separates "Ubersetzen.  F"ur
Schnittstellen entspricht diese Instantiierung der Anwendung eines
Typoperators.  Dies ist im folgenden f"ur die in Abschnitt
\ref{subsec_schnittstellen} eingef"uhrten Schnittstellen \textit{Stack} und
\textit{Stack2} gezeigt:

\begin{quote}
\begin{alltt}
\textbf{Let} Stack = Stack(:StdType :StdIde stdIde);
\textbf{Let} Stack2 = Stack2(:StdType :StdIde stdIde);
\end{alltt}
\end{quote}

Die in Abbildung \ref{abb_stackLINK} dargestellte Funktion liefert mit jedem
Aufruf einen Wert des angegebenen Typen \textit{Stack} und damit bei jedem
Aufruf ein Modul der Schnittstelle \textit{Stack}.  Beachtenswert ist hier, da"s
die Funktion \textit{stackLINK} erst dann ausgef"uhrt werden kann, wenn alle
transitiv importierten Schnittstellen und Module instantiiert wurden.  Die
Auswertung der Schnittstelle \textit{Stack} zum entsprechenden Typ mu"s also
vorher geschehen\footnote{Die Instantiierung der Schnittstellen \textit{List}
  und \textit{StdType} und der Module \textit{list} und \textit{stdType} wird
  hier nicht vorgef"uhrt, erfolgt aber analog zum Gezeigten.  An dieser Stelle
  wird ebenfalls darauf verzichtet, die Schnittstellen \textit{List} und
  \textit{StdType} als Typoperatoren mit entsprechenden Parametern zu zeigen,
  weil dies die "Ubersichtlichkeit negativ beeinflu"st h"atte, ohne zum
  Verst"andnis beizutragen.}.  Durch die folgenden zwei Aufrufe werden zwei
Module evaluiert.

\begin{quote}
\begin{alltt}
\textbf{let} stackA :Stack = stackLINK(:StdType stdType
                              :StdIde stdIde
                              :List list :Stack);
\textbf{let} stackB :Stack = stackLINK(:StdType stdType
                              :StdIde stdIde
                              :List list :Stack);
\end{alltt}
\end{quote}

\noindent
Eine Schnittstelle spezifiziert auf diese Weise mehrere Module.  Sie kann
unterschiedlich implementiert werden.

Durch die Typregeln von {\tlmin} kann ein durch \textit{stackLINK} erzeugtes
Modul an einen Bezeichner, der einem Supertyp des eigenen Typs (maximale
Spezifikation von \textit{Stack}) gen"ugt, gebunden werden. 

\begin{quote}
\begin{alltt}
\textbf{let} stack :Stack = stackLINK(:StdType stdType
                              :StdIde stdIde
                              :List list :Stack);
\textbf{let} stack2 :Stack2 = stackLINK(:StdType stdType
                              :StdIde stdIde
                              :List list :Stack);
\end{alltt}
\end{quote}

\noindent
Das Modul \textit{stack2} besitzt keine sichtbare Komponente \textit{top}.
Diese wird durch die obige Zuweisung ausgeblendet.  Modulinterne Zugriffe sind
jedoch weiterhin m"oglich, da hier nur die Sichtbarkeit nach au"sen
eingeschr"ankt wird.  Das Beispiel zeigt, da"s ein Modul mehrere
Schnittstellen implementieren kann.

\begin{sloppypar}
Die Link-Funktion mu"s mit den importierten Bezeichnern, also anderen Modulen
und Schnittstellen, parametrisiert werden.  Sie werden bei der Evaluierung der
Funktion als Aktualparameter der Funktion \textit{stackLINK} "ubergeben.
Dadurch mu"s der Name, der innerhalb des Moduls \textit{stack} f"ur einen
importierten Bezeichner benutzt wird, nicht dem tats"achlichen Namen
entsprechen.
\end{sloppypar}

Wird in dem bisher verfolgten Beispiel die Implementation des importierten
Moduls \textit{list} vom Typ \textit{:List} ge"andert, so kann das Modul
\textit{stack}, repr"asentiert durch \textit{stackLINK}, ohne neu "ubersetzt zu
werden, an ein anderes Modul gleichen Typs bzw. eines Subtyps gebunden werden.

\begin{quote}
\begin{alltt}
\textbf{let} fastStack :Stack = stackLINK(:StdType stdType
                              :StdIde stdIde
                              :List fastList :Stack);
\end{alltt}
\end{quote}

\noindent
Ein Modul kann an unterschiedliche Module gebunden werden, solange sie dem
angegebenen Typ gen"ugen.  So kann das Modul \textit{fastList} mehr Funktionen
als das Modul \textit{list} aufweisen, es mu"s jedoch in einer Subtypbeziehung
zu diesem stehen.  Zu beachten ist allerdings, da"s durch die Verwendung
unterschiedlicher Implementationen f"ur die Komponente \textit{list} des Moduls
\textit{fastStack} Objekte des Typs \textit{fastStack.T} nicht kompatibel zu
Objekten des Typs \textit{stackA.T} oder \textit{stack.T} sind.  Auch
Objekte des Typs \textit{stackA.T} und \textit{stack.T} sind nicht
untereinander austauschbar, da der Typ"uberpr"ufer die Kompatibilit"at
der Implementationen nicht zusichern kann.

\subsection{Rautenimport}
\label{subsec_rautenimport}
Das bisher vorgestellte Modell der Strukturierung mittels Modulen und
Schnittstellen bietet dem Programmierer gro"se Flexibilit"at
insbesondere in bezug auf die Kombination von Modulen zu
ablauff"ahigen Programmen.

Abbildung \ref{abb_rautenimport} stellt zwei Programmkonfigurationen
gegen"uber, die die besondere Problematik der abstrakten Datentypen aufdecken.
Der vollst"andige Programmcode des Beispiels ist in Anhang
\ref{cha_rautenimport} wiedergegeben.  In Teil a wird das Modul \textit{stack}
"uber mehrere Pfade importiert.  Werden die Module \textit{stack} bzw.\ 
\textit{fastStack} "uber die Module \textit{kreditor} und \textit{debitor}
beide unter dem Namen \textit{stack} sichtbar, so mu"s der Typ"uberpr"ufer
feststellen, da"s es sich hierbei im Fall a um dasselbe Modul handelt und im
Fall b nicht.  Er sollte die beiden in Abbildung \ref{abb_rautenimport}
dargestellten F"alle a und b unterscheiden k"onnen.

%\afterpage{\clearpage
\begin{figure}[htb]
\centering\mbox{\epsfig{file=../Zeichnung/raute.eps}}
\caption{Rautenimport.}
\label{abb_rautenimport}
\end{figure}
%}

Die nachfolgende Sequenz zeigt, wie der Fall a behandelt werden kann.  Hierbei
ist zu ber"uck\-sichtigen, da"s, wie auch der "Ubersetzungvorgang selbst, der
Bindevorgang durch Werkzeuge unterst"utzt werden sollte, um einerseits die
Reihenfolge der Anweisungen einzuhalten und andererseits die fehleranf"allige
Formulierung der Aufrufe zu automatisieren.

\begin{quote}
\begin{alltt}
\textbf{Let} Stack = Stack(:StdType :StdIde stdIde);
\textbf{let} stack :Stack = stackLINK(:StdType stdType
                             :StdIde stdIde
                             :List list :Stack);
\textbf{Let} Kreditor = Kreditor(:StdType stdType 
                             :StdIde stdIde
                             :List list
                             :Stack stack);
\textbf{Let} Debitor = Debitor(:StdType stdType 
                           :StdIde stdIde
                           :List list
                           :Stack stack);
\textbf{let} kreditor :Kreditor = kreditorLINK(:StdType stdType 
                                      :StdIde stdIde
                                      :List list
                                      :Stack stack 
                                      :Kreditor);
\textbf{let} debitor :Debitor = debitorLINK(:StdType stdType 
                                   :StdIde stdIde
                                   :List list
                                   :Stack  stack 
                                   :Debitor);
\textbf{Let} Mandant = Mandant(:StdType stdType 
                      :StdIde stdIde
                      :List list 
                      :Stack stack 
                      :Debitor debitor 
                      :Kreditor kreditor);
\textbf{let} mandant :Mandant = mandantLINK(:StdType stdType
                                   :StdIde stdIde
                                   :List list
                                   :Stack stack
                                   :Debitor debitor
                                   :Kreditor kreditor 
                                   :Mandant);
\end{alltt}
\end{quote}

In der semantischen Analyse kann der Typ"uberpr"ufer durch Vergleich der
Objektidentit"aten herausfinden, da"s der Typ \textit{stack.T} aus
\textit{debitor} mit dem gleichnamigen Typ aus \textit{kreditor} identisch
ist.  Dies ist anhand der Parameter obiger Ausf"uhrungssequenz leicht
nachzuvollziehen.  Im Modul \textit{mandant} ist eine Anwendung der Form

\begin{quote}
\begin{alltt}
debitor.put(kreditor.get())
\end{alltt}
\end{quote}

\noindent
typkorrekt.  Nachfolgend sind Anweisungen wiedergegeben, die dem in Abbildung
\ref{abb_rautenimport} gezeigten Fall b entsprechen:

\begin{quote}
\begin{alltt}
\textbf{Let} Stack = Stack(:StdType :StdIde stdIde);
\textbf{let} stack :Stack = stackLINK(:StdType stdType
                          :StdIde stdIde
                          :List list :Stack);
\textbf{let} fastStack :Stack = stackLINK(:StdType stdType
                              :StdIde stdIde
                              :List list :Stack);
\textbf{Let} Kreditor = Kreditor(:StdType stdType 
                             :StdIde stdIde
                             :List list
                             :Stack stack);
\textbf{Let} Debitor = Debitor(:StdType stdType 
                           :StdIde stdIde
                           :List list
                           :Stack fastStack);
\textbf{let} kreditor :Kreditor = kreditorLINK(:StdType stdType 
                                      :StdIde stdIde
                                      :List list
                                      :Stack stack 
                                      :Kreditor);
\textbf{let} debitor :Debitor = debitorLINK(:StdType stdType 
                                   :StdIde stdIde
                                   :List list
                                   :Stack  fastStack 
                                   :Debitor);
\textbf{Let} Mandant = Mandant(:StdType stdType :StdIde stdIde
                      :List list 
                      :Stack stack 
                      fastStack 
                      :Debitor debitor 
                      :Kreditor kreditor);
\textbf{let} mandant :Mandant = mandantLINK(:StdType stdType
                                   :StdIde stdIde
                                   :List list
                                   :Stack stack
                                   :Stack fastStack
                                   :Debitor debitor
                                   :Kreditor kreditor 
                                   :Mandant);
\end{alltt}
\end{quote}

\noindent
Schon durch die ver"anderte Parameterliste von \textit{mandant} und
\textit{Mandant} wird der Unterschied zu Fall a deutlich: Schnittstelle
\textit{Mandant} und Modul \textit{mandant} sind transitiv sowohl von
\textit{stack} als auch von \textit{fastStack} abh"angig.  Der Typoperator
\textit{Mandant} mu"s zus"atzlich mit \textit{fastStack} parametrisiert werden,
und die Funktion \textit{mandantLINK} erfordert ebenfalls \textit{fastStack}
als weiteres Argument.  Zwar "andert sich am Schnittstellen- und Modulrumpf
nichts, der Typ"uberpr"ufer weist die "uber \textit{kreditor} und
\textit{debitor} referenzierbaren \textit{stack.T} jedoch als inkompatibel
zur"uck, da es sich einmal um \textit{stack.T}, im anderen Fall um
\textit{fastStack.T} handelt.  \bigskip

Aufbauend auf den Basisprimitiven der Sprache {\tlmin} zur Manipulation von
Sichtbarkeitsbereichen zeigt dieser Abschnitt, wie daraus das semantisch
reichhaltigere Konzept der Modulen und Schnittstellen aufgebaut werden kann.
Zwar kommt diese Abbildung nicht g"anzlich ohne Werkzeugunterst"utzung aus, es
sind jedoch zur Realisierung keine Eingriffe in das {\tlmin} Kernsystem
notwendig.  Die unterschiedlichen Bindemechanismen zeigen, welche Flexibilit"at
dem Programmierer in der Wahl seiner Programmkonfiguration, der
Zusammenstellung von "ubersetzten Einheiten, zur Verf"ugung steht.  Auch hier
ist allerdings eine Werkzeugunterst"utzung zum effizienten Arbeiten
unerl"a"slich.

\section{Umgebungen}
\label{sec_umgebung}
Umgebungen (\textit{environments}) sind ein weiteres Strukturierungsmittel.  In
Abgrenzung zu den Basisprimitiven aus Abschnitt \ref{sec_sichtbarkeitsbereiche}
sind Umgebungen auf einer h"oheren Ebene angesiedelt, beeinflussen jedoch
ebenfalls die Sichtbarkeit von Bezeichnern.  Sie gruppieren Softwareeinheiten
bzw.\ Namen, wie sie in Abschnitt \ref{sec_hoehere_strukturierungskonzepte}
modelliert werden, zu gr"o"seren Komplexen oder Systemen.  Diese Gruppen
k"onnen dazu benutzt werden, verschiedenen Entwicklern unterschiedliche Mengen
von Softwareeinheiten zur Verf"ugung zu stellen und damit die parallele
Softwareentwicklung zu unterst"utzen.  Sie k"onnen weiterhin dazu verwendet
werden, Gruppen nach unterschiedlichen semantischen Gesichtspunkten zu formen
und so die Komplexit"at eines gro"sen Softwaresystems zu beherrschen.

Eine Umgebung fa"st f"ur jeden in ihr abgelegten Wert die unterschiedlichen
beschreibenden Informationen und (Zwischen-) Repr"asentationen des Compilers
zusammen.  Ihre Datenstruktur zusammen mit entsprechenden Operationen sind
"uber die in Anhang \ref{cha_environment} gezeigte Schnittstelle erreichbar.
Sie sind nicht direkt Teil der Sprache {\tlmin}, k"onnen aber durch eine
Syntaxerweiterung mittels Schl"usselw"or\-tern angesprochen werden und dem
Programmierer den Eindruck vermitteln, da"s sie zur Sprache selbst geh"oren.
Umgebungen sind in {\tlmin} eine M"oglichkeit, Softwareeinheiten wie z.B.\ 
Module in gr"o"sere Einheiten zusammenzufassen und damit zu strukturieren.
F"ur den Compiler legen sie w"ahrend des "Ubersetzens die Menge an sichtbaren
Bezeichnern fest.  Sie "ubernehmen damit ebenfalls die Funktion der Toplevel in
{\tl} Systemen \cite{tycoon_po}, verfolgen jedoch einen allgemeineren Ansatz,
da sie die folgenden Eigenschaften aufweisen:

\begin{itemize}
\item Umgebungen k"onnen sowohl unver"anderliche als auch variable Bindungen
  enthalten.

\item Die Typinformation ist mit jedem Eintrag persistent abgelegt.  Dadurch
  entf"allt die Notwendigkeit, explizite Mechanismen f"ur dynamische Typen der
  in Umgebungen enthaltenen Bezeichner anzubieten.

\item 
\begin{sloppypar}
  Umgebungen k"onnen beliebig strukturiert werden.  Insbesondere sind
  Schachtelungen denkbar, die zu Strukturen "ahnlich denen eines
  Dateisystems f"uhren.  Dies folgt daraus, da"s Bindungen zwischen
  den Umgebungen aufgebaut werden k"onnen.
\end{sloppypar}

\item Komponenten k"onnen zwischen Umgebungen beliebig verschoben oder kopiert
  werden.  Namens"anderungen von Komponenten sind m"oglich und verletzen wie die
  vorgenannten Operationen Verschieben und Kopieren die Typsicherheit nicht.
\end{itemize}

\subsection{Aufbau}
Umgebungen werden im "Ubersetzer von der Phase der Typ"uberpr"ufung bis zur
Ausf"uhrung des virtuellen Maschinencodes in der Tycoon Maschine benutzt.  Sie
stellen erg"anzend zu den verschiedenen Zwischen- und Coderepr"asentationen
die Verbindung zwischen dem Compiler als statischer Komponente einerseits und
den aktuellen dynamischen Daten (Programme, Ausdr"ucke) andererseits her,
indem sie Informationen, wie z.B.\ den Typ von referenzierten Bezeichnern,
enthalten, auf die sich der "Ubersetzer w"ahrend des Transformationsvorganges
beziehen kann.  So wird im nachfolgenden Beispiel im zweiten Ausdruck Bezug
auf einen zuvor gebundenen Bezeichner \textit{a} genommen:

\begin{quote}
\begin{alltt}
\textbf{let} a = 42
\begin{math}\Rightarrow\end{math}\textsl{ 42 :Int}

\textbf{let} b = a * 2
\begin{math}\Rightarrow\end{math}\textsl{ 84 :Int}

\end{alltt}
\end{quote}

Der Compiler mu"s bei der semantischen Analyse des zweiten Ausdrucks
Typinformationen "uber verwendete Bezeichner, in diesem Fall das \textit{a}
und die Zahl \textit{2} bekommen, um die Korrektheit des Ausdrucks zusichern
zu k"onnen.  Bei der Zwischencode-Generierung ben"otigt der "Ubersetzer
Informationen "uber die Art, wie auf den Speicherplatz, der durch \textit{a}
repr"asentiert wird, zugegriffen wird.  So unterscheidet sich z.B.\ der
Zugriff auf eine Variable von der Anwendung einer Funktion.  Aus dieser
Kenntnis wird der entsprechende TML-Code generiert, der den Zugriff ausf"uhrt.
Der TML-Code dient der nachfolgenden Phase zur Erzeugung des von der virtuellen
Maschine ausf"uhrbaren Bytecodes.  Umgebungen dienen dazu, jeder Phase die
Information "uber bereits typgepr"ufte, zwischencodegenerierte oder
ausgef"uhrte Ausdr"ucke bereitzustellen, die sie zur Erledigung ihrer Ausgabe
ben"otigt.

Eine Umgebung setzt sich aus drei Teilkomponenten zusammen.

\begin{description}

\item[Typkomponente:] Sie umfa"st die Signaturen aller sichtbaren Bezeichner
  wie Funktionen, Variablen etc.  Unter Signaturen wird in diesem Zusammenhang
  die Repr"asentation dieser Signaturen im Syntaxbaum verstanden.  Konkret
  sind in der Typkomponente somit Verweise auf Teilsyntaxb"aume enthalten.

\item[Wertkomponente:] Die Codegenerierung "ubersetzt die Repr"asentation des
  Syntaxbaums in die Darstellung als TML-Baum. Die Knoten dieses Baums werden
  in der Wertkomponente abgelegt.

\item[Laufzeitkomponente:] Nach Erzeugung und Ausf"uhrung des TVM-Codes werden
  die evaluierten Werte in die Laufzeitkomponente eingetragen und stehen damit
  nachfolgenden Ausf"uh\-rungsschritten zur Verf"ugung.

\end{description}

Umgebungen erweitern damit das Konzept der Symboltabelle, wie Abbildung
\ref{abb_symboltab} in Anlehnung an Darstellung \ref{abb_compilerphasen} auf
Seite \pageref{abb_compilerphasen} und an entsprechende Darstellungen in
\cite{aho} verdeutlicht.  Zum einen enthalten sie Informationen von bereits
"ubersetzten Ausdr"ucken und Programmen und speichern diese dauerhaft.  Zum
anderen werden Umgebungen im {\tlmin} System auch zur Laufzeit ben"otigt, da
sie in der Laufzeitkomponente Verweise auf evaluierte Ausdr"ucke enthalten und
somit als Schnittstellen zu diesen fungieren.  Als zus"atzliche Erweiterung
gegen"uber normalen Symboltabellen kann das Konzept angesehen werden, da"s der
Compiler mit Umgebungen parametrisiert werden kann.  Das bedeutet, da"s ein
Ausdruck vom Compiler stets gegen eine bestimmte Umgebung "ubersetzt werden
mu"s und auch in Abh"angigkeit von der Umgebung verschiedene Ergebnisse 
errechnen kann.

\afterpage{%\clearpage
\begin{figure}[htb]
\centering\mbox{\epsfig{file=../Zeichnung/symboltab.eps}}
\caption{Compilerphasen mit Zwischenrepr"asentationen und Umgebung.}
\label{abb_symboltab}
\end{figure}
}

Konzeptuell fa"st eine Umgebung f"ur jeden Wert die entsprechende Information
des Compilers zusammen.  Umgebungen nehmen Bezeichner zusammen mit ihrer
Typinformation, ihrer Wertinformation\footnote{In dieser Arbeit wird der
  Begriff Wertkomponente benutzt, um die Massendatenstruktur zu beschreiben,
  die die vom Codegenerator erzeugten Knoten enth"alt.  Er ist abgeleitet vom
  Variablennamen \textit{valueEnv}, der in der Implementierung des {\tlmin}
  Compilers Verwendung findet.  Es sind auch andere Bezeichnungen, wie z.B.\ 
  Variablenkomponente, denkbar.  Die Belegung der in dieser Datenstruktur
  gespeicherten Objekte mit dem Begriff Wert scheint jedoch aus dem Grund
  angebracht, da es sich um Zugriffsbeschreibungen f"ur Werte (Literale,
  Funktionen usw.) handelt.} und der Laufzeitrepr"asentation auf.  Sie werden
vom Compiler sequentiell mit den errechneten Werten gef"ullt.  Bez"uglich des
"Ubersetzungsvorganges ergeben sich daraus einige Integrit"atsbedingungen, die
auf Umgebungen definiert sind.

\afterpage{%\clearpage
\begin{figure}[htb]
\centering\mbox{\epsfig{file=../Zeichnung/overlap.eps}}
\caption{"Uberlappende Aufrufe der Compilerschnittstelle.}
\label{abb_overlap}
\end{figure}
}

Der "Ubersetzungsvorgang wird durch die Compilerschnittstelle in mehrere
Funktionen aufgeteilt, deren Ergebnis in der entsprechenden
Zwischenrepr"asentation (s. Abbildungen \ref{abb_symboltab} und
\ref{abb_compilerphasen} auf Seite \pageref{abb_compilerphasen}) jeweils als
Argument des n"achsten Schrittes auftritt.  Die "Ubersetzung erfolgt dabei
jeweils gegen eine Umgebung, die ebenfalls als Parameter der Funktionen
auftritt.  Im Beispiel von Abbildung \ref{abb_overlap} ist dies die Umgebung
\textit{Aenv} f"ur den linken und \textit{Benv} f"ur den rechten
Ausf"uhrungsstrang.  Wie in Abbildung \ref{abb_overlap} ebenfalls zu sehen,
k"onnen sich die "Ubersetzungs\-schritte unterschiedlicher Ausdr"ucke durch
bestimmte Ausf"uhrungsreihenfolgen "uberlappen.  Die zur "Ubersetzung eines
Ausdruckes notwendigen Funktionsaufrufe werden nicht notwendigerweise
sequentiell ausgef"uhrt, sondern k"onnen mit den Funktionsaufrufen eines oder
mehrerer anderer "Ubersetzungs\-vorg"ange verzahnt sein\footnote{Die korrekte
  Reihenfolge der Funktionsaufrufe eines "Ubersetzungsvorganges ist dadurch
  gew"ahrleistet, da"s als Parameter jeweils das Funktionsergebnis des
  vorherigen Schrittes "ubergeben werden mu"s.  Die dar"uber hinaus korrekte
  Benutzung der "Ubersetzerfunktionen und die Bereitstellung der korrekten
  Argumente liegt in der Verantwortung des Programmierers.}.  So wird nach dem
Parsen des Ausdrucks \textit{A} (\textit{parse(A)}) zun"achst der Ausdruck
\textit{B} geparst, semantisch "uberpr"uft, in Zwischencode "ubersetzt und
virtueller Maschinencode generiert, bevor diese Schritte inklusive der
Ausf"uhrung auch f"ur den Ausdruck \textit{A} durchgef"uhrt werden.  Dennoch
k"onnen sich diese Vorg"ange auf nur eine Umgebung beziehen.  Eine Umgebung
mu"s sich in einem solchen Fall nach jedem "Ubersetzungsschritt in einem
konsistenten Zustand befinden; d.h., obwohl die Umgebung sequentiell gef"ullt
wird, m"ussen die Einzelkomponenten eines Wertes jeweils zuordenbar sein.

\subsection{Anwendungen}
Einsatzm"og\-lichkeiten von Umgebungen ergeben sich in erster Linie aus den
beschriebenen Anwendungen als "uber den Basisprimitiven angesiedeltes
Strukturierungsmittel und durch die erweiterte Sicht als Symboltabelle als
Compilerhilfsmittel.  Auch in Zusammenhang mit der Verwirklichung von (grafisch
unterst"utzten) Entwicklungsumgebungen und der Realisierung einer
teamorientierten Entwicklungsunterst"utzung ergeben sich f"ur Umgebungen
insbesondere in Verbindung mit der Compilerschnittstelle (s.\ Abschnitt
\ref{sec_compilerschnittstelle}) weitere Anwendungsm"oglichkeiten.

Die grundlegenden Funktionen auf Umgebungen k"onnen der Schnittstelle in
Anhang \ref{cha_environment} entnommen werden.  Grunds"atzlich k"onnen neue
Eintr"age auf zwei unterschiedliche Arten in eine Umgebung gelangen:

\begin{itemize}
\item Durch "Ubersetzen eines Ausdruckes tr"agt der Compiler die von ihm
  generierten Objekte in die als Parameter "ubergebene Umgebung ein.

\item Bereits vorhandene Bezeichner werden von einer Umgebung in eine weitere
  kopiert oder verschoben.
\end{itemize}

Mit Umgebungen lassen sich hierarchische oder andere azyklische Strukturen
aufbauen.  Die in Abbildung \ref{abb_environment} dargestellte Situation wird
durch die folgenden Anweisungen erreicht.

\begin{quote}
\begin{alltt}
\textbf{let} root = environment.new()
\end{alltt}
\end{quote}

\noindent
Die weiteren Anweisungen werden in der zuvor erzeugten Umgebung \textit{root}
"ubersetzt.  Dazu wird die Existenz einer Funktion \textit{compileString}
angenommen, die die in Abschnitt \ref{sec_compilerschnittstelle} beschriebenen
Funktionen der Compilerschnittstelle mit der als Argument "ubergebenen Umgebung
aufruft und als Ergebnis die um die entsprechende Bindung erweiterte Umgebung
zur"uckliefert.

\begin{quote}
\begin{alltt}
\textbf{let} root = compileString("let standard = environment.new()"
                         root)
\textbf{let} root = compileString("let bulk = environment.new()"  
                         root)
\textbf{let} root = compileString("let graphic = environment.new()"  
                         root)
\end{alltt}
\end{quote}

Weitere Freiheitsgrade erh"alt der Programmierer dadurch, da"s
Komponenten einer Umgebung umstrukturiert werden k"onnen.  So sind die
Umgebungen \textit{standard}, \textit{graphic} und \textit{bulk} in der
Umgebung \textit{root} enthalten.  Sie treten dort als Bindungen auf, deren
Wert vom Typ \textit{environment.T} (s.\ Anhang \ref{cha_environment}) ist.
%Da
%Bezeichner in Umgebungen enthalten sein m"ussen und Umgebungen wiederum als
%Namen in Umgebungen auftreten, mu"s es eine Art initiale vom Compiler
%verwaltete Umgebung geben.  Diese wird im {\tlmin} System realisiert, indem
%bevor die Compiler- und Umgebungsschnittstelle sichtbar gemacht werden, auf
%eine interaktive Kommandoschnittstelle zur"uckgegriffen wird, die intern eine
%Umgebung verwaltet.  Auf diese Weise lassen sich auf der Kommandoschnittstelle
%Ausdr"ucke angeben, die vom Compiler "ubersetzt werden und deren Bindungen in
%der Umgebung abgelegt werden. "Uber spezielle Anweisungen der Kommandosprache
%ist es m"oglich, diese initiale Umgebung auszutauschen.
%Alle weiteren Umgebungen sind normale Bindungen auf der interaktiven
%Kommandoschnittstelle oder in anderen Umgebungen.  Die initiale Umgebung ist in
%den Abbildungen \ref{abb_environment} und \ref{abb_parallel} implizit vorhanden
%und enth"alt alle nicht in anderen Umgebungen enthaltenen Umgebungen.

%\afterpage{\clearpage
\begin{figure}[htb]
\centering\mbox{\epsfig{file=../Zeichnung/environment.eps}}
\caption{Baumartige Struktur von Umgebungen.}
\label{abb_environment}
\end{figure}
%}

Im {\tlmin} System k"onnen durch Erzeugen entsprechender Bindungen mehrere
parallele Umgebungen gehalten werden (s.\ Abbildung \ref{abb_parallel}).  F"ur
solche Situationen ist es w"unschenswert, einzelne Komponenten aus einer
Umgebung herausl"osen und in eine weitere wiedereingliedern zu k"onnen.
Denkbar ist ein Szenario, in dem ein Systemprogrammierer in der Umgebung
\textit{root} entwickelt und einem Anwendungsentwickler fertige Komponenten in
der Umgebung \textit{user} zur Verf"ugung stellt.  Folgende Operation kopiert
den Bezeichner \textit{set} aus der Umgebung \textit{bulk} in die Umgebung
\textit{user}:

\begin{quote}
\begin{alltt}
\textbf{let} user = environment.copyBinding(bulk user "set")
\end{alltt}
\end{quote}

\noindent
In der Umgebung \textit{user} ist nun tats"achlich nur der Bezeichner
\textit{set} sichtbar, obwohl zu dessen Erzeugung, insbesondere dessen
semantischer "Uberpr"ufung, auch andere Bezeichner notwendig waren.  Dies ist
vor dem Benutzer der Umgebung \textit{user} verborgen.  Er kann jedoch Code
entwickeln, der auf \textit{set} aufbaut.

Durch eine gleichzeitige oder sp"atere Umbenennung des Bezeichners \textit{set}
erh"alt der Programmierer weitere Kontrolle an die Hand.  Wird z.B.\ in der
Umgebung \textit{user} eine andere Namenskonvention verfolgt, als das in der
Umgebung \textit{bulk} der Fall ist, so kann \textit{set} auf diese Weise
angepa"st werden:

\begin{quote}
\begin{alltt}
\textbf{let} user = environment.copyBindingAs(bulk user 
               "set" "Massendaten_Menge")
\end{alltt}
\end{quote}

Da Objektreferenzen zwischen den Komponenten von den Manipulationen innerhalb
der Umgebungen unber"uhrt bleiben, ist es nicht notwendig, da"s der
Programmierer alle zur "Uberset\-zung notwendigen Komponenten kopiert.  Nur die
Komponenten, die der Benutzer tats"achlich sehen soll, m"ussen kopiert werden.
Auf der Ebene der Objektreferenzen ergibt sich damit die in Abbildung
\ref{abb_envoid} dargestellte Situation, die am Beispiel der Komponente
\textit{set} und der beiden Umgebungen \textit{bulk} und \textit{user}
verdeutlicht, da"s innerhalb der Umgebungen nur Verweise auf die eigentlichen
Objekte abgelegt sind.

%\afterpage{\clearpage
\begin{figure}[H]
\centering\mbox{\epsfig{file=../Zeichnung/envoid.eps}}
\caption{Zusammenhang zwischen Umgebungen und Objektreferenzen.}
\label{abb_envoid}
\end{figure}
%}

In Zusammenhang mit den in Abschnitt \ref{sec_hoehere_strukturierungskonzepte}
und folgende vorgestellten Syntaxerweiterungen f"ur Module und Schnittstellen
und deren werkzeugm"a"sige Unterst"utzung ergibt sich an dieser Stelle eine
Schwierigkeit.  Zur Umsetzung der dort vorgestellten Syntax f"ur Schnittstellen
und Module m"ussen alle transitiv erreichbaren Bezeichner gefunden und als
Parameter verf"ugbar sein.  Dies ist, wenn sich nur das benutzte Modul in einer
Umgebung befindet, nicht der Fall.  Dieser Vorgang k"onnte von einem Werkzeug
durchgef"uhrt werden, welches die erforderlichen Bezeichner ggf.\ nach
bestimmten Regeln in anderen Umgebungen aufsucht.  F"ur den "Ubersetzer stehen
diese jedoch noch nicht zur Verf"ugung, da er immer nur mit einer Umgebung
parametrisiert wird, die Namen und die zugeh"origen Informationen und
Repr"asentationen aber in unterschiedlichen Umgebungen vorliegen.  Die L"osung
kann darin bestehen, die "Ubersetzung in einer weiteren (tempor"aren) Umgebung
durchzuf"uhren, die alle notwendigen Bezeichner enth"alt.  Nach Abschlu"s des
"Ubersetzungsvorganges wird der gew"unschte Bezeichner in die entsprechende
Ziel\-umgebung kopiert.  Die tempor"are Umgebung kann f"ur weitere
"Ubersetzungsvorg"ange erhalten bleiben.

Weiterhin ist beachtenswert, da"s die "Ubersetzung von Ausdr"ucken, die
innerhalb ihrer Originalumgebung\footnote{Hiermit ist die Umgebung gemeint, in
  der der entsprechende Ausdruck "ubersetzt wurde.} ge"andert werden, durch
verschobene Bezeichner nicht reproduzierbar werden kann. Durch die folgende
Anweisung und eine angenommene Abh"angigkeit des Moduls \textit{bag} von dem
Modul \textit{set} kann ersteres nach einer "Anderung nicht erneut "ubersetzt
werden.

\begin{quote}
\begin{alltt}
\textbf{let} user = environment.moveBinding(bulk user "set")
\end{alltt}
\end{quote}

\noindent
Dennoch bleibt das nicht ge"anderte Modul \textit{bag} weiterhin
funktionsf"ahig, was auf die Verwendung von Objektreferenzen zur"uckzuf"uhren
ist.

\noindent
%\afterpage{\clearpage
\begin{figure}[H]
\centering\mbox{\epsfig{file=../Zeichnung/parallel.eps}}
\caption{Operationen zwischen parallelen Umgebungen.}
\label{abb_parallel}
\end{figure}
%}

Die Ausf"uhrungen zu Umgebungen beziehen sich auf ein Szenario, in dem sich
alle Operationen in einem Objektspeicher abspielen, d.h.\ Bezeichner, die von
einer Umgebung in eine andere kopiert bzw. verschoben werden, verbleiben im
selben Objektspeicher.  Zus"atzliche Dynamik erh"alt dieses Szenario jedoch
durch die Verwendung von unterschiedlichen Instanzen eines Tycoon Systems und
somit Objektspeichern und in Zusammenhang mit Netzwerkreferenzen \cite{ramme},
was in dieser Arbeit jedoch nicht betrachtet wird.  Insbesondere die
Entwicklung von Software durch mehrere Programmierer in einem Team kann
hierdurch profitieren.


\section{Anwendungsszenario}
\label{sec_anwendungsszenario}
In diesem Abschnitt werden die bislang getrennt vorgestellten Konzepte und
Mechanismen in einen gr"o"seren Zusammenhang ger"uckt.  Dabei soll das
Hauptaugenmerk auf das Zusammenspiel von Werkzeugen, wie die Modulverwaltung auf
der obersten Ebene, Compilerschnittstelle und Umgebungen auf einer
darunterliegenden Ebene und Basisprimitiven zur Systemstrukturierung und daraus
kombinierte h"ohere Konzepte auf der untersten Ebene gerichtet werden.

Das Ziel dieser Arbeit ist es, die in Kapitel \ref{cha_einleitung} formulierten
Prinzipien zu unterst"utzen.  Unterst"utzung zur Erreichung dieses Ziels wird
einerseits durch Strukturierungsprimitive (Abschnitt \ref{subsec_block} bis
\ref{subsec_import}) in der Programmiersprache und andererseits durch Werkzeuge
(Abschnitt \ref{sec_modulverwaltung}) bereitgestellt.  Die
Strukturierungsprimitive sind so gew"ahlt, da"s sich durch Kombination neue,
semantisch reichhaltigere Strukturierungsmechanismen aufbauen lassen.  In
dieser Arbeit sind dies Module und Schnittstellen (Abschnitt
\ref{subsec_schnittstellen} und \ref{subsec_module}).

Ein Entwickler kann sein Programm in Module und Schnittstellen zerlegen und
diese unabh"angig voneinander entwickeln und implementieren, da sie separat
"ubersetzbar sind.  Er wird damit direkt bei der Erreichung der Prinzipien
Abstraktion, Strukturierung, Modularisierung und Wiederverwendbarkeit
unterst"utzt.  Durch die Formulierung der Module und Schnittstellen wird z.B.\ 
f"ur die importierten Bezeichner das Prinzip Lokalit"at erreicht.
Hierarchisierung, in diesem Fall speziell in der Form eines azyklischen,
gerichteten Graphen, wird durch die nicht wechselseitig zugelassenen
Importbeziehungen erreicht.  Unterst"utzung bei der Formulierung der Module und
Schnittstellen, insbesondere bei der Ermittlung der transitiven Importe,
erh"alt der Programmierer durch die Modulverwaltung auf Werkzeugebene.

Zur Verwaltung der Module und Schnittstellen und zum "Ubersetzen, Binden und
Ausf"uhren stehen der Modulverwaltung die Compilerschnittstelle (Abschnitt
\ref{sec_compilerschnittstelle}) und die Schnittstelle zu Umgebungen
(Abschnitt \ref{sec_umgebung}) zur Verf"ugung.  Sie stellen das Bindeglied
zwischen der Modulverwaltung, die als Anwendungsprogramm abl"auft, und dem
{\tlmin} System dar, welches dar"uber bestimmte Dienste anbietet.

Die Modulverwaltung bietet dem Programmierer "uber entsprechende Funktionen den
Dienst an, f"ur Module und Schnittstellen die (transitiven) Importe zu
ermitteln und sie anschlie"send in Abh"angigkeit dieser Importe zu "ubersetzen
und zu binden.  Beim Binden stehen verschiedene Optionen f"ur die Konfiguration
von Modulen und Schnittstellen zur Verf"ugung (Abschnitt \ref{subsec_binden}),
die es dem Entwickler z.B.\ erlauben, Module nicht nur mit Modulen
zusammenzubinden, die den gleichen Namen, wie die in der Importliste
erw"ahnten, besitzen.  Vielmehr l"a"st sich ein Modul mit beliebigen Modulen
und Schnittstellen zusammenbinden, die dem entsprechenden Typ bzw.\ einem
Subtyp gen"ugen, wobei Einschr"ankungen beim Datenaustausch zwischen abstrakten
Datentypen hingenommen werden m"ussen (Abschnitt \ref{subsec_rautenimport}).

Die Modulverwaltung ist weiterhin in der Lage, die Module und Schnittstellen in
gr"o"seren Einheiten, Umgebungen, zu verwalten (Abschnitt \ref{sec_umgebung}).
Diese kann ein einzelner Programmierer zur Strukturierung seiner
Softwareeinheiten einsetzen.  Mehrere Programmierer eines Teams k"onnen "uber
Umgebungen ihre Module und Schnittstellen austauschen.

\section{Zusammenfassung}
In diesem Kapitel werden Strukturierungsmechanismen vorgestellt, die einerseits
in der Sprache {\tlmin} eingebaut sind, andererseits als Dienst "uber eine
Schnittstelle angeboten werden.  Sie bieten im Vergleich zu den in Kapitel
\ref{cha_strukturierung} vorgestellten und bewerteten Mechanismen, die fest in
Programmiersprachen integriert sind, ein h"oheres Ma"s an Flexibilit"at in
bezug auf ihre Kombinierbarkeit und damit auch auf ihre Einsatzm"oglichkeiten.

Die zur Verf"ugung stehenden orthogonal kombinierbaren Operationen zur
Manipulation von Namensr"aumen bzw.\ Sichtbarkeitsbereichen erlauben es, eine
gro"se Zahl von weiteren h"oheren Konzepten aufzubauen.  Der in {\tlmin}
gew"ahlte Ansatz unterscheidet sich hierdurch grundlegend von denen in Kapitel
\ref{cha_strukturierung}, da keine Konzepte wie Module oder Klassen fest in die
Sprache integriert sind, sondern aus den Basisprimitiven aufgebaut werden.  Das
l"a"st die Option offen, das {\tlmin} System durch eine Syntaxerweiterung
dergestalt um Schl"usselw"orter zu erg"anzen, da"s die
Strukturierungsmechanismen einfach, effizient, d.h.\ unter Vermeidung von
Fehlern und Schreibaufwand benutzt werden.  F"ur den vorgestellten Fall der
Module und Schnittstellen ist, wie in Abschnitt \ref{sec_anwendungsszenario}
gezeigt, weiterhin eine Werkzeugunterst"utzung zum praktischen Einsatz
empfehlenswert, da die transitiven Importe nicht allein aus der Syntax
hervorgehen.  Folglich ist ein {\tlmin} Basissystem ohne Erweiterung und
erg"anzende Werkzeuge nur bedingt als Programmiersprache f"ur gro"se Systeme
geeignet, sondern sollte, wie in Abschnitt
\ref{sec_hoehere_strukturierungskonzepte} gezeigt, durch Abbildungen
von Syntaxerweiterungen auf die Basissprache angepa"st werden.  Dies kann
sehr flexibel und ohne Verlust der Kompatibilit"at des erzeugten
Codes und der erzeugten Zwischenrepr"asentationen des Compilers geschehen.

In bezug auf Werkzeugunterst"utzung und syntaktische Erweiterungen gilt
Gesagtes auch f"ur Umgebungen.  Sie m"ussen durch zus"atzliche, dem
Anwendungsfall angepa"ste, syntaktische Konstrukte verf"ugbar gemacht werden,
und ihre Verwendung sollte mit Hilfe von Werkzeugen erfolgen.  Umgebungen
erf"ullen jedoch noch eine weitere Aufgabe, indem sie "uber bereits bestehende
Softwareeinheiten eine Verwaltung anbieten, wie sie auch in \cite{booch}
gefordert wird.  Umgebungen unterst"utzen damit zwei Aspekte der Entwicklung
gro"ser Softwaresysteme:

\begin{itemize}
\item Programmieren in Teams mehrerer Entwickler durch Zuteilung 
unterschiedlicher Umgebungen mit der M"oglichkeit des gegenseitigen Austauschs
von Softwareeinheiten.

\item Parametrisieren des "Ubersetzungsvorganges, indem dem Compiler durch eine
Umgebung eine Menge an Namen inklusive der damit verbundenen beschreibenden
Information und Repr"asentationen "ubergeben wird, gegen die er die "Ubersetzung        durchf"uhrt.
\end{itemize}

Die Flexibilit"at der vorgestellten Ans"atze zeigt, da"s diese durch
Werkzeuge unterst"utzt werden m"ussen, damit sie effizient und sicher genutzt
werden k"onnen.  Als Beispiel sei auf die in Abschnitt
\ref{subsec_rautenimport} beschriebene M"oglichkeiten zur
Programmkonfiguration verwiesen, die es erlauben, Module ohne Neu"ubersetzung
umzukonfigurieren.  Hierzu wird in Abschnitt \ref{sec_modulverwaltung}
ein Ansatz vorgestellt, der die allgemeine Anbindung eines solchen
Werkzeugs darstellt.  Abschlie"send kann festgehalten werden, da"s durch die
Aufnahme von Operationen zur Manipulation von Sichtbarkeitsbereichen in die
Sprache {\tlmin} und durch die auf h"oherer Ebene angesiedelten Umgebungen dem
Programmierer M"oglichkeiten zur Systemstrukturierung an die Hand
gegeben werden.

