summaryrefslogtreecommitdiff
path: root/doc/user-manual/1.7.3-pd
diff options
context:
space:
mode:
Diffstat (limited to 'doc/user-manual/1.7.3-pd')
-rw-r--r--doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil1924
-rw-r--r--doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil10771
-rw-r--r--doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil111072
-rw-r--r--doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil12234
-rw-r--r--doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil2628
-rw-r--r--doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil32097
-rw-r--r--doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil42306
-rw-r--r--doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil5667
-rw-r--r--doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil6a1590
-rw-r--r--doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil6b1425
-rw-r--r--doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil72469
-rw-r--r--doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil81345
-rw-r--r--doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil9936
-rw-r--r--doc/user-manual/1.7.3-pd/doc/source-disk1
14 files changed, 16465 insertions, 0 deletions
diff --git a/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil1 b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil1
new file mode 100644
index 0000000..cdeca13
--- /dev/null
+++ b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil1
@@ -0,0 +1,924 @@
+ EUMEL-Benutzerhandbuch
+
+ TEIL 1: Einführung
+
+Vorwort
+
+Lieber EUMEL-Nutzer!
+
+Ihnen liegt hier das EUMEL-Benutzerhandbuch zur Public-Domain-Version 1.7.3
+vor. Es gliedert sich in mehrere Teile. Der erste Teil des Benutzerhandbuchs
+soll dem zukünftigen Benutzer den "Einstieg" in das EUMEL-System erleichtern.
+Dazu werden die wichtigsten Eigenschaften des EUMEL-Systems vorgestellt.
+Danach zeigen wir eine Beispielsitzung. Anschließend werden einige
+prinzipielle Konzepte des EUMEL-Systems vermittelt. Den Abschluß bildet ein
+kleines EUMEL-Wörterbuch.
+
+Die übrigen Teile des EUMEL-Benutzerhandbuchs dokumentieren jeweils ein oder
+mehrere abgeschlossene Einheiten des Systems. Ein EUMEL-Nutzer braucht so nur
+die ihn interessierenden Teile zu lesen. Ein Programmierer z.B. sollte
+
+ Einführung, Supervisor/Monitor, Editor, ELAN-Compiler und Dateien
+
+durcharbeiten. Für Programmierer, die noch keine Erfahrung mit ELAN besitzen,
+ist der Teil "Erste Hilfe" gedacht. Weiterhin werden die Teile über Dateien
+und Standardpakete oft benötigt. Ein Nutzer, der vorwiegend an der Textbe-
+und verarbeitung interessiert ist, braucht dagegen nur
+
+ Einführung, Supervisor/Monitor, Dateien, Editor und Textkosmetik.
+
+Der OPERATOR/Spooler-Teil ist nur für diejenigen Programmierer gedacht, die
+ein EUMEL-System betreuen. Weitere Informationen finden System-Programmierer
+im System-Handbuch bzw. in der Veröffentlichung des Quellcodes.
+
+
+1. Eigenschaften des EUMEL-Betriebssystems
+
+Das EUMEL-Betriebssystem (Extendable multi User Microprocessor ELANsystem)
+ist ein Betriebssystem, das z.Z. für den Einsatz auf Mikroprozessoren vorge-
+sehen ist. Es weist u.a. folgende Eigenschaften auf:
+
+- Das EUMEL-System ist ein "Time sharing"-Betriebssystem, d.h. mehrere Be-
+ nutzer können gleichzeitig an einem Rechensystem arbeiten (z.B. Programme
+ übersetzen, bearbetten (rechnen) oder erstellen (edieren)). Dabei wird die
+ verfügbare Rechen- und Speicherkapazität zwischen den Benutzer-Prozessen
+ dynamisch aufgeteilt.
+
+- Jeder Benutzer richtet (mindestens) eine Task ein, in der er sich Programme
+ und/oder Dateien halten kann, auf die andere Nutzer nicht zugreifen können.
+ Tasks können von einem Terminal "abgekoppelt" und trotzdem - sofern aus-
+ reichend freie Rechnerkapazität zur Verfügung steht - als Batch-Auftrag im
+ Hintergrund weiter bearbeitet werden.
+
+- Das EUMEL-Betriebssystem ist so konzipiert, daß der Sicherheit des Systems
+ besondere Beachtung geschenkt wurde. Zu diesem Zweck werden in bestimmten
+ zeitlichen Abständen sogenannte Restart-Punkte auf dem externen Speicher-
+ medium gesichert. In diesen Sicherungen wird der augenblickliche System-
+ Zustand konserviert, so daß bei Netzausfall oder eventuellen System-Zu-
+ sammenbrüchen der Betrieb übergangslos wieder aufgenommen werden kann, mit
+ der Ausnahme des Verlustes der Daten, die nach dem letzten Restart-Punkt
+ aufliefen.
+
+- "Tasks" und/oder Dateien können vor dem unbefugten Zugriff durch "Pass-
+ words" geschützt werden. Ein weitergehender Schutz wird durch die Möglich-
+ keit von Password-Algorithmen vom EUMEL-System angeboten, so daß den Be-
+ langen des Datenschutzes Rechnung getragen werden kann.
+
+- Das EUMEL-Betriebssystem ist leicht erweiterbar. Da der Kern des Betriebs-
+ systems in ELAN geschrieben ist, können Anwender selbst leicht Erweiterun-
+ gen bzw. lokale Modifikationen in das System ein- bzw. anfügen. Dabei kön-
+ nen bestimmte Erweiterungen nur bestimmten Benutzern oder Benutzergruppen
+ zur Verfügung gestellt werden. Da die Programmiersprache ELAN selbst er-
+ weiterbar ist, ist es möglich, verschiedenen Anwendern oder -gruppen unter-
+ schiedliche Erweiterungen der Sprache anzubieten.
+
+- In dem EUMEL-Betriebssystem ist eine implizite Dateihierarchie realisiert.
+ Dies wird erreicht, indem den Tasks Dateien zugeordnet werden. Man kann
+ Dateien im Taskbaum von "Vater-Tasks" holen oder zu ihnen schicken. Lokale
+ Dateien werden mit dem Beenden einer Task automatisch gelöscht, während
+ Dateien, die längerfristig gehalten werden sollen, bei längerlebenden Tasks
+ gehalten werden müssen.
+
+- Die Kommandosprache ("job control language") des EUMEL-Systems entspricht
+ der ELAN-Syntax (Prozeduraufrufe). Das befreit den Anwender von der
+ Schwierigkeit, zwei verschiedenartige Sprachen zu erlernen. Darüber hinaus
+ können eine oder mehrere Anweisungen der Kommandosprache in ELAN-Programmen
+ enthalten sein. Z.B. ist es möglich, Kommandos vom Editor ausführen zu
+ lassen oder den Editor von einem Programm aus aufzurufen.
+
+- Die Dienstprogramme des EUMEL-Systems, wie z.B. der EUMEL-Editor, sind
+ geräteunabhängig und meist erweiterbar konzipiert. Zudem sind sie auch in
+ ELAN formuliert, so daß Änderungen und Korrekturen leicht vorgenommen
+ werden können.
+
+- Das EUMEL-System verwaltet seinen Hauptspeicher nach dem "demand-paging"-
+ Prinzip. Daten und/oder Programme werden daher in Seiten von 512 Bytes
+ aufgeteilt. Nur diejenigen Seiten, die zu einem Zeitpunkt wirklich benötigt
+ werden, befinden sich im Speicher. Dadurch kann sich das EUMEL-System auf
+ wechselnde Speicherplatz-Anforderungen optimal einstellen.
+
+- Für alle Programme wird reentranter Code erzeugt. Somit können mehrere
+ Benutzer Code gleichzeitig benutzen ("sharable code"), wobei der Code nur
+ einmal vorhanden sein muß. Dies ist insbesondere für Dienstprogramme wie
+ z.B. Compiler, Editor usw. wichtig.
+
+- Dateien können ebenfalls (wie Programme) von mehreren Benutzern gemeinsam
+ verwendet werden, ohne daß mehrere Kopien davon hergestellt werden müssen
+ Das System sorgt mit seinen Paging-Fähigkeiten automatisch für das "sharen"
+ von Dateien. Erfolgt jedoch ein Schreibzugriff, so wird nur für den
+ schreibenden Benutzer eine Kopie angelegt.
+
+- Das EUMEL-System bietet gute Textbe- und -verarbeitungsmöglichkeiten.
+ Grundlage dafür ist der bildschirmorientierte Editor (eine Entwicklung der
+ GMD). Der Editor erlaubt auch ein "multi window editing" und die Ausführung
+ von beliebigen Kommandos. Zusätzlich gibt es eine Reihe von Programmen zur
+ "Textkosmetik", die es erlauben, Texte zeilen- und seitenweise zu forma-
+ tieren. Dabei ist es möglich, unterschiedliche Schriftarten zu verwenden.
+
+
+2. Eine kleine Beispielsitzung mit EUMEL
+
+Zum ersten Kennenlernen wird hier ein Beispiel einer EUMEL-Sitzung darge-
+stellt. Diese Vorlage kann man am Rechner "nachspielen". Da die Reaktion des
+Systems hier auf dem Papier nur unvollkommen wiedergegeben werden kann, ist
+diese Beispielsitzung durch "trockenes" Lesen (ohne Rechner) sicherlich etwas
+schwieriger zu verstehen als durch Nachspielen.
+
+Alle Ausgaben des EUMEL werden mit
+
+---->
+
+gekennzeichnet, alle Benutzereingaben haben
+
+<----
+
+als Kennzeichen. Spezielle Tasten werden groß geschrieben, z.B.
+
+ RETURN
+
+als Bezeichnung für die RETURN-Taste.
+
+
+Anfang
+
+Im Multi-User-System können gleichzeitig mehrere Benutzer aktiv sein. Dabei
+braucht jeder ein eigenes "Zimmer" im "EUMEL-Haus", in dem er arbeiten kann,
+ohne andere zu stören. Diese "Zimmer" heißen hier "Tasks" und haben Namen.
+Zu Beginn muß der Benutzer sich an seinem Bildschirm eine Task erzeugen. Dazu
+muß er das Betriebssystem aktivieren:
+
+<---- SV
+
+EUMEL meldet sich: EUMEL Version 1.7.3/M
+
+----> gib supervisor kommando:
+
+Dann muß der Benutzer sich einen Tasknamen ausdenken (z.B. "ottokar") und
+ein Kommando zum Einrichten einer neuen Task geben:
+
+<---- begin ("ottokar") RETURN
+
+Daraufhin wird eine neue Task erzeugt, sie meldet sich:
+
+----> gib kommando:
+
+Jetzt kann die eigentliche Sitzung beginnen.
+
+
+Programm erstellen
+
+Wir schreiben ein kleines Programm zur Primzahlberechnung:
+
+<---- edit ("prim") RETURN
+
+----> neue datei einrichten (j/n) ?
+
+<---- j
+
+Es soll eine neue Datei mit dem Namen 'prim' eingerichtet werden, daher ant-
+worten wir mit 'j'. Die Datei ist zu Anfang leer. Der Editor zeigt nur die
+Überschrift, der restliche Bildschirm ist leer. Wir können jetzt unser Pro-
+gramm eingeben:
+
+ INT VAR zahl := 3 ;
+ WHILE zahl <= 1000 REP
+ drucke falls primzahl ;
+ zahl INCR 2
+ PER .
+
+ drucke falls primzahl :
+ INT VAR teiler := 3 ;
+ WHILE teiler * teiler <= zahl REP
+ IF teiler gefunden
+ THEN LEAVE drucke falls primzahl
+ FI ;
+ teiler INCR 2
+ PER ;
+ put (zahl) ;
+ line .
+
+ teiler gefunden :
+ zahl MOD teiler = 0 .
+
+Bei der Eingabe des Programms können wir auch die Funktionstasten benutzen.
+Die genauen Funktionen sind in den folgenden Teilen des Benutzerhandbuchs
+erklärt. Für den Anfang gilt aber: Probieren geht über Studieren!
+
+Wir verlassen den Editor:
+
+<---- ESC q
+
+----> gib kommando:
+
+
+Programm übersetzen und ausführen
+
+<---- run RETURN
+
+----> ("prim")
+
+Der Dateiname ('prim') wird automatisch ergänzt und das Programm wird vom
+ELAN-Compiler übersetzt. Dabei erscheinen die Nummern der gerade übersetzten
+Zeilen in der linken unteren Bildecke. Wenn keine Fehler gefunden wurden,
+wird das Programm anschließend ausgeführt. Dann sollten die Primzahlen von
+3 bis 1000 erscheinen.
+
+
+Ein fehlerhaftes Programm korrigieren
+
+Falls der ELAN-Compiler Fehler findet, wird das Programm nicht ausgeführt.
+Das System geht automatisch in den Editor, der jetzt zwei Dateien "parallel"
+auf dem Bildschirm zeigt. Die obere enthält die Fehlermeldungen, die untere
+das ELAN-Programm, so daß Korrekturen leicht möglich sind. Dabei kann man gut
+folgende Editor-Funktionen benutzen (ausprobieren!):
+
+ ESC ESC n RETURN positioniert auf Zeile n
+
+ HOP UNTEN
+ zum Blättern
+ HOP OBEN
+
+ ESC w wechselt zur jeweils anderen Datei (z.B. um in der
+ Fehlermeldungsdatei weiterzublättern)
+
+Nach Verlassen des Editors (ESC q) kann das Programm wieder gestartet werden.
+
+
+Ändern des Programms
+
+<---- edit RETURN
+
+----> ("prim")
+
+Auch hier wird der Dateiname zum Kommando 'edit' automatisch ergänzt. Jetzt
+kann das Programm mit den üblichen Editor-Möglichkeiten verändert werden.
+Vorschläge:
+
+ - Man ändere den Bereich (Vorsicht: maxint ist 32767).
+ - Man teste die Teiler bis zur Zahl selbst hoch.
+ - Man benutze REALs anstelle von INTs.
+ - Man suche Zwillinge.
+
+An Editor-Möglichkeiten könnte man ausprobieren:
+
+ RUBOUT löscht ein Zeichen.
+
+ RUBIN schaltet den Einfügezustand ein. Das nächste RUBIN
+ schaltet ihn wieder ab.
+
+ HOP UNTEN zum Anfang des Bildschirms oder "blättern nach oben".
+
+ HOP OBEN zum Ende des Bildschirms oder "blättern nach unten".
+
+ HOP RUBOUT am Zeilenanfang löscht die ganze Zeile.
+
+ HOP RUBIN schaltet "Zeilen einfügen" ein. Das nächste HOP RUBIN
+ schaltet es wieder aus.
+
+
+Datei löschen
+
+<---- forget RETURN
+
+----> ("prim")
+
+----> löschen (j/n) ?
+
+<---- j
+
+----> gib kommando:
+
+
+Ende einer Sitzung
+
+<---- end RETURN
+
+----> task loeschen (j/n) ?
+
+<---- j
+
+----> EUMEL Version 1.7.3 / M
+
+
+
+3. Einige Eigenschaften des EUMEL-Systems
+
+In diesem Abschnitt werden wir einige Eigenschaften des EUMEL-Systems
+schildern, die zum korrekten Arbeiten mit dem System wichtig sind. Um das
+Verständnis zu erleichtern, verwenden wir für einige System-Eigenschaften
+Modelle, die das Verhalten des Systems an typischen Merkmalen widerspiegeln
+spiegeln sollen, die aber - wie bei allen Modellen - kein exaktes Abbild
+darstellen.
+
+
+Tasks, Supervisor und Monitor
+
+Zuerst versuchen wir zu erklären, wie sich ein Benutzer im EUMEL-System
+anmeldet und den Mechanismus, wie man bestimmte Leistungen vom System
+anfordert (Einige Ideen dieses ersten Abschnittes gehen auf W. Ambros,
+Rhein-Sieg Gymnasium, St. Augustin, zurück).
+
+Stellen wir uns das EUMEL-System als ein riesiges Verwaltungsgebäude vor,
+wie es in unseren Städten in den letzten Jahren überall gebaut wurde. Ein
+Verwaltungsangestellter beginnt frohgemut seinen ersten Arbeitstag. Da das
+Gebäude so riesig ist, kann er sein Zimmer nicht finden. Aber er ist pfiffig:
+er fragt einfach den freundlichen Pförtner, der ihn in sein Zimmer führt.
+
+So ist es im EUMEL-System:
+Wenn man eine Arbeit neu beginnen will, muß man sich beim Supervisor (das ist
+der Pförtner in unserem Modell) anmelden. Dazu muß man erstmal den Supervisor
+"wecken" (wie mit einer Klingel): wir drücken die Supervisor-Taste (im
+folgenden mit SV abgekürzt). Der Supervisor meldet sich dann mit
+
+ gib supervisor kommando :
+
+Nun kann man eine Task anmelden. Das ist ein Zimmer im EUMEL-System, in dem
+man arbeiten kann, ohne von den anderen Benutzern gestört zu werden. Ist die
+Task noch nicht vorhanden, wird sie eingerichtet. Dann leitet uns der Super-
+visor in die angegebene Task.
+
+Der Verwaltungsangestellte ist nun vom Pförtner zu seinem Büro geleitet
+worden. Dort empfängt ihn der Bürovorsteher: "Was möchten Sie arbeiten?"
+Unser Angestellter kann nun (z.B.) sagen, daß er etwas schreiben möchte. Der
+Bürovorsteher führt ihn in einen speziellen Schreibraum, in dem einige
+spezielle Einrichtungen und Geräte für komfortables Schreiben stehen.
+
+So sieht es im EUMEL-System aus:
+Nachdem man eine neue Task eingerichtet hat oder eine bereits vorhandene
+fortsetzen will, gelangt man zum Monitor (das ist unser Bürovorsteher), der
+sich mit
+
+ gib kommando :
+
+meldet. Nun kann man verschiedene Arbeiten verrichten, wie z.B. den Editor
+rufen, um einen Text oder ein Programm zu schreiben:
+
+ edit ("meine datei")
+
+In diesem Schreibzimmer kann unser Angestellter irgendetwas schreiben, z.B.
+ein Programm, einen Liebesbrief, ein Testament oder ganz etwas anderes. Hat
+er eine Frage oder will er eine besondere Leistung, dann kann unser Ange-
+stellter den Bürovorsteher aus dem Schreibzimmer rufen. Hat er seine Schreib-
+arbeit beendet, geht er aus dem Zimmer und trifft dort wiederum auf den auf-
+merksamen Vorsteher. Ihm kann er nun sagen, daß er das Schriftstück (z.B.)
+drucken oder von einem Dolmetscher übersetzen lassen will.
+
+Im EUMEL-System:
+Im Editor schreibt man Texte oder Programme. Während man im Editor ist, kann
+man besondere Leistungen durch Kommandos anfordern, ohne den Editor zu ver-
+lassen, z.B. in einer anderen Datei nachschauen oder einen Teiltext in dem
+geschriebenen Schriftstück suchen. Nachdem die Arbeit beendet ist, verläßt
+man den Editor (ESC q) und gelangt wiederum in den Monitor. Hier kann man
+das Schriftstück drucken oder - im Falle eines Programms - übersetzen lassen:
+
+ print ("meine datei")
+ run ("meine datei")
+
+Hat das Programm einen Fehler, eröffnet uns der Monitor ein Fenster auf die
+Datei und zeigt uns gleichzeitig die Fehlermeldungen, so daß wir bequem
+korrigieren können.
+
+Nachdem unser Angestellter mit seinen Arbeiten fertig ist, kann er dem Vor-
+steher (Monitor) sagen:
+
+ Ich kündige! (will nicht mehr weiterarbeiten) ('end')
+ Bis Morgen! (will später weiterarbeiten) ('break')
+
+Merke: Der Supervisor des EUMEL-Systems regelt die Einrichtung, Zugang und
+ Löschung von Tasks. In einer Task kann ein Benutzer arbeiten, ohne
+ von anderen gestört zu werden. Spezielle Tasks sind für allgemeine
+ Aufgaben vorgesehen, wie z.B. das Drucken und Sichern von Dateien.
+ Durch den Monitor kann man Kommandos innerhalb einer Task geben.
+
+
+Demand Paging
+
+Nun versuchen wir einen zentralen Begriff des EUMEL-Systems zu erklären, das
+"demand paging". Diese Eigenschaft moderner Rechensysteme sorgt dafür, daß
+bei (normalerweise immer) beschränkten Speicherkapazitäten eines Rechners
+Programme bearbeitbar sind, die in ihrer Gesamtgröße nicht in den Speicher
+des Rechners passen würden.
+
+Nehmen wir wieder den Angestellten, der nun in einem Zimmer (Task) auf einem
+Tisch das EUMEL-Benutzerhandbuch durcharbeiten will. Stellen wir uns weiter
+vor, daß er das Benutzerhandbuch nicht rein "sequentiell" lesen will, sondern
+daß er fortwährend "blättern" muß. Eigentlich muß unser Angestellter mehrere
+Seiten des Benutzerhandbuchs gleichzeitig lesen. Deshalb kommt er auf die
+listige Idee, die Seiten, die er dringend benötigt, zu photokopieren und auf
+seinem Tisch nebeneinander auszubreiten, damit er nicht mehr blättern muß.
+Leider ist sein Tisch zu klein, um alle photokopierten Seiten darauf auszu-
+breiten. Durch die Sparbemühungen der Regierung ist es auch aussichtslos,
+sich um einen größeren Tisch zu bemühen. Aber im Titel für Verbrauchsmaterial
+ist genügend Geld vorhanden, so daß Papier für den Photokopierer angeschafft
+werden kann. Außerdem geht das Photokopieren sehr schnell, weil er den Photo-
+kopierer direkt neben seinen Tisch aufbaut. Darum photokopiert er nur die-
+jenigen Seiten, die er gerade benötigt und legt diese auf seinen Tisch.
+Braucht er eine neue Seite aus dem Buch und hat diese auf dem Schreibtisch
+keinen Platz mehr, so muß er eine auf dem Tisch liegende Seite entfernen.
+Geschickt wählt sich unser Angestellter eine Seite aus, von der er annimmt,
+daß er diese nicht so schnell wieder benötigt.
+
+Was macht er nun mit der "alten" Seite? Er könnte die kopierte Seite einfach
+in das Benutzerhandbuch einordnen. Aber dazu müßte er erstmal in dem Benut-
+zerhandbuch suchen, was ihm zuviel Mühe macht. Deshalb wirft er diese Seite
+einfach weg, denn er kann sie ja jederzeit wieder aus dem Handbuch kopieren.
+
+Gerade will er eine Seite wegwerfen, da fällt ihm auf, daß er das "Wegwerf"-
+Verfahren vielleicht nicht immer anwenden sollte. Seine Notizen, die er sich
+auf einigen Seiten gemacht hat, würden ja mit weggeworfen und damit ver-
+nichtet. Deshalb wirft er Seiten mit Notizen nicht weg, sondern tauscht diese
+Seiten mit den ursprünglichen Seiten im Benutzerhandbuch aus.
+
+Fassen wir zusammen:
+Jemand arbeitet ein Buch "durch". Er kopiert sich diejenigen Seiten, die er
+jeweils benötigt. Da sein Tisch zu klein ist, um alle Seiten gleichzeitig
+auszulegen, kann er immer nur einen Ausschnitt aus dem Buch bearbeiten, was
+aber ausreicht. Braucht er eine neue Seite, so muß er eine auf dem Tisch
+liegende Seite "verdrängen". Hat er diese Seite nicht verändert, also mit
+Notizen versehen, so kann er sie einfach wegwerfen. "Veränderte" Seiten
+ersetzt er im Buch und bewahrt sie somit auf.
+
+Ähnliches erfolgt auch im EUMEL-System:
+Der Zentralspeicher (der Tisch in unserem Modell) des Rechners ist meist ge-
+genüber dem Massenspeicher, der im EUMEL-System auch als "Hintergrund" be-
+zeichnet wird (Floppy oder Magnetplatte; in unserem Modell das Buch) zu
+klein, als daß alle Informationen gleichzeitig hineinpassen würden. Darum
+werden alle Informationen in sogenannte Seiten ("pages") unterteilt, die
+jeweils 512 Byte (ein Byte entspricht einem Zeichen) groß sind. Wird eine
+Information benötigt, so wird die betreffende Seite in den Speicher geholt
+(daher auch der Begriff "demand paging", etwa: Seitenaustausch auf An-
+forderung). Das geht so lange gut bis der gesamte Platz im Zentralspeicher
+des Rechners belegt ist. Soll nun eine neue Seite vom Massenspeicher geholt
+werden, weil die darin enthaltenen Informationen gebraucht werden, muß eine
+Seite im Zentralspeicher ersetzt werden (Fachwort: die Seite muß "verdrängt"
+werden). Sie kann überschrieben werden (in unserem Modell wurde sie "wegge-
+worfen"), wenn keine Veränderungen vorgenommen wurden, d.h. keine Schreibzu-
+griffe, sondern nur Lesezugriffe auf die Seite erfolgten. Wurde die Seite
+verändert, so muß sie auf den Hintergrund zurückkopiert werden und dort die
+ursprüngliche Seite ersetzen.
+
+
+Merke: Die Vorteile eines "demand paging" Systems sind nun offensichtlich:
+ Es ist möglich, bei weitem größere Informationsmengen (Daten und/oder
+ Programme) zu bearbeiten als diejenige, die eigentlich in den vor-
+ handenen Speicher passen würde, weil tatsächlich immer nur ein Aus-
+ schnitt der gesamten Informationsmenge zu einem Zeitpunkt bearbeitet
+ werden muß. Bei traditionellen Systemen ist dagegen die maximale Größe
+ von Programmen und Daten durch die physikalische Größe des Zentral-
+ speichers beschränkt.
+
+
+Sharing
+
+Sharing bezeichnet die gemeinsame Nutzung von Seiten ("pages") durch mehr
+als einen Benutzer.
+
+Zurück zu unserem Angestellten: Dieser ist inzwischen fleißiger geworden und
+hat das gleiche Verfahren auf mehrere Bücher ausgedehnt, d.h. er kopiert sich
+diejenigen Seiten aus den Büchern, die er gerade benötigt. Bei der Ver-
+drängung einer Seite behält er sein altes (nicht sehr umweltfreundliches)
+Verfahren bei: nur die veränderten Seiten ersetzen die Original-Seiten in den
+Büchern (werden zurückgelegt), die anderen (nicht veränderten) weggeworfen.
+
+Aber auch andere Angestellte seines Büros haben ihn beobachtet, beneiden ihn
+um seine "geschickte" Arbeitstechnik und wollen mitarbeiten. Leider steht
+ihnen gemeinsam nur der eine Tisch zur Verfügung, der zudem in der Zwischen-
+zeit auch nicht größer geworden ist, weil die Sparmaßnahmen der Regierung
+noch immer anhalten. Darum müssen sie sich nun den einzigen Tisch teilen, auf
+dem sie ihre kopierten Seiten auslegen können.
+
+Im Laufe der Arbeit ergibt es sich, daß sie unterschiedliche Seiten der
+Bücher durcharbeiten müssen, weil sie verschieden schnell arbeiten, aber auch
+andere Arbeitsgebiete haben.
+
+Durch die unterschiedliche Arbeitsgeschwindigkeit ergibt es sich, daß ein
+Angestellter z.B. zu einem Zeitpunkt sich intensiv nur mit einer Seite be-
+schäftigt, ein anderer aber mehrere Seiten quasi gleichzeitig braucht. Aber
+oft brauchen mehrere Angestellte mehrere Seiten, so daß der verfügbare Platz
+auf dem Tisch bald etwas zu eng wird. Natürlich "funktioniert" unser Ver-
+fahren immer noch, aber es ist doch etwas langsam geworden, weil unsere
+Angestellten mehr mit dem Austausch von Seiten beschäftigt sind, als daß sie
+noch zu dem Verarbeiten der gelesenen Informationen kommen. Sie überlegen
+also, wie das Verfahren zu verbessern ist und kommen auf folgenden Trick:
+kopierte Seiten, die zwei oder mehr Angestellte zur gleichen Zeit bearbeiten
+wollen, brauchen nur einmal auf dem Tisch zu liegen (schließlich sind unsere
+Angestellten gewöhnt, in Gruppen zu arbeiten). Diese Rationalisierungs-Idee
+ist ja offensichtlich, denn schließlich benutzen die Angestellten die Bücher
+auch gemeinsam. Aber Vorsicht: wenn einer der Angestellten, die gemeinsam
+eine Seite bearbeiten, sich etwas auf dieser Seite notieren will, darf nicht
+die gemeinsam auf dem Tisch liegende Seite verwendet werden. In diesem Fall
+ist es notwendig, vorher eine erneute Kopie zu machen, weil andere Ange-
+stellte seine Notizen nicht unbedingt mitlesen sollen, also die unveränderte
+Seite brauchen.
+
+Und das findet im Rechner statt:
+Das "demand paging" Verfahren funktioniert natürlich nicht nur mit einer
+Datei und einem Programm, sondern auch mit mehreren Dateien und Programmen,
+von denen nur diejenigen Seiten in den Zentralspeicher geholt werden, die zu
+einem Zeitpunkt in den Rechner passen. Aber erst mit mehreren Benutzern des
+EUMEL-Systems entfaltet das "demand paging" Verfahren seine volle Mächtig-
+keit, denn alle Benutzer können Programme und/oder Dateien verarbeiten, die
+in der Gesamtheit nicht in den Speicher passen würden. Dabei wird eine Eigen-
+schaft des EUMEL-Systems gut genutzt: Alle Programme des EUMEL-Systems (und
+übrigens alle Programme, die der ELAN-Compiler übersetzt hat) sind reentrant,
+d.h. können von mehreren Benutzern gleichzeitig gelesen werden, aber brauchen
+nur einmal im Zentralspeicher vorhanden zu sein. Zwei oder mehr Benutzer
+können also eine oder mehrere Seiten gemeinsam verwenden (Fachausdruck:
+"sharen"), sowohl im Zentralspeicher wie auch im Massenspeicher ("Hinter-
+grund"). Dies gilt nicht nur für Programme, sondern auch für Daten. Erst
+wenn ein Benutzer eine Veränderung vornimmt, also schreibend auf die Seite
+zugreift, wird diese Seite (nur für diesen Benutzer!) kopiert (EUMEL-Fachaus-
+druck: "copy on write"). Alle anderen Benutzer arbeiten mit der unveränderten
+Seite weiter. Der große Vorteil dieses Verfahrens: eine redundante
+Speicherung von Daten und Programmen wird vermieden.
+
+Es passiert nun oft, daß ein Benutzer zu einem Zeitpunkt relativ wenig Seiten
+benötigt: sei es, daß er Daten mit Hilfe des Editors eingibt oder nachdenkt,
+sei es, daß ein Programm wenig Daten verwendet und selbst sehr kurz ist. Mit
+anderen Worten: die Anzahl der benötigten Seiten zu einem Zeitpunkt (Fachaus-
+druck: "working set") für diesen Benutzer ist klein. Dann ist es möglich, daß
+andere Benutzer zu diesem Zeitpunkt mehr Seiten im Zentralspeicher des Rech-
+ners haben. Deren "working set" ist also groß.
+
+Merke: Damit wird ein weiterer Vorteil des "demand paging" Verfahrens klar:
+ Ein "demand paging" System stellt sich automatisch und dynamisch auf
+ die Anforderungen von Benutzern ein, indem denjenigen Benutzern mehr
+ Speicher zugeteilt wird, die mehr benötigen und umgekehrt. Aber auch
+ ein Nachteil wird sichtbar: Benötigen alle Benutzer des Systems viel
+ Zentralspeicher, dann kann es zu folgender Situation kommen: Benutzer
+ A benötigt eine neue Seite. Das System verdrängt für diesen Zweck eine
+ Seite, die Benutzer B gehört. Nachdem Benutzer B an die Reihe kommt,
+ benötigt er diese Seite wieder. Das System verdrängt eine Seite des
+ Benutzers A u.s.f.. Eine solche Situation, in der "pages" ständig in
+ den Speicher kopiert und aus dem Speicher bei einer Seitenverdrängung
+ auf den Hintergrund geschrieben werden muß (und somit kaum gerechnet
+ wird), wird als "thrashing" bezeichnet. "thrashing" oder mit anderen
+ Worten: sehr geringer Verbrauch an Rechenzeit bei gleichzeitig er-
+ höhtem "paging"-Aufwand ist ein Anzeichen für zu hohe Anforderungen
+ an das System (Ausweg: Erweiterung des Hauptspeichers oder Be-
+ schleunigung des Hintergrundmediums (Platte statt Floppy) oder
+ Reduktion der Anforderungen).
+
+
+Datenräume
+
+Datenräume sind die Grundlage für Dateien im EUMEL-System.
+
+Zurück zu unseren Angestellten:
+Nachdem die Verbesserung vorgenommen wurde, daß sich zwei oder mehr Ange-
+stellte eine Seite auf dem Tisch "teilen", tritt sofort ein neues Problem
+auf. Es kann nun nämlich passieren, daß zwei Angestellte eine Original-Seite
+verändern und beide in dem gleichen Buch ersetzt werden müssen. Es befinden
+sich somit noch mindestens zwei andere mit Notizen versehene Seiten mit
+gleicher Seitennummer in einem Buch. Zu allem Unglück wurde die Original-
+Seite ersetzt, so daß andere Angestellte nur die mit Notizen versehene Seiten
+erhalten können. Was ist zu tun? Das Verfahren sollte doch beibehalten
+werden, denn schließlich ist eine totale Abkehr von Arbeitsvorgängen für
+Verwaltungsangestellte nicht denkbar.
+
+Als erste Idee kommt ihnen in den Sinn, einfach alle Bücher für alle Ange-
+stellten zu photokopieren. Dann kann es ja nicht zu einer solchen Kollision
+kommen, daß zwei oder mehr Angestellte eine Seite in einem Buch ersetzen
+wollen, weil jeder Angestellte seine eigene Kopie besitzt. Um die ver-
+schiedenen Kopien eines Buches auseinander zu halten, wird von den Ange-
+stellten verlangt, ihre Buch-Kopie mit einem sinnvollen Namen zu versehen.
+Dies Verfahren funktioniert auch eine Weile, bis ein strebsamer Angestellter
+einen Verbesserungsvorschlag macht, der prompt mit DM 5,- honoriert wird:
+wie bereits mit den Seiten auf dem Tisch geschehen, ist es ja nicht not-
+wendig, die Bücher zu photokopieren, sondern nur die mit Notizen versehenen
+in einen Ordner, der entsprechend einer Buch-Kopie angelegt wird, einzu-
+ordnen. Alle anderen, nicht veränderten Seiten können noch immer gemeinsam
+benutzt werden.
+
+Und so funktioniert es nun:
+Bei Arbeitsbeginn finden die Angestellten einen Buchbestand vor. Um mit einem
+Buch arbeiten zu können, muß ein Angestellter einen Ordner für dieses Buch
+anlegen, in den die ggf. veränderten Seiten eingeordnet werden. Zu diesem
+Zweck muß jeder Ordner einen sinnvollen Namen erhalten, damit die Angestell-
+ten ihre Ordner auch wiederfinden. Am Anfang müssen die Angestellten Seiten
+der Original-Bücher kopieren. Wird eine solche Seite mit Notizen versehen,
+also verändert, muß sie bei einer Verdrängung in den entsprechenden Ordner
+eingefügt werden. Muß ein Angestellter eine neue Seite kopieren, so schaut
+er erst in seinem Ordner nach, ob sich die entsprechende Seite dort befindet.
+Damit wird garantiert, daß jeder Angestellte auch immer seine, mit Notizen
+versehene Seiten erhält. Befindet sich eine gesuchte Seite nicht in dem
+Ordner (am Arbeitsbeginn ist ein Ordner natürlich immer leer), so kopiert er
+sich eine Seite aus dem entsprechenden Original-Buch.
+
+In der Zwischenzeit passiert folgendes im Rechner:
+Eine Sammlung von Daten und/oder Programmen wird im EUMEL-System ein "Daten-
+raum" ("dataspace") genannt. Erhält ein Datenraum einen Namen, so wird
+dieser Datenraum eine Datei ("file") genannt. Angenommen, es existiert im
+System eine Datei mit dem Namen 'Mist', die ein Angestellter mit dem Namen
+'Krümel Monster' erstellt hat. Ein anderer Benutzer mit dem Namen 'Grobi'
+will mit dieser Datei arbeiten. Grobi kopiert sich also diese Datei und gibt
+ihr den Namen 'Grobis Mist'. Durch diese Kopier-Operation wird ein neuer
+Datenraum angelegt, der aber anfänglich nur Verweise auf den Datenraum ent-
+hält, der sich unter dem Namen 'Mist' verbirgt. Der Datenraum bzw. die
+Seiten, die in Datei 'Mist' enthalten sind, werden also "geshared", d.h. von
+mehreren Benutzern gemeinsam verwendet (in unserem Beispiel von Grobi und
+Krümel Monster). Es erfolgt also eine logische Kopie, aber keine physika-
+lische!
+
+Will der Angestellte Grobi nun eine Seite der Datei 'Grobis Mist' verwenden,
+so erhält er natürlich die entsprechende Seite aus der Datei 'Mist'. Ver-
+ändert der Angestellte Grobi nun eine Seite, so wird diese veränderte Seite
+in dem Datenraum vermerkt, der unter dem Namen 'Grobis Mist' ansprechbar ist.
+Davon merkt der Benutzer 'Krümel Monster' natürlich nichts, denn er arbeitet
+mit den Seiten seines Datenraums weiter, die unverändert geblieben sind. Aber
+auch Grobi merkt nichts davon, daß Seiten soweit wie möglich gemeinsam be-
+nutzt werden.
+
+Merke: Durch das Konzept der Datenräume und Dateien (die nichts anderes sind
+ als benannte Datenräume), ist es möglich, auch Daten von verschiedenen
+ Programmen her gemeinsam zu benutzen und somit eine redundante
+ Speicherung überflüssig zu machen. Programme sind ebenfalls in Daten-
+ räumen gespeichert, so daß einer gemeinsamen Benutzung von z.B.
+ Systemprogrammen durch mehrere Nutzer nichts im Wege steht.
+
+
+
+Fixpunkte
+
+In gewissen Zeitabständen wird der gesamte Systemzustand eines EUMEL-Systems
+gespeichert ("Fixpunkt"). Bei eventuell auftretenden Störungen kann dadurch
+immer bei dem letzten Fixpunkt mit der Verarbeitung fortgefahren werden.
+
+Zurück zu unseren Angestellten, die typischerweise dieses komische System
+weiter benutzen: Es passiert zum ersten Mal ein entsetzliches Unglück:
+während im Sommer mehrere Fenster geöffnet wurden, betritt der "reitende"
+Bürobote das Zimmer und alle Seiten werden von den Tischen und aus allen
+offenen Ordnern herabgeweht. Da unsere Angestellten - wie man sich leicht
+vorstellen kann - etwas vergeßlich sind, können sie nicht mehr rekon-
+struieren, welche Seiten auf den Tischen und welche sich in den Büchern bzw.
+Ordnern befanden. Die Arbeit von mehreren Monaten ist somit verloren!
+
+Deshalb werden Sicherheitsmaßnahmen getroffen:
+In regelmäßigen Zeitabständen müssen alle Angestellten ihre Arbeit unter-
+brechen. Dann wird von einem - extra dazu abgestellten - Angestellten Listen
+angelegt, in denen die Seiten auf dem Tisch, den Ordnern und den Büchern
+vermerkt wird. Im Falle eines erneuten Unglücks braucht man also nur die
+letzte dieser Listen zu konsultieren, um eine gesicherte Arbeitssituation
+herzustellen. Allerdings ist in einem solchen Fall diejenige Arbeit verloren,
+die in der Zwischenzeit seit der Erstellung der letzten Liste geleistet
+wurde. Aber das wird ja gerne in Kauf genommen, weil überhaupt weitergemacht
+werden kann und nicht die gesamte Arbeit verloren ist.
+
+Merke: In gewissen (einstellbaren, typisch: 15 Minuten) Zeitabständen wird
+ vom EUMEL-System der gesamte Zustand des Systems gesichert. Diese
+ Sicherung wird "Fixpunkt" genannt. Dazu ist es notwendig, daß die
+ Verarbeitung der Programme kurz (z.Z. 0.2 Sek.) unterbrochen wird,
+ was sich jedoch meist nicht besonders störend auswirkt. Damit ist es
+ aber sichergestellt, daß bei einem Stromausfall, Hardware- oder Soft-
+ warestörungen immer zu einem Zeitpunkt in der Verarbeitung "aufge-
+ setzt" werden kann, bei dem nur diejenigen Daten verloren sind, die
+ seit dem letzten "Fixpunkt" aufliefen.
+
+
+
+Archiv
+
+Ein weiteres Sicherungsmittel im EUMEL-System ist das Archiv, mit welchem
+man Dateien (also Daten und/oder Programme) extern zum EUMEL-System
+speichern kann.
+
+Verlassen wir nun lieber unsere Angestellten. Dieses Modell würden wir sonst
+übermäßig strapazieren. Wenden wir uns vielmehr einem weiteren Sicherungs-
+mittel des EUMEL-Systems zu, dem EUMEL-Archiv. Mit Hilfe des EUMEL-Archivs
+ist es möglich, Dateien auf Floppies zu schreiben und somit außerhalb des
+EUMEL-Systems aufzubewahren. Es ist nun möglich, mehrere Dateien auf einer
+Floppy zu speichern. Bloß wie funktioniert das?
+
+Ein gutes Modell des EUMEL-Archivs stellt ein Tonband oder eine Musikkassette
+dar. Auf diesen werden die Musikstücke (unsere Dateien) nacheinander (Fach-
+ausdruck: "sequentiell") aufgezeichnet, d.h. neue Musikstücke (Dateien)
+können immer nur angefügt werden. Ist das Tonband oder die Kassette voll
+beschrieben, so schaltet das Gerät meist automatisch ab. Im EUMEL-System
+gibt's in solchen Fällen eine Fehlermeldung.
+
+Unterschiedlich zu einem Tonband ist jedoch, daß im EUMEL-System die Namen
+der Dateien mit abgespeichert werden und diese Dateien - durch die Angabe
+des Dateinamens - gezielt vom Archiv gelesen werden können. Bei einem Ton-
+band oder einer Kassette muß man sich erst alle Musikstücke anhören, bis
+das Musikstück erreicht ist, welches benötigt wird. Dieses "sequentielle"
+Überlesen nicht benötigter Dateien erledigt das EUMEL-System "automatisch".
+
+Im EUMEL-System gibt es nun nicht nur die Möglichkeit, eine Datei auf ein
+Archiv zu schreiben oder von einem Archiv zu lesen, sondern auch mehrere Da-
+teien mit einem Kommando zu lesen oder zu schreiben. Zusätzlich ist es mög-
+lich, ein Archiv zu löschen (und dann ggf. neu zu beschreiben), wenn die
+"archivierten" Dateien nicht mehr benötigt werden.
+
+Nun passiert es oft, daß eine bereits archivierte Datei verändert wird und
+nochmals auf das Archiv geschrieben werden soll. Aber durch eine Veränderung
+der Datei hat diese gerade ihren Platzbedarf verändert. Somit könnte die
+Datei - sofern sie sich vergrössert hat - eine nachfolgende Datei auf dem
+Archiv u.U. teilweise überschreiben. Deshalb wurde im EUMEL-Archiv folgende
+Vereinbarung getroffen: Wird eine Datei nochmals auf ein Archiv geschrieben,
+so wird die Datei, die sich bereits auf dem Archiv befindet, als "ungültig"
+gekennzeichnet und die neue Version an das Ende angefügt. Nur wenn die alte
+Datei die letzte auf dem Archiv ist, wird sie von der neuen Version über-
+schrieben.
+
+Merke: Durch dieses Verfahren kann es zu einer kuriosen Situation kommen:
+ zwei Dateien werden abwechselnd auf ein Archiv in mehreren Versionen
+ geschrieben. Obwohl beide Dateien zusammengenommen bei weitem nicht
+ das Archiv auffüllen würden, kommt es zum Überlauf. In einem solchen
+ Fall muß man das Archiv löschen (wobei vorher die Dateien ggf. in das
+ System geholt werden müssen) und beide Dateien erneut auf das Archiv
+ schreiben.
+
+
+
+4. Kleines #ib#EUMEL-Wörterbuch
+
+In diesem Wörterbuch werden einige der Begriffe, die häufig in diesem Be-
+nutzer-Handbuch verwendet werden, erläutert. Bezüge auf weitere Begriffe,
+die in diesem Wörterbuch stehen, werden mit den Zeichen ">" und "<" ge-
+klammert.
+
+Anweisung: Direktive an die Textkosmetik, welche direkt in einen Text
+ geschrieben wird. Eine Anweisung muß in "\#" eingefaßt
+ werden. Beachte den Unterschied zu einem Kommando.
+
+Archiv: Ein Programmsystem, um Dateien des EUMEL-Systems auf
+ Floppys außerhalb des Systems zu speichern oder von dort
+ wieder in das EUMEL-System zu holen. Als Archiv wird auch
+ noch ein Speichermedium bezeichnet (in der Regel eine
+ Diskette).
+
+Benutzer-Task: Im Gegensatz zu einer >System-Task< ist eine Benutzer-Task
+ eine Task, die von einem Benutzer erzeugt worder ist. Sie
+ ist entweder an ein Terminal gekoppelt oder kann unab-
+ hängig von einem Terminal im Hintergrund bearbeitet werden.
+
+BOUND: Attribut von Variablen, das bei einer Deklaration vor die
+ Typangabe gesetzt wird. Dient zur Aufprägung eines Daten-
+ typs auf einen Datenraum.
+
+DATASPACE: Eine Datei ohne Namen.
+
+Datenraum: Siehe >DATASPACE<.
+
+Editor: Programm zur Eingabe und Veränderung von Texten, Daten und
+ Programmen.
+
+ELAN: Programmiersprache des EUMEL-Systems ("ELementary
+ LANguage").
+
+ELAN-Compiler: Ein Programm, welches ein korrektes ELAN-Programm in ein
+ äquivalentes, ablauffähiges Programm (im >EUMEL0-Code<)
+ übersetzt.
+
+EUMEL0-Code: Maschinensprache des EUMEL-Systems.
+
+EUMEL-Drucker: Programm zur Ansteuerung von (unterschiedlichen) Druckern.
+ Der EUMEL-Drucker wird durch Kommandos gesteuert und er-
+ laubt es, unterschiedliche Drucker mit verschiedenartigen
+ Leistungen immer gleich anzusprechen.
+
+EUMEL-Standard: Objekte (also Datentypen, Prozeduren und/oder Operatoren),
+ die durch Pakete realisiert werden und standardmässig in
+ jedem EUMEL-System verfügbar sind.
+
+Fixpunkt: Speicherung des aktuellen Systemzustandes in regelmäßigen
+ Abständen. Bei Hardware- oder Softwarestörungen kann immer
+ bei der letzten Fixpunkt-Sicherung aufgesetzt werden.
+
+Hintergrund-Task: Eine >Task<, die nicht an ein Terminal angekoppelt ist
+ (d.h. einem Benutzer nicht direkt zugänglich), aber trotz-
+ dem vom System bearbeitet wird oder im Wartezustand ist
+ (warten auf einen Auftrag oder eine Ein/Ausgabe-Operation).
+
+Kommando: Ein ELAN-Programm, welches in der Regel aus einem
+ Prozeduraufruf besteht. Ein Kommando kann vom >Monitor<
+ oder Editor gegeben werden. Kommandos können ebenfalls in
+ Programmen verwandt werden.
+
+Lokale Dateien: Dateien einer Benutzer-Task.
+
+Manager: Eine >Task<, die auf Aufträge wartet. Beispiele sind die
+ Spool-Task bzw. Datei-Manager. Letzterer wird für die
+ Haltung längerfristig benötigter Dateien gebraucht.
+
+Monitor: Der Monitor steuert die Kommunikation zwischen einem
+ Benutzer am Terminal und dem EUMEL-Betriebssystem, nachdem
+ der Benutzer sich mit Hilfe des >Supervisors< eine Task
+ erschaffen hat. Die Monitor-Kommandos beziehen sich immer
+ auf die angekoppelte Benutzer-Task.
+
+paging: Benötigte Informationen werden in Einheiten ("pages") in
+ den Zentralspeicher des Rechners geladen. Somit ist es
+ möglich, bei weitem größere Informationsmengen zu ver-
+ arbeiten, als auf einmal in den Speicher des Rechners
+ passen.
+
+OPERATOR: >Task<, mit der das EUMEL-System u.a. gestartet, "abge-
+ schaltet" und gesichert werden kann.
+
+Scanner: Programm, um aus einem Text lexikalische Elemente ("Le-
+ xeme") herauszublenden. In dem im >EUMEL-Standard<
+ implementierten Scanner werden Lexeme nach der ELAN-Syntax
+ erkannt, redundante Leerzeichen (nicht in Texten) sowie
+ Kommentare überlesen.
+
+Sendungs-Vermittlung: Steuerung der Übermittlung von Informationen zwischen
+ verschiedenen >Tasks<.
+
+sharing: >Datenräume< und/oder >pages< können von mehreren Benutzern
+ gleichzeitig benutzt werden. Erst bei einer Schreibopera-
+ tion eines Benutzers wird nur für diesen Nutzer eine Kopie
+ der Daten angelegt. ("copy on write").
+
+Spooler: Systemprogramm des EUMEL-Systems, welches Druckaufträge
+ zwischenspeichert, so daß unmittelbar weiter gearbeitet
+ werden kann.
+
+Supervisor: Kern des EUMEL-Betriebssystems auf der ELAN-Ebene zum Ver-
+ walten von Tasks.
+
+Supervisor-Kommando: Kommando zur Steuerung (An-/Abkoppeln, Erzeugen,
+ Benutzung) einer >Benutzer-Task<.
+
+System-Task: Eine >Task<, die für Aufrechterhaltung, Betrieb und Steu-
+ erung des EUMEL-Systems benötigt und nicht von einem
+ Benutzer erzeugt wird, sondern "immer" im >Taskbaum<
+ vorhanden ist.
+
+Task: Eigenständiger Prozeß (Auftrag) im EUMEL-System.
+
+Taskbaum: Eine baumförmige Anordnung von >Tasks<, in die jede Task
+ des EUMEL-Systems eingefügt wird. Dabei hat jede Task
+ - mit Ausnahme des >Urvaters< - eine >Vater-Task<, und
+ kann weitere Tasks erzeugen ("Söhne").
+
+Textkosmetik: Programme des EUMEL-Systems, die die Gestaltung eines
+ Textes erlauben.
+
+Urvater: Wurzel des >Task-Baums< mit dem Namen 'UR'.
+
+Vater-Dateien: Dateien einer >Vater-Task<.
+
+Vater-Task: Eine >Task<, die einer Task in direkt aufsteigender Linie
+ im >Taskbaum< übergeordnet ist. Es wird dabei zwischen
+ einer "unmittelbaren" (die direkt übergeordnete Vater-Task)
+ und "mittelbaren" Vater-Tasks (Vater-Tasks, die über die
+ unmittelbare Vater-Task erreichbar sind) unterschieden.
+
+
+
+5. ELAN-Literatur
+
+Bittner, M., Jäckel, J., Jähnichen, S.:
+ ELAN - Beispielsammlung.
+ Institut für angewandte Informatik,
+ Fachbereich 20, TU Berlin,
+ Berlin, 1979
+
+Hahn, R.:
+ Höhere Programmiersprachen im Vergleich.
+ Akademische Verlagsgesellschaft,
+ Wiesbaden, 1981
+
+Hahn, R., Nienaber, B.:
+ Probleme lösen mit dem Computer.
+ Teil 1: Einführung in die algorithmische Problemlösung.
+ Teil 2: Werkzeuge und Methoden.
+ Neuer Verlag Bernhard Bruscha,
+ Tübingen, 1978
+
+Hahn, R., Stock, P.:
+ ELAN - Handbuch.
+ Akademische Verlagsgesellschaft,
+ Wiesbaden, 1979
+
+Hommel, G., Jäckel, J., Jähnichen, S., Kleine, K., Koch, W., Koster, K.:
+ ELAN - Sprachbeschreibung.
+ Akademische Verlagsgesellschaft,
+ Wiesbaden, 1979
+
+Hommel, G., Jähnichen, S., Koch, W.:
+ SLAN - Eine erweiterbare Sprache zur Unterstützung der strukturierten
+ und modularen Programmierung.
+ 4. GI Fachtagung Programmiersprachen in Erlangen,
+ Springer Verlag, 1976
+
+Hommel, G., Jähnichen, S., Koster, C.H.A.:
+ Methodisches Programmieren.
+ De Gruyter, Berlin, 1983
+
+Klingen, L., Liedtke, J:
+ Programmieren mit ELAN
+ Teubner, Stuttgart, 1983
+
+Liedtke, J.:
+ EUMEL - Ein ELAN-System für Mikroprozessoren.
+ GMD-Spiegel,
+ Bonn, 1979
+
+Voila, H.T.:
+ A new computer routine for the generation of publishable data from
+ nothing.
+ Computer Quickies 48, 117 (1984)
+
+
diff --git a/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil10 b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil10
new file mode 100644
index 0000000..0f3b656
--- /dev/null
+++ b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil10
@@ -0,0 +1,771 @@
+ EUMEL-Benutzerhandbuch
+
+ TEIL 10: Graphik
+
+1. Übersicht
+
+Dieser Teil des Benutzer-Handbuchs beschreibt die Graphik-Möglichkeiten des
+EUMEL-Systems. Die Graphik-Pakete gehören nicht zum EUMEL-Standard, sondern
+sind Anwenderpakete, die im Quellcode ausgeliefert und von jeder Instal-
+ation in das System aufgenommen werden können. Unter Umständen müssen
+Programme erstellt werden, die die Anpassungen für spezielle graphische
+Geräte einer Installation vornehmen.
+
+Das Graphik-System ermöglicht es, durch ELAN-Programme geräteunabhängige
+Informationen für Zeichnungen ("Graphiken") zu erstellen. Die Graphik
+erzeugenden Programme brauchen dabei keine gerätespezifischen Größen sowie
+gerätespezifischen Unterprogramme zu enthalten. Sie befassen sich somit
+ausschließlich mit der Erzeugung der problemorientierten Information für die
+Konstruktion einer Zeichnung. Nach der geräteunabhängigen Erzeugung einer
+Graphik kann diese auf unterschiedlichen Geräten ausgegeben werden (z.B.
+erst auf einem Terminal zur Kontrolle und dann auf einem Plotter).
+
+Die EUMEL-Graphik umfaßt zwei- und dreidimensionale Graphik. Dabei ent-
+spricht die Y-Achse bei der zweidimensionalen Graphik der Z-Achse (Höhe) bei
+der dreidimensionalen Graphik. Im dreidimensionalen Fall sind perspektivi-
+sche, orthografische und schiefwinklige Projektionen mit beliebigen Betrach-
+tungswinkeln möglich.
+
+Bei der EUMEL-Graphik wird streng zwischen Erzeugung und Manipulation von
+Graphiken (Bildern) auf der einen und Darstellung der erzeugten Bilder auf
+der anderen Seite unterschieden. Für die Erzeugung und Manipulation der
+Graphiken existiert der Typ PICTURE, für die Darstellung der Bilder gibt es
+den Typ PICFILE. Dabei müssen Ausschnitt, Maßstab, Betrachtungswinkel und
+Projektionsart erst bei der Darstellung festgelegt werden. Diese Kon-
+struktion des Graphik-Systems hat folgende Vorteile:
+
+a) Programme, die Graphik-Informationen erzeugen, sind geräteunabhängig.
+ Das bedeutet, daß Programmierer sich ausschließlich mit einem logischen
+ Problem zu befassen brauchen und nicht mit gerätespezifischen Besonder-
+ heiten.
+
+b) Graphiken können auf mehreren unterschiedlich gearteten Geräten mehrmals
+ dargestellt werden, ohne daß das erzeugende Programm geändert oder neu
+ gestartet werden muß. Z.B. kann ein Programmierer eine Graphik erst auf
+ dem Terminal auf Richtigkeit und Größenverhältnisse überprüfen, bevor er
+ die Zeichnung auf einem Plotter zeichnen läßt.
+
+c) Graphiken können leicht geändert (z.B. vergrößert oder in eine Richtung
+ gestreckt) werden, ohne daß das erzeugende Programm erneut durchlaufen
+ werden muß. Zudem können Graphiken aneinander oder übereinander gelegt
+ werden.
+
+d) Graphiken mit unterschiedlichen Farben, Strichen usw. können leicht er-
+ zeugt werden.
+
+e) Der Anschluß von neuen Graphik-Geräten durch Benutzer ist leicht möglich,
+ ohne daß die Graphik erzeugenden Programme modifiziert werden müssen.
+
+f) Plotter können wie Drucker an einen SPOOLER gehängt werden.
+
+g) Bilder können als PICFILEs gespeichert und versandt werden.
+
+
+
+Erzeugung von Bildern
+
+Bilder entstehen in Objekten vom Datentyp
+
+ PICTURE
+
+Diese müssen mit der Prozedur
+
+ nilpicture
+
+initialisiert werden. Sie enthalten dann ein leeres Bild, dessen Dimension
+noch nicht festgelegt ist. Die Dimension eines PICTUREs wird mit dem ersten
+Schreibzugriff ('move' oder 'draw') festgelegt. Ein PICTURE kann immer nur
+entweder zwei- oder dreidimensional sein. Außerdem kann einem PICTURE mit
+der Prozedur
+
+ pen
+
+genau ein virtueller Stift zugeordnet oder der aktuelle Stift erfragt werden.
+
+Die Erzeugung eines Bildes basiert auf dem Modell eines Plotters. Der (vir-
+tuelle) Zeichenstift kann mit
+
+ move
+
+ohne zu zeichnen an beliebige Stellen gefahren werden (reine Positionierung).
+Mit
+
+ draw
+
+wird der Stift veranlaßt, eine Linie von der aktuellen zur angegebenen Ziel-
+position zu zeichnen. 'move' löst also Bewegungen mit gehobenem, 'draw'
+solche mit gesenktem Stift aus. Um auch 'relatives' Zeichnen zu ermöglichen,
+existiert die Prozedur
+
+ where
+
+die die aktuelle Stiftposition liefert.
+
+
+
+Manipulation von Bildern
+
+Erstellte Bilder können als Ganzes manipuliert werden. Die Prozeduren
+
+ translate (* verschieben *)
+ stretch (* strecken bzw. stauchen *)
+ rotate (* drehen *)
+ reflect (* spiegeln *)
+
+verändern jeweils das ganze Bild. Es ist aber auch möglich, mehrere Bilder
+zusammenzufügen. Mit
+
+ CAT
+
+kann ein weiteres Bild angefügt werden. Dabei müssen allerdings beide
+PICTURE die gleiche Dimension haben. In solchen als ganzes manipulierten
+Bildern kann man ohne Einschränkung mit 'draw' und 'move' weiterzeichnen.
+
+
+
+Darstellung
+
+Für die Darstellung der erzeugten Bilder existiert der Typ
+
+ PICFILE
+
+Dieser besteht aus max. 128 PICTUREs, die mit den Prozeduren
+
+ put
+ get
+
+eingegeben bzw. ausgegeben werden können. PICFILE wird durch Datenräume
+realisiert, deshalb erfolgt die Assoziation an einen benannten Datenraum
+ähnlich wie beim FILE. Dafür wird die Prozedur
+
+ picture file
+
+verwandt. Ein neuer PICFILE enthält genau ein leeres PICTURE. Die Darstel-
+lung der PICFILEs auf Zeichengeräten erfolgt mit der Prozedur
+
+ plot
+
+Da die Graphiken aber in "Weltkoordinaten" erzeugt werden und die spätere
+Darstellung vollkommen unbeachtet bleibt, müssen gewisse Darstellungspara-
+meter für die Zeichnung gesetzt werden. Diese Parameter werden im PICFILE
+abgelegt und gelten jeweils für den gesamten PICFILE. Dadurch ist es möglich,
+einen PICFILE mit spezifizierter Darstellungsart über einen SPOOLER an einen
+Plotter zu senden oder die bei der letzten Betrachtung gewählte Darstellung
+mit in dem PICFILE gespeichert zu halten. Für die Darstellung können den
+virtuellen Stiften mit der Prozedur
+
+ select pen
+
+reale Stifte zugeordnet werden. Voreingestellt ist für alle virtuellen
+Stifte: Standardfarbe, Standardstärke, durchgängige Linie.
+
+Indem man einigen virtuellen Stiften den leeren Stift als realen Stift zu-
+ordnet, kann man einzelne PICTUREs ausblenden. Sowohl bei der Darstellung
+von zwei- als auch dreidimensionaler Graphik kann die gewählte Zeichenfläche
+auf dem Endgerät mit der Prozedur
+
+ viewport
+
+festgelegt werden. Voreingestellt ist das Quadrat mit der größtmöglichen
+Seitenlänge, d.h. der kürzeren Seite der hardwaremäßigen Zeichenfläche.
+
+
+
+Darstellung zweidimensionaler Graphik
+
+Bei der Darstellung zweidimensionaler Bilder muß der zu zeichnende Ausschnitt
+(das 'Fenster') angegeben werden. Mit der Prozedur
+
+ window
+
+wird durch Angabe der minimalen und maximalen X- bzw. Y-Koordinaten ein
+Fenster definiert. Da das so definierte Fenster auf die ganze (mit 'viewport'
+definierbare) Zeichenfläche abgebildet wird, ist der Abbildungsmaßstab durch
+das Zusammenspiel von 'viewport' und 'window' bestimmt. Da bei 'viewport'
+standardmäßig das maximale Zeichenquadrat voreingestellt ist, wird in diesem
+Fall durch gleiche X- und Y-Fenstergröße eine winkeltreue Darstellung er-
+reicht.
+
+
+
+Darstellung dreidimensionaler Graphik
+
+Im dreidimensionalen Fall wird das Fenster ebenfalls mit
+
+ window
+
+definiert, wobei dann allerdings auch der Bereich der dritten Dimension
+(Z-Koordinaten) zu berücksichtigen ist. Da die dreidimensionale Graphik auf
+eine zweidimensionale Fläche projiziert wird, können aber noch weitere Dar-
+stellungsparameter angegeben werden. Der Betrachtungswinkel wird mit Hilfe
+der Prozedur
+
+ view
+
+angegeben. Zur Spezifikation der gewünschten Projektionsart gibt es
+
+ orthographic (* orthographische Projektion *)
+ perspective (* perspektivische Projektion,
+ der Fluchtpunkt ist frei wählbar *)
+ oblique (* schiefwinklige Projektion *)
+
+
+
+Beispiel (Sinuskurve)
+
+ funktion zeichnen;
+ bild darstellen .
+
+funktion zeichen :
+ PICTURE VAR pic :: nilpicture;
+ REAL VAR x := -pi;
+ move (pic, x, sin (x));
+ REP x INCR 0.1;
+ draw (pic, x, sin (x))
+ UNTIL x >= pi PER .
+
+bild darstellen :
+ PICFILE VAR p :: picture file ("sinus");
+ window (p, -pi, pi, -1.0, 1.0);
+ put (p, pic);
+ plot (p) .
+
+
+
+Beispiel (Würfel)
+
+ wuerfel zeichen;
+ wuerfel darstellen.
+
+wuerfel zeichnen :
+ zeichne vorderseite;
+ zeichne rueckseite;
+ zeichne verbindungskanten.
+
+zeichne vorderseite :
+ PICTURE VAR vorderseite :: nilpicture;
+ move (vorderseite, 0.0, 0.0, 0.0);
+ draw (vorderseite, 1.0, 0.0, 0.0);
+ draw (vorderseite, 1.0, 0.0, 1.0);
+ draw (vorderseite, 0.0, 0.0, 1.0);
+ draw (vorderseite, 0.0, 0.0, 0.0).
+
+zeichne rueckseite :
+ PICTURE VAR rueckseite :: translate (vorderseite, 0.0, 1.0, 0.0).
+
+zeichne verbindungskanten :
+ PICTURE VAR verbindungskanten :: nilpicture;
+ move (verbindungskanten, 0.0, 0.0, 0.0);
+ draw (verbindungskanten, 0.0, 1.0, 0.0);
+
+ move (verbindungskanten, 1.0, 0.0, 0.0);
+ draw (verbindungskanten, 1.0, 1.0, 0.0);
+
+ move (verbindungskanten, 1.0, 0.0, 1.0);
+ draw (verbindungskanten, 1.0, 1.0, 1.0);
+
+ move (verbindungskanten, 0.0, 0.0, 1.0);
+ draw (verbindungskanten, 0.0, 1.0, 1.0).
+
+wuerfel darstellen :
+ PICFILE VAR p := picture file ("wuerfel");
+ put (p, vorderseite);
+ put (p, rueckseite);
+ put (p, verbindungskanten);
+ window (p, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0);
+ view (p, 0.0, 40.0, 20.0);
+ orthographic (p);
+ plot (p).
+
+
+
+Beschreibung der Graphik-Prozeduren
+
+Zweidimensionale PICTUREs brauchen weniger Speicherplatz als dreidimensio-
+nale. Daher werden in einigen Fehlermeldungen unterschiedliche Größen ange-
+geben.
+
+:=
+ OP := (PICTURE VAR dest, PICTURE CONST source)
+ Zweck: Zuweisung
+
+ OP := (PICFILE VAR dest, DATASPACE CONST source)
+ Zweck: Assoziiert die PICFILE Variable 'dest' mit der DATASPACE CONST
+ 'source' und initialisiert die PICFILE Variable sofern nötig.
+ Fehlerfall:
+ * dataspace is no PICFILE
+ Der anzukoppelnde Datenraum hat einen falschen Typ.
+
+CAT
+ OP CAT (PICTURE VAR dest, PICTURE CONST source)
+ Zweck: Aneinanderfügen von zwei PICTURE's.
+ Fehlerfälle:
+ * OP CAT: left dimension <> right dimension
+ Es können nur PICTUREs mit gleicher Dimension angefügt werden.
+ * OP CAT: Picture overflow
+ Die beiden PICTURE überschreiten die maximale Größe eines Pictures.
+
+act picture
+ PICTURE PROC act picture (PICFILE VAR p)
+ Zweck: Liefert das PICTURE des PICFILEs 'p', auf das mit 'backward' o.ä.
+ positioniert wurde.
+
+backward
+ PROC backward (PICFILE VAR p)
+ Zweck: Positioniert den PICFILE 'p' um ein PICTURE zurück.
+ Fehlerfall:
+ * backward at begin of file
+ Es wurde versucht vor den Anfang des PICFILEs zu positionieren.
+
+draw
+ PROC draw (PICTURE VAR pic, REAL CONST x, y)
+ Zweck: Die Prozedur zeichnet in dem (zweidimensionalen) Bild 'pic' eine
+ Linie von der aktuellen Position zur Position (x, y).
+ Fehlerfälle:
+ * picture overflow
+ Zu viele Befehle in einem PICTURE (z. Zeit max. 1927)
+ * picture is three dimensional
+ Ein PICTURE kann nur entweder zwei- oder dreidimensional sein.
+
+ PROC draw (PICTURE VAR pic, REAL CONST x, y, z)
+ Zweck: Die Prozedur zeichnet in dem (dreidimensionalen) Bild 'pic' eine
+ gerade Linie von der aktuellen Position zur Position (x, y, z).
+ Fehlerfälle:
+ * picture overflow
+ Zu viele Befehle in einem PICTURE (z. Zeit max. 1310)
+ * picture is only two dimensional
+ Ein PICTURE kann nur entweder zwei- oder dreidimensional sein.
+
+ PROC draw (PICTURE VAR pic, TEXT CONST text)
+ Zweck: Der angegebene Text wird in das Bild 'pic' eingetragen. Der An-
+ fang ist dabei die aktuelle Stiftposition. Diese wird nicht ver-
+ ändert.
+ Fehlerfall:
+ * picture overflow
+ Der Text paßt nicht mehr in das PICTURE.
+
+ PROC draw (PICTURE VAR pic, TEXT CONST text, REAL CONST angle, height)
+ Zweck: Der angegebene Text wird unter dem Winkel 'angle' gegenüber der
+ Waagerechten und in der Größe 'height' in das PICTURE 'pic'
+ eingetragen. Der Anfang ist dabei die aktuelle Stiftposition.
+ Diese wird nicht verändert.
+ Fehlerfall:
+ * picture overflow
+ Der Text paßt nicht mehr in das PICTURE.
+
+ PROC draw (PICFILE VAR pic, REAL CONST x, y)
+ Zweck: Die Prozedur zeichnet in dem aktuellen (zweidimensionalen)
+ PICTURE des PICFILEs 'p' eine gerade Linie. Der (virtuelle) Stift
+ wird von der aktuellen Position zur Position (x, y) gefahren.
+ Falls das aktuelle PICTURE zu voll ist, wird automatisch auf das
+ nächste umgeschaltet.
+ Fehlerfälle:
+ * picfile overflow
+ Das letzte PICTURE ist voll (z. Zeit max. 128 PICTURE)
+ * picture is threedimensional
+ Das aktuelle PICTURE ist dreidimensional.
+
+ PROC draw (PICTFILE VAR pic, REAL CONST x, y, z)
+ Zweck: s. o.
+ Fehlerfälle:
+ * picfile overflow
+ Das letzte PICTURE ist voll (z. Zeit max. 128)
+ * picfile is only twodimensional
+ Das aktuelle PICTURE ist zweidimensional.
+
+ PROC draw (PICTFILE VAR pic, TEXT CONST text)
+ Zweck: Der angegebene Text wird in das aktuelle PICTURE des PICFILEs 'p'
+ eingetragen. Falls das aktuelle PICTURE zu voll ist, wird auto-
+ matisch auf das nächste umgeschaltet. Der Anfang ist dabei die
+ aktuelle Stiftposition. Diese wird nicht verändert.
+ Fehlerfall:
+ * picfile overflow
+ Das letzte PICTURE ist voll (z. Zeit max. 128)
+
+ PROC draw (PICFILE VAR pic, TEXT CONST text, REAL CONST angle, height)
+ Zweck: Der angegebene Text wird unter dem Winkel 'angle' gegenüber der
+ Waagerechten und in der Größe 'height' in das aktuelle PICTURE
+ des PICFILES 'p' eingetragen. Falls das aktuelle PICTURE zu voll
+ ist, wird automatisch auf das nächste umgeschaltet. Der Anfang ist
+ dabei die aktuelle Stiftposition. Diese wird nicht verändert.
+ Fehlerfall:
+ * picfile overflow
+ Das letzte PICTURE ist voll (z. Zeit max. 128)
+
+eof
+ BOOL PROC eof (PICFILE CONST p)
+ Zweck: Liefert 'TRUE' wenn hinter das Ende des PICFILEs positioniert
+ wurde.
+
+extrema
+ PROC extrema (PICTURE CONST p, REAL VAR x min, x max, y min, y max)
+ Zweck: Die Prozedur liefert die größten und kleinsten X- und Y-Koordi-
+ naten des PICTUREs 'p'. Diese werden in die Parameter 'x min',
+ 'x max', 'y min' und 'y max' eingetragen.
+
+ PROC extrema (PICTURE CONST p,
+ REAL VAR x min, x max, y min, y max, z min, z max)
+ Zweck: s.o.
+
+ PROC extrema (PICFILE VAR p, REAL VAR x min, x max, y min, y max)
+ Zweck: s.o.
+
+ PROC extrema (PICFILE VAR p,
+ REAL VAR x min, x max, y min, y max, z min, z max)
+ Zweck: s.o.
+
+forward
+ PROC forward (PICFILE VAR p)
+ Zweck: Positioniert den PICFILE um ein PICTURE weiter.
+ Fehlerfall:
+ * picfile overflow
+ Es sollte hinter das Ende des PICFILEs positioniert werden.
+
+get
+ PROC get (PICFILE VAR p, PICTURE VAR pic)
+ Zweck: Liest ein PICTURE aus einem PICFILE und positioniert auf das
+ Nächste.
+ Fehlerfall:
+ * input after end of picfile
+ Es sollte nach dem Ende des Picfiles gelesen werden.
+
+move
+ PROC move (PICTURE VAR pic, REAL CONST x, y)
+ Zweck: Der (virtuelle) Stift wird zur Position (x, y) gefahren.
+ Fehlerfälle:
+ * picture overflow
+ Zu viele Befehle in einem PICTURE (z. Zeit max. 1927 'moves')
+ * picture is three dimensional
+ Ein PICTURE kann nur entweder zwei- oder dreidimensional sein.
+
+ PROC move (PICTURE VAR pic, REAL CONST x, y, z)
+ Zweck: Der (virtuelle) Stift wird zur Position (x, y, z) gefahren.
+ Fehlerfälle:
+ * picture overflow
+ Zu viele Befehle in einem PICTURE (z. Zeit max. 1310)
+ * picture is only twodimensional
+ Ein PICTURE kann nur entweder zwei- oder dreidimensional sein.
+
+ PROC move (PICFILE VAR p, REAL CONST x, y)
+ Zweck: Der (virtuelle) Stift wird zur Position (x, y) gefahren. Falls
+ das aktuelle PICTURE des PICFILEs 'p' zu voll ist, wird auto-
+ matisch auf das nächste umgeschaltet.
+ Fehlerfall:
+ * picfile overflow
+ Das letzte PICTURE ist voll (z. Zeit max. 128 PICTUREs)
+
+ PROC move (PICFILE VAR p, REAL CONST x, y, z)
+ Zweck: Der (virtuelle) Stift wird zur Position (x, y, z) gefahren. Falls
+ das aktuelle PICTURE des PICFILEs 'p' zu voll ist, wird auto-
+ matisch auf das nächste umgeschaltet.
+ Fehlerfall:
+ * picfile overflow
+ Das letzte PICTURE ist voll (z. Zeit max. 128 PICTUREs)
+
+nilpicture
+ PICTURE PROC nilpicture
+ Zweck: Die Prozedure liefert ein leeres PICTURE zur Initialisierung.
+
+oblique
+ PROC oblique (PICFILE VAR p, REAL CONST a, b)
+ Zweck: Bei dem (dreidimensionalen!) Bild 'p' wird 'schiefwinklig' als
+ gewünschte Projektionsart eingestellt. Dabei ist (a, b) der Punkt
+ in der X-Y-Ebene, auf den der Einheitsvector in Z-Richtung
+ abgebildet werden soll.
+
+orthographic
+ PROC orthographic (PICFILE VAR p)
+ Zweck: Bei dem (dreidimensionalen!) Bild 'p' wird "orthografisch" als
+ Projektionsart eingestellt. Bei der orthografischen Projektion
+ wird ein dreidimensionaler Körper mit parallelen Strahlen senk-
+ recht auf die Projektionsebene abgebildet.
+
+pen
+ INT PROC pen (PICTURE CONST pic)
+ Zweck: Liefert die Nummer des 'virtuellen Stifts'.
+
+ PICTURE PROC pen (PICTURE CONST pic, INT CONST pen)
+ Zweck: Liefert ein PICTURE mit dem Inhalt 'pic' und dem 'virtuellen
+ Stift' mit der Nummer 'pen'. Möglich sind die Nummern 1 - 16.
+ Fehlerfälle:
+ * PROC pen: pen [No] < 1
+ Der gewünschte Stift ist kleiner als 1.
+ * PROC pen: pen [No] > 16
+ Der gewünschte Stift ist größer als 16.
+
+perspective
+ PROC perspective (PICFILE VAR p, REAL CONST cx, cy, cz)
+ Zweck: Bei den dreidimensionalen PICTUREs des PICFILE's 'p' wird
+ "perspektivisch" als gewünschte Projektionsart eingestellt. Der
+ Punkt (cx, cy, cz) ist der Fluchtpunkt der Projektion, d.h. alle
+ Parallelen zur Blickrichtung schneiden sich in diesem Punkt.
+
+pic no
+ INT PROC pic no (PICFILE CONST p)
+ Zweck: Liefert die Nummer des aktuellen PICTUREs.
+
+picture file
+ DATASPACE PROC picture file (TEXT CONST name)
+ Zweck: Die Prozedur dient zur Assoziation eines benannten Datenraumes
+ mit einem PICFILE (s. Operator ':=').
+
+plot
+ PROC plot (TEXT CONST name)
+ Zweck: Der PICFILE mit dem Namen 'name' wird entspechend der angege-
+ benen Darstellungsart gezeichnet. Diese Parameter ('perspective',
+ 'orthographic', 'oblique', 'view', 'window' etc.) müssen vorher
+ eingestellt werden.
+ Fehlerfall:
+ * FILE does not exist
+ Es existiert kein PICFILE mit dem Namen 'name'
+
+ PROC plot (PICFILE VAR p)
+ Zweck: Der PICFILE 'p' wird entspechend der angegebenen Darstellungsart
+ gezeichnet. Diese Parameter müssen vorher eingestellt werden.
+
+
+ Zweidimensional:
+
+ obligat: 'window' (zweidimensional)
+ optional: 'view' (zweidimensional)
+ 'select pen'
+ 'viewport'
+
+ Dreidimensional:
+
+ obligat: 'window' (dreidimensional)
+ optional: 'view' (dreidimensional)
+ 'orthographic', 'perspective', 'oblique'
+ 'viewport'
+ 'select pen'
+
+put
+ PROC put (PICFILE VAR p, PICTURE CONST pic)
+ Zweck: Schreibt ein PICTURE in einen PICFILE und positioniert um eins
+ vor.
+ Fehlerfall:
+ * picfile overflow
+ Der PICFILE ist voll. (z. Z. max. 128 PICTURE)
+
+reset
+ PROC reset (PICFILE VAR p)
+ Zweck: Positioniert auf den Anfang eines Picfiles.
+
+rotate
+ PICTURE PROC rotate (PICTURE CONST pic, REAL CONST alpha)
+ Zweck: Das PICTURE 'pic' wird um den Punkt (0, 0) um den Winkel 'alpha'
+ (im Gradmaß) im mathematisch positiven Sinn gedreht.
+
+ PICTURE PROC rotate (PICTURE CONST pic, REAL CONST alpha, beta, gamma)
+ Zweck: Das dreidimensionale PICTURE 'pic' wird um den Winkel 'alpha',
+ 'beta' oder 'gamma' im mathematisch positiven Sinn gedreht. Der
+ Winkel 'alpha' dreht um die X-Achse, der Winkel 'beta' um die
+ Y-Achse und 'gamma' um die Z-Achse. Es darf dabei nur jeweils
+ ein Winkel von 0.0 verschieden sein. Alle Winkel werden im
+ Gradmaß angegeben.
+
+select pen
+ PROC select pen (PICFILE VAR p,
+ INT CONST pen, colour, thickness, linetype)
+ Zweck: Für die Darstellung des Bildes 'p' soll dem "virtuellen Stift"
+ 'pen' ein realer Stift zugeordnet werden, der möglichst die Farbe
+ 'colour' und die Dicke 'thickness' hat und dabei Linien mit dem
+ Typ 'line type' zeichnet. Es wird die beste Annäherung für das
+ Ausgabegerät für diese Parameter genommen. Dabei gelten folgende
+ Vereinbarungen:
+
+ Farbe: negative Farben setzten den Hintergrund, positive Farben
+ zeichnen im Vordergrund.
+
+ 0 Löschstift (falls vorhanden)
+ 1 Standardfarbe des Endgeräts (schwarz oder weiß)
+ 2 rot
+ 3 blau
+ 4 grün
+ 5 schwarz
+ 6 weiß > 20 nicht normierte Sonderfarben
+
+ Dicke: 0
+ Standardstrichstärke des Endgerätes > 0
+ Strichstärke in 1/10 mm
+
+ Typ:
+ 0 keine sichtbare Linie
+ 1 durchgängige Linie
+ 2 gepunktete Linie
+ 3 kurz gestrichelte Linie
+ 4 lang gestrichelte Linie
+ 5 Strichpunktlinie
+
+ Die hier aufgeführten Möglichkeiten müssen nicht an allen
+ grafischen Endgeräten vorhanden sein. Der geräteabhängige
+ Graphik-Treiber wählt jeweils die für ihn bestmögliche Annäherung.
+
+ Fehlerfälle:
+ * pen < 1
+ * pen > 16
+
+size
+ INT PROC size (PICFILE CONST p)
+ Zweck: Liefert die aktuelle Größe eines PICFILEs in Bytes.
+
+stretch
+ PICTURE PROC stretch (PICTURE CONST pic, REAL CONST xc, yc)
+ Zweck: Das PICTURE 'pic' wird in X-Richtung um den Faktor 'xc', in
+ Y-Richtung um den Faktor 'yc' gestreckt (bzw. gestaucht). Dabei
+ bewirkt der Faktor
+ c > 1 eine Streckung
+ 0 < c < 1 eine Stauchung
+ c < 0 zusätzlich eine Achsenspiegelung
+
+ PICTURE PROC stretch (PICTURE CONST pic, REAL CONST xc, yc, zc)
+ Zweck: Das dreidimensionale PICTURE 'pic' wird entsprechend den
+ angegeben Faktoren 'xc', 'yc' und 'zc' gestreckt. Wirkung s.o.
+
+translate
+ PICTURE PROC translate (PICTURE CONST pic, REAL CONST dx, dy)
+ Zweck: Das PICTURE 'pic' wird um 'dx' und 'dy' verschoben.
+ Fehlerfall:
+ * picture is threedimensional
+ 'pic' ist dreidimensional.
+
+ PICTURE PROC translate (PICTURE CONST pic, REAL CONST dx, dy, dz)
+ Zweck: Das PICTURE 'pic' wird um 'dx', 'dy' und 'dz' verschoben.
+ Fehlerfall:
+ * picture is twodimensional
+ Das PICTURE 'pic' ist zweidimensional
+
+two dimensional
+ PROC two dimensional (PICFILE VAR p)
+ Zweck: Setzt als Projektionsart zweidimensional.
+
+view
+ PROC view (PICFILE VAR p, REAL CONST alpha, phi, theta)
+ Zweck: Dreidimensionale Bilder werden häufig nicht direkt von vorne
+ dargestellt, sondern für die Betrachtung gedreht. Mit der Prozedur
+ 'view' kann diese Betrachtungsrichtung durch die Polarwinkel 'phi'
+ und 'theta' angegeben werden. Mit dem Winkel 'alpha' kann dann
+ das Bild um den Mittelpunkt der Zeichenfläche gedreht werden.
+ Dadurch kann ein Bild auch auf einem Terminal hochkant gestellt
+ werden. Voreingestellt ist 'phi = 0, theta = 0 und alpha = 0',
+ d.h. direkt von oben.
+
+ Im Gegensatz zu 'rotate' hat 'view' keine Wirkung auf das eigent-
+ liche Bild (PICFILE), sondern nur auf die gewählte Darstellung.
+ So addieren sich zwar aufeinanderfolgende "Rotationen", 'view'
+ aber geht immer von der Nullstellung aus. Auch kann das Bild
+ durch eine "Rotation" ganz oder teilweise aus oder in das Dar-
+ stellungsfenster ('window') gedreht werden. Bei 'view' verändern
+ sich die Koordinaten der Punkte nicht, d.h. das Fenster wird mit-
+ gedreht.
+
+viewport
+ PROC viewport (PICFILE VAR p,
+ REAL CONST hormin, hormax, vertmin, vertmax)
+ Zweck: Die Zeichenfläche auf dem Endgerät, auf dem das Bild dargestellt
+ werden soll, wird spezifiziert. Dabei wird sowohl die Größe als
+ auch die relative Lage der Zeichenfläche definiert. Der linke
+ untere Eckpunkt der physikalischen Zeichenfläche des Gerätes hat
+ die Koordinaten (0.0, 0.0). Die definierte Zeichenfläche erstreckt
+ sich
+
+ 'hormin' - 'hormax' in der Horizontalen,
+ 'vertmin' - 'vertmax' in der Vertikalen.
+
+ So liegt der linke untere Eckpunkt dann bei (hormin, vertmin), der
+ rechte obere bei (hormax, vertmax).
+
+ Damit sowohl geräteunabhängige als auch maßstabsgerechte
+ Zeichnungen möglich sind, können die Koordinaten in zwei Arten
+ spezifiziert werden :
+
+ a) Gerätekoordinaten
+ Die Koordinaten können Werte von 0.0 bis 2.0 annehmen. Dabei
+ hat die kürzere Seite der physikalischen Zeichenfläche defini-
+ tionsgemäß die Länge 1.0.
+
+ b) absolute Koordinaten
+ Die Werte werden in cm angegeben. Für die Maximalwerte sind
+ nur Werte größer als 2.0 möglich.
+
+ Voreingestellt ist
+
+ viewport (0.0, 1.0, 0.0, 1.0),
+
+ d.h. das größtmöglichste Quadrat, beginnend in der linken unteren
+ Ecke der physikalischen Zeichenfläche. In vielen Fällen wird
+ diese Einstellung ausreichen, so daß der Anwender kein eigenes
+ 'viewport' definieren muß.
+
+ Der Abbildungsmaßstab wird durch das Zusammenspiel von 'viewport'
+ und 'window' festgelegt (siehe dort). Dabei ist insbesondere
+ darauf zu achten, daß winkeltreue Darstellungen nur bei gleichem
+ X- und Y-Maßstab möglich sind. Da man oft quadratische Fenster
+ ('window') verwendet, wurde als Standardfall auch ein quadrati-
+ sches 'viewport' gewählt.
+
+where
+ PROC where (PICTURE CONST pic, REAL VAR x, y)
+ Zweck: Die aktuelle Stiftposition wird in 'x' und 'y' eingetragen.
+ Fehlerfall:
+ * picture is threedimensional
+ Das PICTURE 'pic' ist dreidimensional
+
+ PROC where (PICTURE CONST pic, REAL VAR x, y, z)
+ Zweck: Die aktuelle Stiftposition wird in 'x', 'y' und 'z' eingetragen.
+ Fehlerfall:
+ * picture is twodimensional
+ Das PICTURE 'pic' ist zweidimensional
+
+window
+ PROC window (PICFILE VAR p, REAL CONST x min, x max, y min, y max)
+ Zweck: Für die Darstellung eines zweidimensionalen Bildes wird das
+ darzustellende Fenster definiert. Alle Bildpunkte, deren X-Ko-
+ ordinaten im Intervall [x min, x max] und deren Y-Koordinaten im
+ Intervall [y min, y max] liegen, gehören zum definierten Fenster.
+ Vektoren, die über dieses Fenster hinausgehen, werden abge-
+ schnitten. Dieses Fenster wird auf die spezifizierte Zeichen-
+ fläche abgebildet. (Das ist standardmäßig das größtmögliche
+ Quadrat auf dem ausgewählten Gerät).
+
+ Der Darstellungsmaßstab ergibt sich als
+
+ x max - x min
+ -----------------------------------------
+ horizontale Seitenlänge der Zeichenfläche
+
+ y max - y min
+ -----------------------------------------
+ vertikale Seitenlänge der Zeichenfläche
+
+ Für eine winkeltreue Darstellung müssen X- und Y-Maßstab
+ gleich sein! Einfach können winkeltreue Darstellung erreicht
+ werden, wenn das Fenster eine quadratische Form hat. Die
+ Zeichenfläche ('viewport') ist dementsprechend als Quadrat vor-
+ eingestellt.
+
+ PROC window (PICFILE VAR p,
+ REAL CONST x min, x max, y min, y max, z min, z max)
+ Zweck: Für die Darstellung eines dreidimensionalen Bildes wird das darzu-
+ stellende Fenster definiert. Alle Bildpunkte, deren X-Koordinaten im
+ Intervall [x min, x max] und deren Y-Koordinaten im Intervall
+ [y min, y max] und deren Z-Koordinaten im Intervall [z min, z max]
+ liegen, gehören zum definierten Fenster. Dieses dreidimensionale
+ Fenster (Quader) wird entsprechend der eingestellten Projektions-
+ art (orthografisch, perspektivisch oder schiefwinklig) und den
+ Betrachtungswinkeln (s. 'view') auf die spezifizierte Zeichen-
+ fläche abgebildet. (Das ist standardmäßig das größtmögliche
+ Quadrat auf dem ausgewählten Gerät.) Linien, die außerhalb dieses
+ Quadrates liegen, werden abgeschnitten.
+
+ Anders als im zweidimensionalen Fall ist das Problem der Maßstäbe
+ nicht mehr nur durch das Zusammenspiel von 'window' und 'view-
+ port' zu beschreiben. Hier spielen auch Projektionsart und Dar-
+ stellungswinkel eine Rolle. Falls alle Darstellungswinkel den
+ Wert 0.0 haben, gilt das für den zweidimensionalen Fall gesagte
+ für die Ebene (y = 0.0) entsprechend.
+
+write is possible
+ BOOL PROC write is possible (PICTURE CONST pic, INT CONST space)
+ Zweck: Liefert 'TRUE', falls 'space' Bytes Platz in 'pic' vorhanden ist.
+
diff --git a/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil11 b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil11
new file mode 100644
index 0000000..cae9c50
--- /dev/null
+++ b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil11
@@ -0,0 +1,1072 @@
+ EUMEL-Benutzerhandbuch
+
+ TEIL 11: Utilities
+
+
+In diesem Teil werden einige Dienstprogramme aufgeführt. Diese Programme
+sind bei speziellen Anwendungen nützlich.
+
+
+
+1. Scanner
+
+Der Scanner zerlegt einen TEXT in Symbole bzw. "Tokens" entsprechend der
+ELAN-Sprachdefinition.
+
+Der Scanner kann benutzt werden, um festzustellen, welche Art von Symbolen
+in einem TEXT enthalten sind. Die Repräsentation der Symbole müssen dabei
+der ELAN-Syntax entsprechen. Folgende #ib#Symbole#ie# kann der Scanner
+erkennen:
+
+ - "tags", d.h. Namen,
+ - "bolds", d.h. Schlüsselworte,
+ - "number", d.h. INT oder REAL Zahlen,
+ - Operatoren,
+ - "delimiter", d.h. Begrenzer wie z.B. ";",
+ - und das Ende des Scan-Textes.
+
+
+Der Scanner überliest Kommentare und Leerzeichen zwischen den Symbolen.
+Der (erste) zu verarbeitende Text muß mit der Prozedur
+
+ scan
+
+in den Scanner "hineingesteckt" werden. Mit der Prozedur
+
+ next symbol
+
+wird das jeweils nächste Symbol des TEXTes geholt. Am Ende wird "end of scan"
+und als Symbol 'niltext' geliefert. Falls innerhalb eines TEXT-Denoters oder
+eines Kommentars "end of scan" auftritt, wird "within text" bzw. "within
+comment" gemeldet. Der Scan-Prozeß kann dann mit dem nächsten zu scannenden
+TEXT (der nächsten Zeile) fortgesetzt werden. Dafür wird nicht die Prozedur
+'scan', sondern
+
+ continue scan
+
+verwandt. Sie setzt im letzten Scan-Zustand (z.B. Kommentar oder TEXT-
+Denoter) wieder auf, so daß auch Folgen von TEXTen (Zeilen) wie z.B. Dateien
+leicht gescannt werden können.
+
+Mit den Prozeduren
+
+ scan (* meldet eine Datei zum scannen an *)
+ next symbol (* holt die Symbole *)
+
+kann man auch eine Datei nach ELAN-Symbolen untersuchen. Beispiel:
+
+ FILE VAR f :: ...
+ ...
+ scan (f); (* beginnt das Scanning in der nächsten Zeile *)
+ TEXT VAR symbol;
+ INT VAR type;
+ REP
+ next symbol (f, symbol, type);
+ verarbeite symbol
+ UNTIL type >= 7 END REP.
+
+Merke: Mit dem Scanner kann man einen ELAN-Text analysieren.
+
+
+
+Scanner-Kommandos
+
+continue scan
+ PROC continue scan (TEXT CONST scan text)
+ Zweck: Das Scanning soll mit 'scan text' fortgesetzt werden. Falls der
+ Scan-Vorgang beim vorigen 'scan text' innerhalb eines TEXT-
+ Denoters oder eines Kommentars abgebrochen wurde, wird er jetzt
+ entsprechend mit dem nächsten 'next symbol' fortgesetzt. Der
+ erste Teil-Scan einer Folge muß aber stets mit 'scan' einge-
+ leitet werden!
+
+next symbol
+ PROC next symbol (TEXT VAR symbol, INT VAR type)
+ Zweck: Holt das nächste Symbol. In "symbol" steht der TEXT des Symbols,
+ so z.B. die Ziffern eines INT-Denoters. Bei TEXT-Denotern
+ werden die führenden und abschließenden Anführungsstriche ab-
+ geschnitten. Leerzeichen oder Kommentare spielen in "tags" oder
+ "numbers" keine Rolle. Zwischen Symbolen spielen Leerzeichen
+ oder Kommentare keine Rolle. In "type" steht eine Kennzeichung
+ für den Typ des Symbols:
+
+ tag = 1 ,
+ bold = 2 ,
+ number = 3 ,
+ text = 4 ,
+ operator = 5 ,
+ delimiter = 6 ,
+ end of file = 7 ,
+ within comment = 8 ,
+ within text = 9 .
+
+ Wird Scan-Ende innerhalb eines Kommentars gefunden, so wird
+ 'niltext' und 'within comment' geliefert. Wird Scan-Ende inner-
+ halb eines TEXT-Denoters gefunden, so wird der schon analysierte
+ Teil des Denoters und 'within text' geliefert.
+
+ PROC next symbol (TEXT VAR symbol)
+ Zweck: s.o. Es wird aber nur der Text des Symbols (ohne Typ) geliefert.
+
+ PROC next symbol (FILE VAR f, TEXT CONST symbol)
+ Zweck: arbeitet wie obige Prozeduren, jedoch auf einen FILE.
+
+ PROC next symbol (FILE VAR f, TEXT CONST symbol, INT VAR type)
+ Zweck: arbeitet wie obige Prozeduren, jedoch auf einen FILE.
+
+scan
+ PROC scan (TEXT CONST scan text)
+ Zweck: Meldet einen 'scan text' für den Scanner zur Verarbeitung an.
+ Die Prozedur 'scan' muß vor dem ersten Aufruf von 'next symbol'
+ gegeben werden. Im Gegensatz zu 'continue scan' normiert 'scan'
+ den inneren Zustand des Scanners, d.h. vorherige Scan-Vorgänge
+ haben keinen Einfluß mehr auf das Scanning.
+
+ PROC scan (FILE VAR f)
+ Zweck: Wie obige Prozedur, jedoch auf einen FILE. Die zu scannende Zeile
+ ist die nächste Zeile im FILE 'f' ('scan' macht zuerst ein 'get-
+ line').
+
+
+
+2. Inspector
+
+Der Inspector stellt ein Hilfsmittel bei der Programmentwicklung dar.
+
+Der Inspector informiert über alle
+
+ - insertierten Prozeduren / Operatoren mit dem gleichen Namen
+ - Prozeduren / Operatoren / Typen, die ein Paket definiert
+ - bisher insertierten Pakete
+ - insertierten Prozeduren / Operatoren / Typen.
+
+Mit dem Aufruf von
+
+ help ("name")
+
+wird eine Liste aller Prozeduren / Operatoren, die 'name' heißen, auf dem
+Bildschirm ausgegeben. Die Liste ist paketweise sortiert unter Angabe des
+Paketnamens. Die Ausgabe erfolgt mit der Angabe der Parametertypen. Gibt es
+kein Objekt mit dem angegebenen Namen, so erscheint die Ausgabe
+
+ unbekannt: name
+
+Das Kommando
+
+ bulletin ("paket name")
+
+informiert über alle Objekte, die in der DEFINES-Liste des Pakets mit dem
+Namen "paket name" stehen. Die Ausgabe erfolgt wie beim list-Kommando.
+
+Eine gesamte Liste aller bisher insertierten Prozeduren/Operatoren/Typen
+erhält man mit dem Kommando
+
+ bulletin
+
+Bei diesen Funktionen ist (noch) zu beachten, daß Typen immer dem textmäßig
+vorhergehendem Paket zugeordnet werden. Der Grund hierfür liegt in der
+Behandlung abstrakter Datentypen im ELAN-Compiler. Eine Korrektur ist für
+spätere Auslieferungen geplant.
+
+Mit
+
+ packets
+
+werden die Namen aller bisher insertierten Pakete "gelistet".
+
+Merke: Mit 'help' kann man sich über verfügbare Prozeduren/Operatoren in-
+formieren.
+
+
+
+Inspector-Kommandos
+
+help
+ PROC help (TEXT CONST name)
+ Zweck: Listen aller Prozeduren / Operatoren mit dem Namen "name". Die
+ Ausgabe erfolgt direkt auf den Bildschirm.
+
+bulletin
+ PROC bulletin (TEXT CONST paket name)
+ Zweck: Listen aller in der DEFINES-Liste des Pakets mit dem Namen
+ "paket name".
+
+ PROC bulletin
+ Zweck: Es wird eine Liste aller bisher insertierter Objekte erstellt.
+ Diese Liste ist paketweise sortiert.
+
+packets
+ PROC packets
+ Zweck: Auflisten der Namen aller bisher insertierten Pakete.
+
+
+
+3. Lexikographische Vergleiche
+
+Die üblichen Operatoren für TEXTe arbeiten mit dem der Reihenfolge des EUMEL-
+Zeichencodes. Hier wird beschrieben, wie man lexikographische Vergleiche
+nach DIN erhält.
+
+Für TEXT-Vergleiche nach DIN 5007 gibt es die Operatoren
+
+ LEXEQUAL
+ LEXGREATER
+ LEXGREATEREQUAL
+
+Diese Operatoren vergleichen zwei TEXTE nach DIN 5007 mit folgenden
+Bedingungen:
+
+- Die Reihenfolge enspricht 'ABC...Z', wobei große und kleine Buchstaben
+ gleich behandelt werden.
+
+- Weitere Entsprechungen:
+ ö = oe, ä = ae, ü = ue
+ Ö = Oe, Ü = Ue, Ä = Ae,
+ Ä = ä, Ü = ü, Ö = ö,
+ ß = ss
+ Dadurch ist z.B.
+
+ "muß" LEXGREATER "Muster" --> FALSE
+ "Goethe" LEXEQUAL "Göthe" --> TRUE
+
+- Alle Sonderzeichen (außer " " und "-") werden ignoriert.
+
+- Ein Leerzeichen und ein Bindestrich zwischen Worten werden gleich behan-
+ delt. Beispiel:
+
+ "EUMEL System" LEXEQUAL "EUMEL-System" --> TRUE
+
+Anmerkung: Diese drei Operatoren sind - sofern die oben erwähnten Zeichen in
+den Operanden vorkommen - langsamer als die "normalen" TEXT-Vergleiche
+(=, >, <, usw.). Das liegt daran, daß die Operanden in solchen Fällen
+umgewandelt werden.
+
+
+
+Lexikographische Operatoren
+
+LEXEQUAL
+ BOOL OP LEXEQUAL (TEXT CONST l, r)
+ Zweck: Lexikographischer Vergleich von 'l' und 'r' auf Gleichheit.
+
+LEXGREATER
+ BOOL OP LEXGREATER (TEXT CONST l, r)
+ Zweck: Lexikographischer Vergleich von 'l' und 'r' auf "Grösser".
+
+LEXGREATEREQUAL
+ BOOL OP LEXGREATEREQUAL (TEXT CONST l, r)
+ Zweck: Lexikographischer Vergleich von 'l' und 'r' auf "Grösser Gleich".
+
+
+
+4. Der 'reporter'
+
+Das Programm 'reporter' dient zur Fehlersuche und/oder Lokalisierung von
+besonders häufig durchlaufenen Programmteilen. Zu diesem Zweck werden in ein
+Programm Prozeduraufrufe eingefügt, die veranlassen, daß bestimmte Informa-
+tionen (normalerweise Ablaufinformationen) in eine Datei (die TRACE-Datei)
+geschrieben werden.
+
+'reporter' ermöglicht
+
+a) Ablaufinformationen ("trace");
+b) Häufigkeitszählung ("frequency count");
+c) Programmunterbrechung bei Nichterfüllung einer Bedingung ("assertion").
+
+
+
+Installation von 'reporter'
+
+Das Programm befindet sich in der Datei 'reporter' und kann wie üblich in-
+sertiert werden. Jedoch muß es mit 'check off' übersetzt werden, damit keine
+Zeilennummern für 'reporter' generiert werden. Dies ist notwendig, damit die
+Zeilennummern des zu testenden Programms nicht mit den Zeilennummern des
+Programms 'reporter' verwechselt werden können. Beispiel:
+
+ check off; insert ("reporter"); check on
+
+
+
+Vorbereitungen
+
+Mit dem Kommando
+
+ generate reports ("testdatei")
+
+werden die oben erwähnten Prozeduraufrufe ('report') in das zu testende
+Programm, welches in der Datei 'testdatei' steht, geschrieben. Die Prozedur-
+aufrufe werden nach jedem Prozedur-, Operator- oder Refinement-Kopf
+eingefügt und erhalten den entsprechenden Namen als Parameter. Diese
+Prozeduraufrufe werden gekennzeichnet, damit sie von der Prozedur
+
+ eliminate reports ("testdatei")
+
+automatisch wieder entfernt werden können. Beispiel (für die eingefügten
+Prozeduraufrufe):
+
+ ...
+ PROC beispiel (INT CONST mist):
+ ##report ("beispiel");##
+ ...
+
+
+
+Automatische Ablaufinformationen
+
+Ist ein Programm mit 'generate reports' mit 'report'-Aufrufen versehen
+worden, kann es wie gewohnt übersetzt werden. Wird das Programm vom ELAN-
+Compiler korrekt übersetzt und dann gestartet, wird bei jedem Antreffen
+eines 'report'-Aufrufs der Parameter (Name der Prozedur, Operator oder
+Refinement) in eine Datei, die TRACE-Datei geschrieben. Die TRACE-Datei wird
+beim Programmlauf automatisch von 'reporter' unter dem Namen 'TRACE' einge-
+richtet.
+
+Mit Hilfe dieser Datei kann der Programmablauf verfolgt werden. Es ist damit
+auch möglich festzustellen, wo eine "Endlos-Rekursion" auftritt. Die Ablauf-
+informationen bestehen nur aus den Namen der angetroffenen Prozeduren und
+Refinements. Trotzdem können die Anzahl der Informationen sehr umfangreich
+werden. Deshalb gibt es die Möglichkeit, die Erzeugung der Ablaufinforma-
+tionen ab- bzw. wieder anzuschalten. Dazu gibt es die Möglichkeit, in das zu
+testende Programm die Prozeduren
+
+ report on
+ report off
+
+einzufügen und das zu testende Programm mit diesen Prozeduraufrufen (erneut)
+zu übersetzen.
+
+
+
+Benutzereigene Ablaufinformationen
+
+Zusätzlich zu den von 'generate reports' eingefügten 'report'-Aufrufen kann
+ein Benutzer eigene Aufrufe an geeigneten Stellen in ein Programm schreiben.
+Dafür werden weitere 'report'-Prozeduren zur Verfügung gestellt, die als
+ersten Parameter ein TEXT-Objekt (meist Name des Objekts oder der Ausdruck
+selbst) und als zweiten ein INT/REAL/TEXT/ BOOL-Objekt (der zu überprüfende
+Wert oder Ausdruck) enthalten. Beispiel:
+
+ ...
+ PROC beispiel (INT CONST mist):
+ ##report ("beispiel");## (* automatisch eingefuegte *)
+ INT VAR mist :: ...; ...
+ ##report ("mist:", mist);## (* vom Benutzer per Hand eingefuegt *)
+ ...
+
+Folgende 'report'-Routinen stehen zur Verfügung, damit man sie "von Hand" in
+ein zu testendes Programm einfügen kann:
+
+ PROC report on
+ PROC report off
+ PROC report (TEXT CONST message)
+ PROC report (TEXT CONST message, INT CONST value)
+ PROC report (TEXT CONST message, REAL CONST value)
+ PROC report (TEXT CONST message, TEXT CONST value)
+ PROC report (TEXT CONST message, BOOL CONST value)
+
+Wichtig: Hier - wie bei allen anderen "von Hand eingefügten" Aufrufen -
+sollte ein Nutzer sich an die Konvention halten, diese in "##" einzuklammern.
+Mit 'eliminate reports' werden diese Einfügungen automatisch entfernt.
+Sollen diese Aufrufe aber immer im Programm erhalten bleiben (jedoch nicht
+wirksam sein), sollten sie
+
+a) vor 'generate reports'-Aufruf mit jeweils '###' eingefaßt werden.
+ Beispiel:
+ ### report ("...") ###
+ So steht das 'report'-Statement in einem Kommentar. 'generate reports'
+ wandelt '###' --> '####' um, so daß ein solches Statement wirksam wird.
+ 'eliminate reports' wandelt ein '####' --> '###' zurück.
+
+b) nach 'generate reports' in '####' eingefaßt werden.
+
+
+
+Häufigkeitszählung
+
+Eine Häufigkeitszählung erhält man, in dem man in das zu testende Programm
+die Aufrufe
+
+ count on
+ count off
+
+einfügt. Ist die Häufigkeitszählung eingeschaltet, merkt sich 'reporter' die
+Anzahl der Durchläufe für jede Prozedur bzw. Refinement. Mit der Prozedur
+
+ generate counts ("zu testende datei")
+
+werden die vermerkten Häufigkeiten in das zu testende Programm direkt einge-
+fügt. Die Häufigkeiten werden wie oben beschrieben gekennzeichnet, so daß sie
+mit 'eliminate reports' entfernt werden können.
+
+
+
+Assertions
+
+Zusätzlich zu den oben erwähnten Möglichkeiten bietet 'reporter' noch die
+Prozedur
+
+ assert
+
+an. Diese Prozedur kann von einem Programmierer an einer Stelle in das zu
+testende Programm eingefügt werden, an der bestimmte Bedingungen erfüllt sein
+müssen. Die Prozedur 'assert' steht in zwei Formen zur Verfügung:
+
+ PROC assert (BOOL CONST zusicherung)
+ PROC assert (TEXT CONST message, BOOL CONST zusicherung)
+
+Ist der Wert von 'zusicherung' nicht TRUE, wird der Programmlauf abgebrochen.
+
+
+
+'reporter'-Kommandos
+
+count on
+ PROC count on
+ Zweck: Schaltet die Häufigkeitszählung ein.
+
+count off
+ PROC count off
+ Zweck: Schaltet die Häufigkeitszählung aus.
+
+eliminate reports
+ PROC eliminate reports (TEXT CONST datei)
+ Zweck: Entfernt gekennzeichnete 'report'-Aufrufe aus der Datei 'datei'.
+
+generate reports
+ PROC generate reports (TEXT CONST datei)
+ Zweck: Fügt 'report'-Aufrufe in die Datei 'datei' ein und kennzeichnet
+ diese mit '##'.
+
+report on
+ PROC report on
+ Zweck: Schaltet die Ablaufinformationen in die Datei 'TRACE' ein.
+
+report off
+ PROC report off
+ Zweck: Schaltet die Ablaufinformationen wieder aus.
+
+generate counts
+ PROC generate counts (TEXT CONST datei)
+ Zweck: Bringt die Häufigkeitszählung (wie oft eine Prozedur oder Refine-
+ ment durchlaufen wurde) in die Programmdatei 'datei'. Mit
+ 'eliminate reports' werden diese wieder automatisch entfernt.
+
+assert
+ PROC assert (TEXT CONST message, BOOL CONST value)
+ Zweck: Schreibt 'message' und den Wert von 'value' in die TRACE-Datei.
+ Ist 'value' FALSE, wird angefragt, ob das Programm fortgesetzt
+ werden soll.
+
+
+
+5. Referencer
+
+Das Programm 'referencer' erstellt aus einem (syntaktisch korrektem) ELAN-
+Programm eine Liste, in der jedes Auftreten eines Objekts mit der betref-
+fenden Zeilennummer verzeichnet ist.
+
+ 'referencer' wird durch
+
+ referencer ("ref datei", "referenz liste")
+
+aufgerufen, wobei die Datei 'referenz liste' nicht existieren darf.
+'referenz liste' enthält nach Ablauf des Programms die gewünschte Liste, die
+sogenannte Referenzliste.
+
+Achtung: 'referencer' arbeitet ausschließlich mit Namen und verarbeitet nur
+wenige syntaktische Konstrukte. Darum ist es nur erlaubt, ein PACKET auf
+einmal von 'referencer' verarbeiten zu lassen. Verarbeitet man mehrere
+PACKETs auf einmal, kann es geschehen, daß gleichnamige Objekte in unter-
+schiedlichen Paketen zu Warnungen (vergl. die unten beschriebenen Überprü-
+fungen) führen.
+
+In der Referenzliste sind
+
+- alle Objekte mit ihrem Namen (in der Reihenfolge ihres Auftretens im
+ Programm)
+
+- alle Zeilennummern, in der das Objekt angesprochen wird
+
+- die Zeilennummern, in der das Objekt deklariert wurde ('L' für ein lokales
+ und 'G' für ein globales Objekt, 'R' für ein Refinement)
+
+verzeichnet.
+
+Die Referenzliste kann u.a. dazu dienen, zu kontrollieren, ob und wie (bzw.
+wo) ein Objekt angesprochen wird. Dies lohnt sich selbstverständlich nur bei
+etwas umfangreicheren Programmen (bei "Mini"-Programmen kann man dies sofort
+sehen).
+
+Bei der Erstellung der Referenzliste nimmt das Programm 'referencer' gleich-
+zeitig einige Überprüfungen vor, die helfen können, ein Programm zu ver-
+bessern:
+
+1. Warnung bei mehrzeiligen Kommentaren.
+
+2. Überdeckungsfehler. Wird ein Objekt global (auf PACKET-Ebene) und noch-
+ mals lokal in einer Prozedur deklariert, ist das globale Objekt nicht mehr
+ ansprechbar. Überdeckungen sind nach der gültigen Sprachdefinition z.Zt.
+ noch erlaubt, werden aber bei einer Revision des Sprachstandards verboten
+ sein.
+
+3. Mehrmaliges Einsetzen von Refinements. Wird ein Refinement mehrmals einge-
+ setzt (das ist völlig legal), sollte man überlegen, ob sich dieses Refine-
+ ment nicht zu einer Prozedur umgestalten läßt.
+
+4. Nicht angewandte Refinements. Wird ein Refinement zwar deklariert, aber
+ nicht "aufgerufen", erfolgt eine Warnung.
+
+5. Nicht angesprochene Daten-Objekte. Werden Daten-Objekte zwar deklariert,
+ aber im folgenden nicht angesprochen, wird eine Warnung ausgegeben.
+ Hinweis: Alle Objekte, die nur wenig angesprochen werden, also nur wenige
+ Zeilennummern in der Referenzliste besitzen, sind verdächtig (Ausnahmen:
+ importierte Prozeduren, LET-Objekte u.a.m.).
+
+
+
+'referencer'-Kommandos
+
+referencer
+ PROC referencer (TEXT CONST check file, dump file)
+ Zweck: Überprüft 'check file'. In 'dump file' steht nach Abschluß die
+ Referenzliste.
+
+
+
+6. Notizen (Notizbuch, Fehlerprotokoll)
+
+Das Notizbuch erlaubt es u.a., Fehlermeldungen zwischenzeitig zu speichern
+und am Ende einer Verarbeitung die Fehlermeldungen zusammen mit dem bear-
+beiteten Text im Paralleleditor anzuzeigen.
+
+Das Notizbuch wird eingesetzt, wenn Texte bearbeitet werden, die gewissen
+Regeln entsprechen müssen (Beispiele: ELAN-Compiler, Textkosmetik usw.). In
+solchen Fällen ist es nützlich, die Fehlermeldungen zwischenzeitig zu
+speichern und erst am Ende einer Verarbeitung gesammelt dem Benutzer zusam-
+men mit dem Quelltext anzuzeigen. Diese Aufgaben übernimmt das Notizbuch.
+Mit der Prozedur
+
+ note
+
+kann eine Meldung im Notizbuch gespeichert werden. Mit
+
+ note line
+
+wird der Beginn einer neuen Zeile im Notizbuch signalisiert. Das bedeutet,
+daß ein Programmierer für alle Zeilenvorschübe in der Fehlermeldungsdatei mit
+dieser Prozedur zu sorgen hat.
+
+Mit der Informationsprozedur
+
+ anything noted
+
+kann man am Ende einer Verarbeitung abfragen, ob Fehlermeldungen gespeichert
+wurden. Ist das der Fall, kann man den Paralleleditor aufrufen:
+
+ note edit
+
+In der oberen Hälfte werden die Fehlermeldungen dargestellt, in der unteren
+den zu bearbeitenden Text. Beispiel:
+
+ PROC verarbeite (TEXT CONST datei):
+ FILE VAR f :: sequential file (input, datei);
+ verarbeitung;
+ ende behandlung.
+
+ verarbeitung:
+ ...
+ note (fehlermeldung);
+ note line.
+
+ ende behandlung:
+ IF anything noted
+ THEN note edit (f)
+ FI
+ END PROC verarbeite
+
+
+
+Notizbuch-Kommandos
+
+anything noted
+ BOOL PROC anything noted
+ Zweck: Informationsprozedur, ob etwas in das Notizbuch geschrieben wurde.
+
+note edit
+ PROC note edit
+ Zweck Bewirkt das Anzeigen des Notizbuchs auf vollem Bildschirm.
+
+ PROC note edit (FILE VAR f)
+ Zweck: Anzeigen des Notizbuchs und der Datei 'f' durch den Parallel-
+ editor.
+
+note file
+ FILE PROC note file
+ Zweck: Assoziierungsprozedur. Liefert das Notizbuch.
+
+note line
+ PROC note line
+ Zweck: Zeilenvorschub im Notizbuch.
+
+note
+ PROC note (TEXT CONST meldung)
+ Zweck: Schreibt 'meldung' in das Notizbuch.
+
+ PROC note (INT CONST zahl)
+ Zweck: Schreibt 'zahl' als TEXT in das Notizbuch (analog 'put').
+
+
+
+7. Sortier-Programme
+
+Es stehen zwei verschiedene Sortier-Programme zur Verfügung: 'sort'
+(Sortierung nach ASCII-Reihenfolge) und 'lex sort' (Sortierung nach
+deutschem Alphabet).
+
+Das Kommando
+
+ sort ("datei")
+
+sortiert 'datei' zeilenweise. Beispiel:
+
+ Eingabe-Datei:
+ Berta ist eine Frau.
+ Adam ist ein Mann.
+ ...
+ Sortierte Datei:
+ Adam ist ein Mann.
+ Berta ist eine Frau.
+ ...
+
+Dabei werden die Zeilen-Anfänge solange zeichenweise miteinander verglichen,
+bis ein Unterschied auftritt und dann ggf. umgeordnet. Werden zwei ungleich
+lange Zeilen (Anzahl Zeichen/Zeile) miteinander verglichen, dann kann man
+sich die kürzere Zeile mit Leerzeichen auf die Länge der längeren Zeile
+verlängert denken.
+
+Die Reihenfolge, in der die Zeilen sortiert werden, erfolgt nach dem ASCII-
+Zeichensatz in aufsteigender Reihenfolge (vergl. TEIL 3; EUMEL-Zeichencode):
+
+ Leerzeichen
+ einige Sonderzeichen
+ Ziffern
+ einige Sonderzeichen
+ Große Buchstaben
+ einige Sonderzeichen
+ kleine Buchstaben
+ einige Sonderzeichen
+ Umlaute und ß
+
+Das bedeutet, daß z.B. folgendermaßen sortiert wird:
+
+ Adam
+ Ball
+ Zuruf
+ aber das ist ein Satz
+ niemals
+ Überlauf
+
+Um zu erreichen, daß große und kleine Buchstaben gleichwertig behandelt
+werden, kann man das Kommando
+
+ lex sort ("datei")
+
+geben. In diesem Fall würde die sortierte Datei folgendermaßen aussehen:
+
+ aber das ist ein Satz
+ Adam
+ Ball
+ niemals
+ Überlauf
+ Zuruf
+
+Man beachte, daß der Umlaut 'Ü' wie 'Ue' behandelt wird (für die restlichen
+Umlaute gilt eine analoge Behandlung; ebenso wird 'ß' wie 'ss' behandelt).
+Weiterhin werden alle Sonderzeichen bei der Sortierreihenfolge ignoriert.
+
+
+
+Sortier-Kommandos
+
+sort
+ PROC sort (TEXT CONST datei)
+ Zweck: Die Prozedur 'sort' sortiert die Datei 'datei' zeilenweise. Die
+ Sortierung erfolgt nach der Ordnung, die der EUMEL-Zeichencode
+ vorschreibt. Beispielsweise werden Zeilen ("Sätze"), die mit
+ Ziffern beginnen, vor Sätzen, die mit Buchstaben anfangen, ein-
+ geordnet. Sätze, die mit großen Buchstaben beginnen, werden vor
+ Sätzen mit kleinen Buchstaben einsortiert. Weiterhin werden die
+ Umlaute und das "ß" nach allen anderen Buchstaben eingeordnet.
+
+ PROC sort (TEXT CONST datei, INT CONST anfang)
+ Zweck: Sortiert eine Datei wie obige Prozedur, jedoch wird bei der
+ Sortierung nicht der Anfang eines Satzes beachtet, sondern die
+ Position 'anfang'.
+
+lex sort
+ PROC lex sort (TEXT CONST datei)
+ Zweck: Wie 'sort', jedoch nach (deutscher) lexikographischer Reihen-
+ folge nach DIN 5007. Bei den Vergleichen werden die Operatoren
+ LEXEQUAL, LEXGREATER, LEXGREATEREQUAL (vergl. TEIL 11 des
+ Benutzerhandbuchs) verwandt. Anmerkung: 'lex sort' ist um
+ einiges langsamer als 'sort'.
+
+ PROC lex sort (TEXT CONST datei, INT CONST anfang)
+ Zweck: Wie 'lex sort', jedoch wird bei der Sortierung bei 'anfang'
+ jeder Zeile begonnen.
+
+
+
+8. Rechnen im Editor: TeCal
+
+Das Programm TeCal (Abkürzung für "Text Calculator") ermöglicht das einfache
+Rechnen im EUMEL-Editor.
+
+Das Programm TeCal ermöglicht einfache Rechnungen (ähnlich wie mit einem
+Taschenrechner) unter der Benutzung des Editors. Gleichzeitig stehen dem
+Benutzer aber alle Fähigkeiten des Editors zur Verfügung. TeCal ermöglicht
+Rechnungen auf einfache Weise zu erstellen oder Tabellenspalten zu berechnen.
+
+TeCal wird aus dem Editor heraus durch 'ESC t' oder durch das Editor-
+Kommando
+
+ tecal
+
+aktiviert. (Anmerkung: TeCal ist nicht standardmäßig insertiert). Dadurch
+wird in der untersten Zeile des Bildschirms eine Informationszeile aufgebaut,
+in der die (Zwischen-) Ergebnisse einer Rechnung zur Kontrolle festgehalten
+werden.
+
+Merke: TeCal ermöglicht einfache Rechnungen im EUMEL-Editor.
+
+
+
+Ein einfaches Beispiel
+
+Angenommen, Prokurist Meier der Firma 'Software Experts' muß eine Rechnung
+schreiben. Er schreibt u.a.:
+
+ ...
+ Wir berechnen Ihnen
+
+ 1 Manual 'Software Auswahl leicht gemacht' 112.30 DM
+ 1 Manual 'Ohne Fehler programmieren' 300.-
+
+ Summe
+
+Nun kann er die TeCal-Funktionen durch
+
+ ESC t
+
+zuschalten. (Natürlich kann TeCal auch schon während des Schreibens einge-
+schaltet sein, das Editorfenster ist dann nur um eine Zeile (nämlich die
+TeCal-Informationszeile) kürzer. Zuerst löscht Prokurist Meier eventuell
+vorhandene Zwischenergebnisse von TeCal (TeCal vergißt eine angefangene
+Rechnung durch Abschalten nicht!) mit
+
+ ESC C
+
+Das funktioniert wie eine CLEAR-Taste bei einem Taschenrechner, löscht also
+ggf. vorhandene Werte. In der Informationszeile (die letzte Zeile des Bild-
+schirms) erscheint darum als Wert '0.0'.
+
+Nun "fährt" er mit dem Cursor auf den ersten Wert ('112.30'). Dabei ist es
+belanglos, welche Ziffer er "trifft". Dann betätigt er
+
+ ESC L
+
+(für Lesen). Damit erscheint dieser Wert in der Informationszeile. Durch
+'ESC L' wird versucht, einen Wert von der Stelle aus der Datei zu lesen, die
+durch den Cursor angezeigt wird. (Gelingt dies nicht, erfolgt in der
+obersten Zeile eine Fehlermeldung). Dann betätigt er
+
+ ESC +
+
+weil er ja die zwei Werte addieren will. Das Zwischenergebnis in der TeCal-
+Informationszeile bleibt dadurch unverändert. Jetzt fährt er auf den zweiten
+Wert und betätigt erneut 'ESC L'. Nun erscheint der zweite Wert in der An-
+zeige. Um das Ergebnis der Rechnung zu erfahren, betätigt er
+
+ ESC =
+
+Die Summe der zwei Zahlen erscheint nun in der Informationszeile. Nun fährt
+er mit dem Cursor auf die Stelle, an der die Summe stehen soll und betätigt
+hier
+
+ ESC S
+
+(für Schreiben). Damit erscheint die eben errechnete Summe (412.30) an dieser
+Stelle der Datei.
+
+Man bedient TeCal also wie einen Taschenrechner. Man muß allerdings, um die
+Rechentasten zu bedienen, ESC zuvor drücken. Dies ist notwendig, um die
+"normalen" Tasten von den TeCal-Tasten zu unterscheiden.
+
+Merke: Mit einigen einfachen Tastendrücken können Berechnungen vorgenommen
+werden. 'ESC L' liest einen Wert von der aktuellen Cursor-Position, 'ESC S'
+schreibt den angezeigten TeCal-Wert an die aktuelle Cursor-Position. 'ESC C'
+löscht alle Werte im TeCal-Rechner.
+
+
+
+Einige weitere einfache Rechenoperationen
+
+In diesem Abschnitt werden weitere einfache Operationen von TeCal be-
+schrieben.
+
+Natürlich kann man mit TeCal nicht nur Addieren. Die folgenden Operationen
+laufen analog 'ESC +':
+
+ ESC - (Subtrahieren)
+ ESC * (Multiplizieren)
+ ESC / (Dividieren)
+
+Beispiel:
+
+ ...
+ Wir berechnen Ihnen
+
+ Artikelbezeichnung Anzahl Einzelpreis Summe
+
+ Schraube, verdreht 27 1.05 28.35
+
+ Gesamt 28.35
+
+Dazu drückt Prokurist Meier folgende Tasten:
+
+ Cursor auf Taste TeCal-Anzeige
+
+ 27 ESC C 0.00
+ unverändert ESC L 27.00
+ unverändert ESC * 27.00
+ 1.05 ESC L 1.05
+ unverändert ESC = 28.35
+ unter Summe ESC S 28.35
+ in Gesamtzeile ESC S 28.35
+
+Wie wir sehen, kann Prokurist Meier jederzeit seine Eingaben kontrollieren
+mit Hilfe der TeCal-Informationszeile.
+
+Anmerkung:
+
+'ESC S' schreibt den aktuellen Wert wie der Dezimal-Tabulator des Editors
+(vergleiche Kapitel Editor). Die Stelle, an der der Cursor steht, wird beim
+Schreiben die letzte Stelle vor dem Dezimalpunkt. Ziffern vor dem Dezimal-
+punkt werden also nach links, Ziffern nach dem Dezimalpunkt nach rechts ge-
+schrieben.
+
+Merke: ESC mit den Tasten '-', '+', '*' und '/' haben die gewohnte Wirkung.
+
+
+
+Die Verwendung von Klammern
+
+TeCal erlaubt bei Rechnungen die Eingabe von Klammern.
+
+Beispiel (wir haben hier die Taste ESC fortgelassen):
+
+ 2 * (3 + 5) = 16.00
+
+Merke: Klammern können bei Rechnungen beliebig verwendet werden.
+
+
+
+Der Prozent-Operator
+
+Angenommen, wir wollen 14 Prozent von 200 DM errechnen. Dann können wir wie
+gewohnt verfahren (für bessere Lesbarkeit zeigen wir hier für 'ESC L' den
+jeweiligen Wert):
+
+ 200 ESC % ESC =
+
+Der Prozent-Operator berechnet immer einen eingestellten Prozentsatz von dem
+gerade angezeigten Zwischenergebnis. Der eingestellte Prozentsatz wird in der
+Informationszeile angezeigt. Er läßt sich mit Hilfe des Kommandos
+
+ prozentsatz ('prozentzahl')
+
+verändern.
+
+Was müssen wir machen, um die 14 Prozent von 200 auf den Wert von 200 zu
+addieren? Ganz einfach:
+
+ 200 ESC + ESC % ESC =
+
+Wie wir solche Tastensequenzen einfacher erledigen können, zeigen wir in
+einem späteren Abschnitt.
+
+Merke: Der Prozent-Operator berechnet immer den eingestellten Prozentanteil
+vom angezeigten Wert.
+
+
+
+Spaltenweise summieren
+
+Da es beim Schreiben von Rechnungen o.ä. häufig vorkommt, daß eine ganze
+Zahlenkolonne addiert werden soll, besitzt TeCal eine Sonderfunktion, die es
+dem Benutzer erspart, mit dem Cursor auf jeden einzelnen Wert zu fahren und
+'ESC L' sowie 'ESC +' zu drücken. Durch
+
+ ESC V
+
+addiert TeCal zu der Zahl, auf der der Cursor steht alle, die in gerader
+Linie darüberstehen, solange bis eine Zeile gefunden wird, in der Text oder
+andere Zeichen stehen, die nicht zu einer Zahl gehören. Leerzeichen führen
+also nicht zum Abbruch der Rechnung. Nehmen wir an, Prokurist Meier hätte
+seine Rechnung soweit fertig :
+
+ ...
+ Wir berechnen Ihnen
+
+ Artikelbezeichnung Anzahl Einzelpreis Summe
+
+ Schraube, verdreht 27 1.05 28.35
+ Nagel, m. Kopf 33 0.50 16.50
+ Hammer, Spezialausführung m.
+ Eichenholzgriff 1 44.70 44.70
+ --------
+
+Um nun die Gesamtsumme zu berechnen fährt er einfach mit dem Cursor auf die
+unterste Zahl (44.70) und betätigt ESC V. In der Anzeige steht direkt die
+Gesamtsumme, die dann mit ESC S unter dem Strich eingetragen werden kann.
+
+Merke: Zahlenkolonnen können mit ESC V summiert werden.
+
+
+
+Direkte Eingabe
+
+Es kann ein Wert direkt in die Berechnung eingehen, ohne daß er vorher in
+der Datei stehen muß.
+
+Durch das Betätigen von
+
+ ESC E
+
+erscheint 'gib wert :' in der TeCal-Informationszeile. Nun kann ein Wert
+(wie im Editor) eingegeben werden, zugelassen ist auch ein ganzer Ausdruck
+wie z.B.
+
+ (3.00 DM + 5.00 DM) * 365 Tage - 2,00 DM * 12 Monate
+
+Dabei sind auch Buchstaben erlaubt, die aber überlesen werden. Betätigt man
+RETURN, wird der Ausdruck ausgewertet und der Wert in die Anzeige über-
+nommen. Für das oben gezeigte Beispiel steht die Anzeige also anschließend
+auf 2896. Auf diese Weise kann man auch einfach Zwischenrechnungen machen,
+ohne daß die verwendeten Zahlen irgendwo in der Datei stehen. Das Ergebnis
+kann man dann weiter verrechnen, als wäre es mit ESC L aus der Datei gelesen
+worden. Natürlich kann man es auch direkt mit ESC S in die Datei schreiben.
+
+Merke: Mit ESC E wird ein Wert direkt in TeCal aufgenommen. Durch Eingabe
+eines ganzen Rechenausdrucks lassen sich leicht auch Rechnungen durchführen,
+ohne daß die Zahlen in einer Datei stehen.
+
+
+
+TeCal und Lernen im Editor
+
+Bei sich wiederholenden Rechnungen ist es sinnvoll, Rechenoperationen "zu
+lernen" und auf eine Taste zu legen.
+
+Angenommen, Prokurist Meier hat häufig Rechnungen zu schreiben und muß des
+öfteren die Mehrwertsteuer und Bruttopreis unter die jeweiligen Nettopreise
+schreiben. Zu diesem Zweck kann er die "Lern"-Einrichtung des Editors
+benutzen (vergl. EUMEL-Benutzerhandbuch: Editor). Beim Lernen "merkt" sich
+der Editor jeden Tastendruck (also auch TeCal-Operationen). Die gelernten
+Tasten kann man anschließend mit einem Tastendruck abrufen. Meier kann die
+Operationen wie folgt vom Editor lernen lassen:
+
+Er fährt mit dem Cursor zuerst auf den Nettopreis, von der die Mehrwertsteuer
+errechnet werden soll. Dann betätigt er ESC HOP (es erscheint LEARN in der
+Kopfzeile des Editors). Dann schreibt er die TeCal-Operationen wie oben
+gezeigt (in diesem Falle also ESC L ESC + ESC % ; dann steht der Mehrwert-
+steuerbetrag in der Anzeige. Er fährt also mit dem Cursor eine Zeile tiefer
+und betätigt ESC S, dann geht er noch eine Zeile tiefer und gibt ESC = und
+wiederum ESC S um den Bruttobetrag zu berechnen und zu schreiben. Mit dem
+abschließenden ESC HOP und einer weiteren Taste (sagen wir mal 'm' als
+Abkürzung für Mehrwert) beendet er das Lernen. Nun kann er jederzeit die
+Mehrwertsteuer und Bruttobetrag unter einen gegebenen Nettobetrag schreiben,
+indem er ESC m betätigt.
+
+Praktischer Tip:
+
+Tabulator-Bewegungen kann man ebenfalls lernen. So ist es z.B. möglich, die
+Berechnung von Spalten- oder Reihensummen zu erlernen, indem man mit
+TAB jeweils zu dem nächsten Wert springt.
+
+Merke: Es können beliebige Rechnungen erlernt und auf eine Taste gelegt
+werden. Die gelernten Rechnungen können mit Hilfe einer Taste abgerufen
+werden.
+
+
+
+Benutzung des Merkregisters
+
+Mit
+
+ ESC M
+
+(für Merken) kann man ein gerade angezeigtes (Zwischen-) Ergebnis im
+Speicher aufbewahren, um es später an anderer Stelle wieder in die Rechnung
+einzubeziehen. Das geschieht, in dem man dann statt eine Zahl mit ESC L
+einzulesen
+
+ ESC K
+
+(für Konstante) eingibt. Dadurch wird die Zahl aus dem Merkregister wieder
+in die Anzeige übertragen, so daß man damit weiterrechnen kann.
+
+Merke: Man kann Zahlen mit ESC M abspeichern und mit ESC K wiederholen.
+
+
+
+Auskunft über TeCal-Funktionen
+
+Wenn Sie beim Arbeiten mit TeCal noch nicht so sicher sind oder eine Funktion
+benutzen möchten, die Sie sonst nur selten verwenden und deren genaue
+Wirkung sie vielleicht wieder vergessen haben, so hilft Ihnen
+
+ ESC ?
+
+weiter. Nach betätigen dieser Tasten meldet sich die TeCal Auskunft mit
+Funktionstaste drücken oder <?>. Dann geben Sie das Funktionssymbol ein, das
+Sie erklärt bekommen möchten. Geben Sie z.B. ein C ein, wenn Sie die Wirkung
+von ESC C wissen möchten. Daraufhin wird ein Text gezeigt, in dem die
+entsprechende Auskunft steht. In diesem Text können Sie sich wie im Editor
+bewegen. Wenn Sie den Text gelesen haben, können Sie das Fenster wieder mit
+ESC Q verlassen. Dadurch wird der alte Zustand vor der Auskunftsfunktion
+wiederhergestellt. Durch
+
+ ESC ? ?
+
+erklärt sich die Auskunft selbst. Sie bekommen dort unter anderem die Liste
+aller TeCal-Funktionen gezeigt.
+
+Merke: Mit ESC ? erhält man Auskünfte über TeCal-Funktionen.
+
+
+
+Einstellen von Nachkommastellen
+
+Durch das Kommando
+
+ kommastellen ('zahl')
+
+wird die Anzahl der angezeigten Nachkommastellen (0-9) eingestellt. Genau so
+viele Nachkommastellen werden auch bei ESC S oder ESC T geschrieben (intern
+wird aber jeweils mit höchster Genauigkeit gerechnet). Mit
+
+ ESC R
+
+kann man ein angezeigtes Zwischenergebnis auch intern auf die angezeigte Zahl
+von Nachkommastellen runden. Beispiel:
+
+ ESC ( 1 ESC / 3 ESC ) ESC * 2 ESC=
+
+führt zur Anzeige von 0.67 (bei zwei eingestellten Nachkommastellen). Gibt
+man jetzt (aber nach ESC ) noch ESC R ein, so wird das Zwischenergebnis von
+1/3 auf 0.33 gerundet, so daß das Endergebnis 0.66 beträgt.
+
+Merke: Im Kommandomodus kann man durch das Kommando 'kommastellen' die An-
+zahl der Nachkommastellen einstellen.
+
diff --git a/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil12 b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil12
new file mode 100644
index 0000000..ba5d0c6
--- /dev/null
+++ b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil12
@@ -0,0 +1,234 @@
+ EUMEL-Benutzerhandbuch
+
+ TEIL 12: SPOOLER / OPERATOR
+
+1. Spooler-Übersicht
+
+Ein "Spooler" ist eine Warteschlange von Datenräumen#ie# (Dateien) vor einem
+"Worker":
+
+ +------------+ +------------+
+ -----> | | | |
+ -----> | spooler | ------------> | worker |
+ -----> | | | |
+ +------------+ +------------+
+
+Der Spooler puffert Dateien, die von beliebigen Tasks geschickt werden kön-
+nen, in seiner Warteschlange und gibt sie der Reihe nach dem Worker zur
+eigentlichen Verarbeitung. Ein typischer Einsatzfall (aber nicht der einzige)
+für ein solches System ist der EUMEL-Drucker in Multi-User-Systemen. Unab-
+hängig davon, ob der Drucker gerade aktiv ist und wieviele Dateien noch auf
+den Ausdruck warten, kann man seine Datei dem Druckspooler schicken und
+sofort danach weiterarbeiten.
+
+Da jeder Spooler und auch jeder Worker eine eigene Task ist, können Spooler
+nur im Multi-User-Systemen eingesetzt werden.
+
+Im folgenden wird nur die anwenderseitige Schnittstelle eines Spoolers be-
+schrieben.
+
+Merke: Ein Spooler puffert Dateien für einen Worker.
+
+
+
+2. Die Benutzung eines Spoolers
+
+Jeder Spooler im System ist eine eigene Task und hat dementsprechend einen
+Tasknamen, über den er angesprochen werden kann. So heißt der Druckspooler
+beispielsweise " PRINTER".
+
+Jede Task kann jedem Spooler durch Aufruf von 'save' eine Datei schicken.
+Beispiel:
+
+ save ("datei name", task ("spooler name"))
+
+(Vergl. auch TEIL 7). In der Regel ist ein SPOOLER für (mindestens) einen
+Drucker in einem EUMEL-System vorhanden. Dieser kann über den internen
+Task-Bezeichner 'print' angesprochen werden. Beispiel:
+
+ save ("datei name", printer)
+
+Eine so übergebene Datei kann man durch
+
+ erase ("datei name", printer)
+
+aus der Warteschlange löschen. (Natürlich nur solange sie sich noch in dieser
+Warteschlange befindet). Dabei kann man nur auf solche Dateien zugreifen, die
+aus der eigenen Task stammen. Durch Aufruf von
+
+ list (printer)
+
+wird die aktuelle Warteschlange des angegebenen Spoolers auf dem Terminal
+angezeigt, so daß man sich über die Anzahl der Dateien und die Position der
+eigenen Dateien im Spooler informieren kann.
+
+Aufbauend auf diesen allgemeinen Kommandos können weitere für spezielle
+Spooler programmiert werden. So gibt es für den Spooler 'printer' die Proze-
+duren
+
+ print und print ("datei name")
+
+die im wesentlichen auf
+
+ save ("datei name", printer)
+
+zurückgeführt werden.
+
+Merke: Einem SPOOLER kann man eine (oder mehrere) Dateien mit 'save'
+schicken. Mit 'list' kann man sich über die Dateien im SPOOLER informieren.
+Einem Drucker-SPOOLER übergibt man mit 'print' eine Datei.
+
+
+
+3. Privilegierte Spooler-Kommandos
+
+Gewisse Kommandos können einer #ib#Spooler-Task#ie# direkt im Dialog (ähn-
+lich wie im 'maintenance'-Zustand eines globalen Datei-Managers) gegeben
+werden. Dazu muß der Spooler mit 'continue' an ein Terminal geholt werden.
+Ist der SPOOLER durch ein Paßwort, so sind diese privilegierten Kommandos
+nicht für jeden Benutzer zugänglich.
+
+break
+ PROC break
+ Zweck: Beendet den Dialogzustand des Spoolers. Der Spooler koppelt sich
+ vom Terminal ab und geht in seinen normalen Verarbeitungsmodus
+ über.
+
+first
+ PROC first
+ Zweck: Vorziehen einer Datei in der Warteschlange auf den ersten Platz.
+ Alle Dateien von der zweiten an werden im Dialog zum Vorziehen
+ angeboten.
+
+start
+ PROC start
+ Zweck: Die (vorher gestoppte) Worker-Task wird neu kreiert und ge-
+ startet.
+
+stop
+ PROC stop
+ Zweck: Die Worker-Task wird abgebrochen und gelöscht. Damit wird auch
+ ein von ihr belegetes Terminal wieder frei.
+
+
+Hinweis: Die Kommandos 'start/stop' sind gut dazu geeignet, die Verarbeitung
+ einer Datei durch einen Worker (z.B. Druckoutput) abzubrechen, bei
+ Hardwareeingriffen zu stoppen oder Worker (wie z.B. Drucker) nur
+ zeitweise zu betreiben.
+
+Hinweis: Wenn der Worker mit Verzögerung abgebrochen werden soll, kann man
+ den Spooler an ein Terminal holen und dann so lange mit der Eingabe
+ von 'stop' warten, bis der Worker mit der gerade bearbeiteten Datei
+ fertig ist. Der Spooler kann in dieser Zeit nicht von anderen Tasks
+ oder dem Worker angesprochen werden.
+
+
+
+4. Der OPERATOR
+
+Im folgenden Abschnitt wird die standardmäßig implementierte Task OPERATOR
+erläutert. Erweiterungsmöglichkeiten sind im Systemhandbuch beschrieben. Dem
+OPERATOR stehen gewisse privilegierte Kommandos zur Verfügung. Diese Kom-
+mandos (System abschalten, fremde Tasks löschen u.a) werden vom "normalen"
+Benutzer des Multi-User-Systems nicht benötigt. Sie sind nur für den
+"Operateur" interessant. Es empfiehlt sich, OPERATOR mit einem Paßwort zu
+versehen, damit die priviligierten Kommandos nicht jedem Benutzer zur Ver-
+fügung stehen.
+
+
+
+Einschalten des EUMEL-Systems
+
+Wie ein EUMEL-System eingeschaltet wird, kann hier nicht beschrieben werden,
+weil dies abhängig von speziellen Rechnern ist (Lage des Ein/Aus-Schalters
+u.a.m.). Üblicherweise liefern die Hersteller für diesen Zweck bei der Aus-
+lieferung Anweisungen mit.
+
+Nach Einschalten des Rechnersystems befindet man sich in der Task OPERATOR.
+Diese Task dient zum kontrollierten Ein- und Ausschalten des EUMEL-Systems.
+Nach dem Einschalten wird man automatisch von der Task OPERATOR nach dem
+aktuellen Datum und der Uhrzeit gefragt. Nach Eingabe dieser Werte erfolgt
+
+ gib kommando :
+
+Der Benutzer befindet sich also in der Monitor-Ebene (vergl. dazu auch
+TEIL 2). Um die Task OPERATOR vom Terminal abzukoppeln, gibt man
+
+ break
+
+Nach Betätigen der SV-Taste erscheint dann
+
+ gib supervisor kommando :
+
+Nun kann man mit 'begin' oder 'continue' eine neue Task einrichten oder mit
+einer alten Task in der Arbeit fortfahren.
+
+Merke: Nach dem Einschalten gibt man das Datum und die Uhrzeit an.
+ Dann koppelt man die Task OPERATOR mit 'break' ab.
+
+
+
+EUMEL-System ausschalten
+
+Nachdem die Arbeiten in der Benutzer-Task beendet wurden, koppelt man die
+Task mit
+
+ break
+
+vom Terminal ab oder beendet die Task mit
+
+ end
+
+Achtung: Bei 'end' werden alle Dateien der Task gelöscht.
+
+Nach Betätigen der SV-Taste kann nun ein Supervisor-Kommando gegeben
+werden. Um das EUMEL-System kontrolliert auszuschalten, muß man die Task
+OPERATOR wieder an das Terminal holen. Das erfolgt mit
+
+ continue ("OPERATOR")
+
+Die OPERATOR-Task meldet sich mit
+
+ gib kommando :
+
+Nun kann man das Kommando
+
+ shutup
+
+geben, welches das System kontrolliert abschließt. 'shutup' garantiert, daß
+alle Dateien auf dem Hintergrund des EUMEL-Systems gesichert werden. Wird
+das EUMEL-System ohne 'shutup' ausgeschaltet (z.B. indem der Rechner einfach
+ausgeschaltet wird), können die Informationen, die seit dem letzten Fixpunkt
+(üblicherweise 15 Minuten) aufgelaufen sind, verloren sein.
+
+Merke: In der Task OPERATOR wird mit dem Kommando 'shutup' das EUMEL-System
+kontrolliert abgeschaltet.
+
+
+
+Übersicht über die #ib#OPERATOR-Kommandos
+
+end
+ PROC end (TASK CONST task)
+ Zweck: Löschen der Task 'task'. Hierbei findet keine Paßwortüberprüfung
+ statt. Darum sollte die Task OPERATOR auch mit einem Paßwort
+ versehen sein, weil man vom OPERATOR jede Task löschen kann.
+ Beispiel:
+
+ end (task ("hugo")) (* oder: *)
+ end (/"hugo")
+
+set date
+ PROC set date
+ Zweck: Einstellen des Datums und der Uhrzeit. Das Erfragen der Werte
+ erfolgt interaktiv.
+
+shutup
+ PROC shutup
+ Zweck: Kontrolliertes Herunterfahren des gesamten Systems. Alle Tasks
+ bleiben mit ihren Daten erhalten. Beim Start des Systems meldet
+ sich die OPERATOR-Task wieder auf dem gleichen Terminal. Das
+ Kommando sollte deshalb möglichst nur am Terminal 0 gegeben
+ werden. Nach dem Start sollte der OPERATOR mit 'break' vom
+ Terminal abgekoppelt werden.
+
diff --git a/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil2 b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil2
new file mode 100644
index 0000000..c70ddfc
--- /dev/null
+++ b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil2
@@ -0,0 +1,628 @@
+ EUMEL-Benutzerhandbuch
+
+ TEIL 2: Supervisor/Monitor
+
+
+1. Task-Organisation
+
+In diesem Kapitel wird die Task-Verwaltung und der Task-Baum beschrieben.
+
+Alle Tasks des EUMEL-Systems werden in einen Task-Baum eingebunden. Das be-
+deutet, daß die Task eines Benutzers automatisch einen "Vater" besitzt, aber
+auch neue Tasks ("Söhne") erzeugen kann. In einem EUMEL-System gibt es in
+der Regel zwei spezielle Tasks (#ib#UR#ie# und #ib#SUPERVISOR#ie#). Alle
+anderen Tasks sind Söhne oder Enkel dieser Tasks. Zum Beispiel:
+
+Die mit großen Buchstaben geschriebenen Tasknamen sind "System"-Tasks; die
+mit kleinen Buchstaben geschriebenen Tasknamen sind Benutzer-Tasks (dies
+ist nicht zwingend, sondern Konvention).
+
+- SUPERVISOR: Übernimmt das Einrichten bzw. Löschen von Tasks.
+
+- OPERATOR: Übernimmt u.a. die Aufgaben für das Ein- bzw. Ausschalten des
+ EUMEL-Systems.
+
+- ARCHIVE: Übernimmt die Auslagerung von Dateien auf Archive.
+
+- UR: Ist der "Urvater" des EUMEL-Systems, enthält u.a. den
+ ELAN-Compiler.
+
+- PUBLIC: Enthält Dateien, die längerfristig gehalten werden müssen und
+ die alle Benutzer des Systems benötigen.
+
+
+Der Task-Baum hat folgende Bedeutung:
+
+Eine Task, die sich "unter" einer anderen befindet, ist ein "Sohn" dieser
+"Vater"-Task. Beispielsweise ist die Task PUBLIC ein Sohn von UR (und UR ist
+somit Vater von PUBLIC).
+
+Die für eine Task zur Verfügung stehenden Datentypen und Operationen (d.h.
+die Objekte, die aus insertierten ELAN-Paketen herausgereicht werden), sind
+durch die direkte aufsteigende Linie im Task-Baum vorgegeben. Die in "Vater-
+Tasks" insertierten und über die Schnittstelle herausgereichten Objekte
+stehen in den "Söhnen" automatisch zur Verfügung. Beispielsweise stehen einer
+Sohn-Task von 'user 1' alle insertierten Objekte aus der 'user 1'-Task zur
+Verfügung (zusätzlich zu denen, die in UR und PUBLIC insertiert wurden).
+Somit ist leicht möglich, unterschiedliche Sprachmengen des ELAN-Compilers
+zur Verfügung zu stellen. Vergl. dazu auch das Kapitel über den ELAN-
+Compiler.
+Ähnliches gilt bei Dateien. So ist es erlaubt, Dateien zu direkten Vätern und
+Söhnen im Taskbaum zu transportieren, aber nicht unmittelbar in "parallele"
+Tasks. Man kann somit in der 'user 1'-Task Dateien von UR oder PUBLIC be-
+ziehen, aber nicht von 'user 2' (da diese Task eine "parallele" Task ist).
+Soll das trotzdem geschehen, so muß eine Datei erst von 'user 1' zu PUBLIC
+geschickt werden und dann von 'user 2' dort abgeholt werden. Genaueres über
+solche Operationen findet man im Benutzerhandbuch über die Datenräume.
+
+Einige Tasks sind speziell dafür eingerichtet, Dateien für mehrere Nutzer
+aufzubewahren. So sind UR und PUBLIC Tasks, die Dateien verwalten, die
+längerfristig gehalten werden sollen. Solche Tasks werden "Manager"-Tasks
+genannt.
+
+
+2. Supervisor und Tasks
+
+Eine Task ist für einen Benutzer ein "eigener Rechner", in der er Programme
+bearbeiten lassen und/oder Daten aufbewahren kann, ohne von anderen Nutzern,
+die gleichzeitig im System arbeiten, gestört zu werden. Der Supervisor er-
+möglicht u.a. die Einrichtung, Weiterbearbeitung und Beendigung einer Task.
+
+
+Überblick
+
+Eine Task ist im EUMEL-System ein selbständiger Prozeß. Zu jedem Program-
+mierer an einem Terminal gehört eine damit verbundene Task. Für den Benutzer
+ist diese Task sozusagen ein "eigener Rechner". In einem EUMEL-System sind
+zur gleichen Zeit noch weitere Tasks vorhanden, so z.B. zum Start und Ab-
+schalten des Systems (OPERATOR), zur Druckersteuerung (SPOOLER), zur Ver-
+waltung längerfristig benötigter Dateien u.a.m..
+
+Der Supervisor ist auf der ELAN-Ebene des EUMEL-Systems der Betriebssystem-
+kern. Seine Aufgabe ist im wesentlichen die Task-Verwaltung, nämlich die Er-
+richtung und das Löschen von Tasks. Im einfachsten Fall kommt ein Benutzer
+des EUMEL-Systems mit dem Supervisor also nur bei den Supervisor-Kommandos
+in Kontakt, die den Beginn und das Ende einer Task steuern.
+
+Jede Task wird in einen "Taskbaum" eingeordnet. Jede Benutzer-Task ist
+"Sohn" einer bereits vorhandenen "Vater"-Task und "erbt" von dieser vorüber-
+setzte Programme. Man kann Dateien zu einer Vater-Task schicken oder von
+dieser empfangen.
+
+
+Eine neue Task beginnen
+
+Mit dem Supervisor-Kommando 'begin' kann eine neue Task eingerichtet werden.
+
+Soll eine neue Arbeit im EUMEL-System begonnen werden, muß eine neue Task
+eingerichtet werden. Dazu muß das Supervisor-Kommando 'begin' gegeben
+werden. Jedes Supervisor-Kommando muß durch die Betätigung der SV-Taste
+eingeleitet werden. Dadurch meldet sich das EUMEL-System mit
+
+ gib supervisor kommando :
+
+Jetzt kann eines der Supervisor-Kommandos gegeben werden. In unserem Fall
+wollen wir mit dem 'begin'-Kommando eine neue Task einrichten. Beispiel:
+
+ begin ("rainer")
+
+errichtet eine neue Task in dem EUMEL-System mit dem Namen 'rainer'. Die
+Task meldet sich mit
+
+ gib kommando :
+
+Nun kann ein beliebiges Monitor-Kommando gegeben werden.
+
+Wird eine Task in der geschilderten Weise eingerichtet, ist diese Task im
+Taskbaum automatisch ein "Sohn" der Task 'PUBLIC'. 'PUBLIC' ist in der Lage,
+Dateien von der neuen Sohn-Task zu empfangen ('save'-Kommando) oder man kann
+Dateien von 'PUBLIC' in die Sohn-Task holen ('fetch'-Kommando). Solche Tasks,
+die Dateien verwalten können, werden 'manager' genannt.
+
+Merke: Nach dem Betätigen der SV-Taste meldet sich der Supervisor.
+ Mit dem 'begin'-Kommando wird eine neue Task eingerichtet.
+
+
+
+Eine Task ab- und ankoppeln
+
+Mit dem 'break'- und 'continue'-Kommandos können die Arbeiten in einer Task
+unterbrochen und später wieder aufgenommen werden.
+
+Soll die Arbeit in einer Task unterbrochen werden, so kann man das (Monitor-)
+Kommando
+
+ break
+
+geben, welches die Task vom Benutzer-Terminal abkoppelt. Die Task wird dann
+vom System als "Hintergrund-Task" geführt, bleibt also weiterhin bestehen.
+Mit dem Supervisor-Kommando
+
+ continue ("meine task")
+
+kann eine solche "abgekoppelte" Task wieder an ein Terminal angekoppelt und
+die unterbrochenen Arbeiten weitergeführt werden.
+
+Mit 'break' wird eine Task unterbrochen, während durch das 'continue'-Kom-
+mando die Arbeiten fortgesetzt werden können.
+
+
+
+Eine Task beenden
+
+Mit dem 'end'-Kommando wird eine Task beendet und gelöscht.
+
+Sind die Arbeiten in einer Task beendet, so sollte sie aus dem System ent-
+fernt werden. Dies erfolgt mit dem Kommando
+
+ end
+
+Nach einer Rückfrage des Systems wird die Task gelöscht. Beachte, daß mit dem
+Löschen der Task auch alle in ihr befindlichen Dateien gelöscht werden.
+
+Merke: Mit dem 'end'-Kommando wird eine Task beendet und alle in ihr befind-
+lichen Daten werden gelöscht.
+
+
+
+Eine Task als Sohn einer Task einrichten
+
+Mit dem 'begin'-Kommando ist es auch möglich, eine Task als Sohn einer be-
+stimmten Task einzurichten. Damit die Vater-Task auch Dateien der einzu-
+richtenden Sohn-Task verwalten kann, muß man sie vorher zu einer 'manager'-
+Task machen.
+
+In der Regel richtet man seine Task als Sohn von PUBLIC ein. Das erfolgt
+automatisch, sofern man im 'begin'-Kommando nichts anderes als den neuen
+Tasknamen angibt. Manchmal ergibt sich aber die Notwendigkeit, eine Task als
+Sohn einer bestimmten Task einzurichten. Gründe können dafür u.a. sein:
+
+- Man will eine eigene Datei-Hierarchie über mehrere Tasks einrichten.
+
+- Man will ein Programmsystem anderen Benutzern zur Verfügung stellen.
+
+Damit eine Task als Vater für andere, noch einzurichtende Task arbeiten kann,
+muß man sie zuerst zu einer 'manager'-Task machen. Das erfolgt mit dem
+Kommando
+
+ global manager
+
+Dies Kommando muß in der Task gegeben werden, die eine Vater-Task werden
+soll. Damit wird die Task befähigt, Söhne einzurichten und Dateien, die von
+einem (oder mehreren) Söhnen geschickt werden, zu verwalten.
+
+Durch das 'global manager'-Kommando wird implizit ein 'break'-Kommando ge-
+geben, so daß der Benutzer in der Supervisor-Ebene landet. Koppelt man nun
+zu irgendeinem Zeitpunkt diese (zunächst potentielle) Vater-Task wieder an
+('continue'-Kommando), meldet sich die Task nicht wie gewohnt mit 'gib
+kommando :', sondern mit
+
+ maintenance :
+
+um anzudeuten, daß es sich um eine 'manager'-Task handelt.
+
+Um eine Sohn-Task "unterhalb" der 'manager'-Task einzurichten, gibt man das
+'begin'-Kommando, wobei man die Vater-Task mit angibt. Beispiel:
+
+ begin ("rainer", "vatername")
+
+richtet eine neue Task 'rainer' ein, die als Sohn der Vater-Task 'vatername'
+in den Taskbaum eingeordnet wird.
+
+Merke: Das Kommando 'global manager' macht eine Task zu einer 'manager'-Task.
+Mit dem 'begin'-Kommando kann man auch eine Task als Sohn einer bestimmten
+Task einrichten.
+
+
+
+Ein laufendes Programm unterbrechen
+
+Mit dem Betätigen der SV-Taste und dem Supervisor-Kommando 'halt' kann ein
+Programm abgebrochen werden.
+
+Soll ein Programm, welches gerade ausgeführt wird, vorzeitig abgebrochen
+werden, so betätigt man die SV-Taste und gibt das Supervisor-Kommando
+
+ halt
+
+Anschließend kann man wieder ein Monitor-Kommando geben, weil man durch das
+'halt'-Kommando automatisch wieder in seine Task gelangt.
+
+Merke: Mit dem 'halt'-Kommando wird ein Programm abgebrochen.
+
+
+
+Eine Task mit Paßwort schützen
+
+Man kann eine Task durch ein Paßwort vor unberechtigtem Zugriff schützen.
+
+Das Kommando
+
+ task password
+
+welches nur im Monitor gegeben werden kann, sorgt dafür, daß eine Task fort-
+an nur wieder mit einem 'continue'-Kommando 'betreten' werden kann, wenn man
+vorher das richtige Paßwort angibt. Beispiel:
+
+ task passwort ("mein geburtstag")
+
+Versucht nun ein Benutzer, die mit dem Paßwort geschützte Task mit dem
+'continue'-Kommando an sein Terminal anzukoppeln, wird er zunächst nach dem
+'Paßwort' gefragt. Nur unter Angabe des Paßwortes wird die Task angekoppelt. #count("1")#)
+
+Man sollte Paßwörter möglichst behalten! Durch Paßwörter geschützte Tasks
+kann niemand - außer durch die Angabe des korrekten Paßworts - die Task
+wieder ankoppeln. Hat man das Paßwort vergessen, kann man nur noch die Task
+löschen.
+
+Damit ist gewährleistet, daß kein unberechtigter Benutzer an die Dateien und
+Programme der Task gelangen kann. Es gibt jedoch noch zwei Situationen, die
+einen unberechtigten Zugang zu Dateien erlauben:
+
+a) Dateien in die Vater-Task schicken:
+ Transportiert man Dateien in die Vater-Task ('save'-Kommando, vergl. auch
+ Teil 7: Datei-Verwaltung), können Benutzer auf diese Dateien zugreifen
+ (sofern sie Zugang zu dieser Task haben). Dies kann man verhindern, in dem
+ man ein Datei-Paßwort angibt (siehe Teil 7 für die Beschreibung dieser
+ Paßworte). Man beachte, daß das Paßwort für Dateien und das oben be-
+ schriebene Paßwort für Tasks nichts miteinander zu tun haben.
+
+b) Dateien werden in eine Sohn-Task geholt:
+ Ist die Task als Vater-Task eingerichtet (Kommando 'global manager') dann
+ ist es möglich, von der Sohn-Task Dateien ('fetch'-Kommando) aus der
+ Vater-Task zu holen, die mit einem Paßwort geschützt ist. Darum muß man
+ verhindern, daß Unberechtigte Söhne einer mit Paßwort geschützten Task
+ einrichten können. Das kann man mit dem Kommando
+
+ begin password ("geheim")
+
+ Wird dieses Kommando gegeben, wird man bei dem Versuch, eine Sohn-Task
+ einzurichten, nach einem Paßwort gefragt. Beachte, daß das 'begin-
+ password' nichts mit dem Task-Paßwort und Datei-Paßwort zu tun hat.
+
+Merke: Mit dem 'task password'-Kommando wird eine Task durch ein Paßwort
+geschützt.
+
+
+
+Informations-Kommandos
+
+(Die Informations-Kommandos können auch vom Monitor aus gegeben werden).
+
+Mit der Informationsprozedur
+
+ task status
+
+können Sie sich über den Zustand einer Task informieren. Beispiele:
+
+ task status (* informiert über die eigene Task *)
+ task status (father) (* informiert über die Vater-Task *)
+
+'task status' informiert u.a. über die verbrauchte CPU-Zeit der Task, den
+belegten Speicherplatz (man beachte, daß Dateien mit Vater-Tasks oder Sohn-
+Tasks werden), den Kanal, an dem die Task angekoppelt ist und dem Zustand
+der Task (vergl. auch 'task info').
+
+Mit der Prozedur
+
+ task info
+
+können Sie eine Übersicht über alle in dem System befindlichen Tasks er-
+halten.
+Mit dem Kommando
+
+ storage info
+
+kann man erfahren, wieviel Speicherplatz auf dem EUMEL-Hintergrund (noch)
+zur Verfügung steht.
+
+Durch einige Kommandos, die man nur vom Monitor aus geben kann, kann man
+sich den Namen von Tasks liefern lassen. Die Kommandos
+
+ myself
+ father
+
+liefern den (internen) Task-Namen. Mit dem Kommando
+
+ name
+
+bekommt man den internen Tasknamen in einen Text gewandelt. Beispiel:
+
+ put (name (myself))
+ put (name (father))
+
+Mit dem Kommando
+
+ rename myself
+
+kann der Task-Name der Benutzer-Task geändert werden.
+
+Merke: Durch die Informations-Kommandos 'storage info' und 'task info' kann
+man erfahren, wieviel Speicherplatz und welche Tasks in dem EUMEL-System
+sind. Mit den Kommandos 'myself' und 'father' kann man mehrere Dateien auf
+einmal manipulieren (vergl. Teil 7).
+
+
+
+Übersicht über Supervisor- und Task-Kommandos
+
+In diesem Abschnitt werden alle Supervisor- und Task-Kommandos in der ELAN-
+Notation dargestellt.
+
+Die Supervisor-Kommandos entsprechen - wie alle anderen Kommandos im EUMEL-
+System - der ELAN-Syntax (Kommando-Namen werden klein geschrieben, Parameter
+in Klammern, mehrere Parameter durch Kommata getrennt, TEXT-Parameter in
+Anführungstrichen usw.). Dabei ist jedoch zu beachten, daß diese Kommandos
+zum Teil nur im Supervisor-Zustand (vorheriges Betätigen der SV-Taste) ge-
+geben werden können. Die Kommandos 'break', 'end', 'storage info' und
+'task info' können auch im Monitor gegeben werden.
+Folgende Supervisor-Kommandos stehen zur Verfügung:
+
+begin
+ PROC begin (TEXT CONST task name)
+ Zweck: Richtet eine neue Task als Sohn von PUBLIC ein.
+
+ PROC begin (TEXT CONST task name, father task name)
+ Zweck: Richtet eine neue Task als Sohn der 'father task name'-Task ein.
+
+begin password
+ PROC begin password (TEXT CONST geheim)
+ Zweck: Verhindert das unberechtigte Einrichten einer Sohn-Task.
+
+break
+ PROC break
+ Zweck: Die zum Terminal aktuell zugeordnete Task wird abgekoppelt. Sie
+ wird damit zu einer Hintergrund-Task, d.h. sie wird entweder bis
+ zu ihrem Ende oder bis zur nächsten angeforderten Terminal-Ein-/
+ Ausgabe oder bis zum nächsten 'continue'- Kommando weiter be-
+ arbeitet.
+
+continue
+ PROC continue (TEXT CONST task name)
+ Zweck: Eine im Hintergrund laufende Task wird an das Terminal des
+ Benutzers angekoppelt.
+
+end
+ PROC end
+ Zweck: Die zum Terminal aktuell gehörende Task wird abgebrochen und
+ gelöscht. Das Kommando ist im Monitor verfügbar.
+
+father
+ TASK PROC father
+ Zweck: Liefert den internen Tasknamen.
+
+global manager
+ PROC global manager
+ Zweck: Macht eine Task zur 'manager'-Task. Erst nach Aufruf dieser
+ Prozedur sind Sohn-Tasks möglich.
+
+halt
+ PROC halt
+ Zweck: Das laufende Programm der dem Terminal aktuell zugeordneten Task
+ wird abgebrochen. Im Gegensatz zum 'end'-Kommando wird nur das
+ laufende Programm abgebrochen, aber die Task wird nicht gelöscht.
+ Genauer:
+ Es wird der Fehler 'halt from terminal' induziert. Normalerweise
+ wird das Programm dadurch wie durch jeden anderen Fehler abge-
+ brochen. Genaueres findet man im Systemhandbuch unter Fehler-
+ behandlung.
+
+name
+ TEXT PROC name (TASK CONST interner name)
+ Zweck: Wandelt den internen Task-Namen in einen TEXT.
+
+rename myself
+ PROC rename myself (TEXT CONST neuer name)
+ Zweck: Umbenennen einer Benutzer-Task.
+
+myself
+ TASK PROC myself
+ Zweck: Liefert den internen Task-Namen der Benutzer-Task.
+
+storage info
+ PROC storage info
+ Zweck: Informationsprozedur über den verfügbaren Hintergrund-Speicher.
+
+task info
+ PROC task info
+ Zweck: Informiert über alle Tasknamen im System unter gleichzeitiger An-
+ gabe der Vater/Sohn-Beziehungen (Angabe durch Einrückungen).
+
+ PROC task info (INT CONST art)
+ Zweck: Informiert über alle Tasks im System. Mit 'art' kann man die Art
+ der Zusatz-Information auswählen. Für 'art' sind zur Zeit
+ folgende Werte zugelassen:
+
+ 1: entspricht 'task info' ohne Parameter, d.h. gibt nur die
+ Tasknamen unter angabe der Vater/Sohn-Beziehungen aus.
+
+ 2: gibt die Tasknamen aus. Zusätzlich erhalten Sie Informationen
+ über die verbrauchte CPU-Zeit der Task, die Priorität, den
+ Kanal, an dem die Task angekoppelt ist und den eigentlichen
+ Taskstatus. Hierbei bedeuten:
+
+ 0 -busy- Task ist aktiv.
+ 1 i/o Task wartet auf Beendigung des Outputs
+ oder auf Eingabe.
+ 2 wait Task wartet auf Sendung von einer anderen
+ Task.
+ 4 busy-blocked Task ist rechenwillig, aber blockiert.
+ 5 i/o -blocked Task wartet auf I/O, ist aber blockiert.
+ 6 wait-blocked Task wartet auf Sendung, ist aber blockiert.
+ Achtung: Die Task wird beim Eintreffen einer
+ Sendung automatisch entblockiert.
+
+ 3: wie 2, aber zusätzlich wird der belegte Speicher angezeigt.
+ (Achtung: Prozedur ist aufwendig!). Beachten Sie, daß Dateien
+ mit Väter/Söhnen "geshared" werden. Beispiel:
+ Mit 'begin ("sohn", "vater")' wird eine neue Task eingerichtet.
+ Für 'sohn' wird in diesem Zustand der gleiche belegte Speicher
+ angezeigt wie für 'vater'. Erst wenn (Datei-)Operationen in
+ der Sohn- oder Vater-Task vorgenommen werden, wird ein unter-
+ schiedlicher Speicherplatz angezeigt.
+
+task status
+ PROC task status
+ Zweck: Informationsprozedur über den Zustand der eigenen Task.
+ Informiert u.a. über
+ - Name der Task, Datum und Uhrzeit;
+ - verbrauchte CPU-Zeit;
+ - belegten Speicherplatz;
+ - Kanal, an den die Task angekoppelt ist;
+ - Zustand der Task (rechnend u.a.m.);
+ - Priorität.
+
+ PROC task status (TASK CONST t)
+ Zweck: Wie obige Prozedur, aber über die Task mit dem internen Task-
+ namen 't'. Beispiel: task status (father)
+
+task password
+ PROC password (TEXT CONST geheim)
+ Zweck: Einstellen eines Paßworts für eine Task im Monitor. Das Kommando
+ 'task password' ist ein Monitor-Kommando. Ist eine Task mit einem
+ Paßwort geschützt, so wird durch den Supervisor nach dem
+ 'continue'-Kommando das Paßwort angefragt. Nur nach Eingabe des
+ richtigen Paßworts gelangt man in die gewünschte Task. Das Paß-
+ wort kann durch nochmaligen Aufruf von 'task password' geändert
+ werden, z.B., wenn es in regelmäßigen Abständen geändert werden
+ muß, um personenbezogene Daten zu schützen.
+
+ Es gibt keine Möglichkeit, ein einmal eingestelltes Paßwort in
+ Erfahrung zu bringen. Sollte das Paßwort vergessen werden, kann
+ somit die Task nur noch gelöscht werden.
+
+ Wird als Paßwort ein '-'-Zeichen eingegeben, so wird verhindert,
+ daß die betreffende Task jemals wieder mit dem 'continue'-Kom-
+ mando angekoppelt werden kann. Dies ist z.B. für Manager-Tasks
+ sinnvoll.
+
+
+
+3. Der Monitor
+
+Der EUMEL-Monitor führt den Dialog mit dem Benutzer innerhalb einer Task. In
+diesem Kapitel werden nur die Ausführung der Kommandos und die Kommando-
+Arten beschrieben, während die einzelnen Kommandos selbst in den jeweiligen
+Kapiteln des Benutzerhandbuchs erläutert werden.
+
+Der Monitor ermöglicht es, Leistungen im Dialog mit Hilfe von Kommandos
+(ELAN-Prozeduraufrufen) vom EUMEL-Betriebssystem anzufordern. Nach dem
+Beginn einer Sitzung meldet sich der Monitor mit
+
+ gib kommando :
+
+Danach kann der Benutzer Monitor-Kommandos geben. Erfolgt dabei ein Schreib-
+fehler, so kann er (wie beim Editor) innerhalb der Zeile positionieren, über-
+schreiben, löschen, einfügen u.a.m.. Die Ausführung des/der Kommandos wird
+mit der Taste RETURN ausgelöst. Nach Abschluß einer Kommando-Ausführung er-
+scheint wieder obige Meldung. Die Tastenfolge ESC k stellt das zuletzt gege-
+bene Kommando wieder dar.
+
+Monitor-Kommandos müssen gemäß der ELAN-Syntax geschrieben werden (Kommando-
+Namen werden klein geschrieben, Parameter in Klammern, mehrere Parameter
+durch Kommata getrennt, TEXT-Parameter in Anführungstrichen usw.). Beispiele:
+
+ edit ("meine datei")
+ copy ("meine datei", "Duplikat")
+
+Bei den meisten Kommandos mit einem TEXT-Parameter kann der Parameter fort-
+gelassen werden. Der Monitor versorgt das Kommando immer mit dem zuletzt an-
+gegebenen Parameter und zeigt dies auch auf dem Bildschirm des Benutzers an.
+Beispiel:
+
+ edit ("Datei vom 17.4.")
+
+schreibt der Nutzer nun z.B.
+
+ run
+
+und betätigt RETURN, dann ergänzt der Monitor das Kommando:
+
+ run ("Datei vom 17.4.")
+
+Monitor-Kommandos sind einzeilige ELAN-Programme, die dem ELAN-Compiler zur
+Übersetzung und anschließender Ausführung zugeleitet werden. Darum können
+die Monitor-Kommandos auch von Programmen aus verwendet werden. Falsch ge-
+schriebene oder nicht vorhandene Kommandos werden vom ELAN-Compiler mit ent-
+sprechender Fehlermeldung abgewiesen. Oft benutzte Kommandos werden aus
+Effizienzgründen vom Monitor selbst interpretiert und ausgeführt. Durch die
+automatische Überleitung von Kommandos zum ELAN-Compiler ist es möglich
+
+a) einzeilige ELAN-Programme direkt in der Monitor-Ebene ausführen zu
+ lassen, d.h. ohne das Programm in eine Datei zu schreiben. Beispiel:
+
+ put (sin (0.5))
+
+b) mehrere Kommandos (ELAN-Anweisungen), durch ";" getrennt, auf einmal zu
+ schreiben. Beispiele:
+
+ edit ("datei"); lineform ("datei"); print ("datei")
+ INT VAR i; FOR i FROM 1 UPTO90 REP print ("x") ENDREP
+
+c) eine Erweiterung des Kommando-Vorrats jederzeit vorzunehmen, indem man
+ die gewünschte Prozedur (in einem PACKET "verpackt") 'insertiert'.
+
+Im folgenden werden die am häufigsten benutzten Kommandos aufgeführt.
+Genauere Informationen über die einzelnen Kommandos findet man in den
+entsprechenden Kapiteln des Benutzerhandbuchs.
+
+Informations-Kommandos
+
+ storage info Belegter externer Speicher
+ task info Zeigt die im System befindlichen Tasks
+ task status Zustände der im System befindlichen Tasks
+
+
+Verbindung zum Supervisor
+
+ end Task und die in ihr befindlichen Dateien
+ löschen
+ break Task abkoppeln
+ task password ("geheim") Paßwort einstellen
+
+
+Editor-Kommandos
+
+ edit ("datei") Datei editieren
+ edit ("datei1", "datei2") Parallel-Editor
+
+
+Compiler-Kommandos
+
+ run ("datei") Übersetzen und ausführen eines ELAN-Programms
+ run again Letztes übersetztes Programm nochmal aus-
+ führen
+ insert ("datei") Übersetztes Programm eintragen
+
+
+Datei-Kommandos
+
+ copy ("datei", "duplikat") Datei kopieren
+ rename ("alt", "neu") Datei umbenennen
+ reorganize ("datei") Datei "reorganisieren"
+ fetch ("datei") Datei von Vater-Task holen
+ save ("datei") Datei zur Vater-Task schicken
+ erase ("datei") Datei in Vater-Task löschen
+ forget ("datei") Datei in Benutzer-Task löschen
+ list Dateien der Benutzer-Task anzeigen
+
+
+Archiv-Kommandos
+
+ archive ("name") Archiv mit einem Namen reservieren
+ release (archive) Archiv freigeben
+ clear (archive) Löscht ein Archiv
+ list (archive) Dateien des Archivs anzeigen
+ save all (archive) Archiviert alle Dateien einer Task
+ fetch all (archive) Holt alle Dateien eines Archivs in eine Task
+ save ("datei", archive) Datei archivieren
+ fetch ("datei", archive) Datei vom Archiv holen
+
+
+Textkosmetik und Drucker
+
+ lineform ("datei") Zeilenweises Formatieren
+ pageform ("datei") Seitenweises Formatieren
+ index ("datei") Stichwort- und Inhaltsverzeichnis
+ print ("datei.p") Drucken
+
diff --git a/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil3 b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil3
new file mode 100644
index 0000000..eaf1ed6
--- /dev/null
+++ b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil3
@@ -0,0 +1,2097 @@
+ EUMEL-Benutzerhandbuch
+
+ TEIL 3: Editor
+
+Vorwort
+
+Der EUMEL-Editor ist ein Programm zur Bearbeitung von Texten. Er bietet
+vielfältige Möglichkeiten, um Autoren oder Programmierer bei dem Erstellen,
+Korrigieren und Gestalten von Manuskripten oder Programmen zu unterstützen.
+Die größte Hilfe beim Schreiben besteht (durch die Speicherfähigkeit von
+Computern) aus dem Zugriff auf einmal geschriebene Informationen. Im Gegen-
+satz zu einer Schreibmaschine können durch den EUMEL-Editor (beliebig oft)
+Einfügungen vorgenommen, Texte korrigiert, gelöscht und umgeordnet werden.
+Somit ist das Schreiben von Texten mittels des EUMEL-Systems besonders dann
+vorteilhaft und zeitsparend, wenn Texte häufig geändert werden oder wenn
+sie in einer besonders schönen Form gedruckt werden sollen (sofern ein ent-
+sprechender Drucker zur Verfügung steht). Weiterhin bietet der Editor Hilfen
+zum Schreiben an, wie z.B. automatischen Wortumbruch am Zeilenende, eine
+Einrückungsautomatik, "Lernen" von Texten u.a.m.. Zusätzlich kann der Editor
+in seinen Fähigkeiten erweitert und somit für spezielle Schreibarbeiten an-
+gepaßt werden. Bei der Entwicklung des Editors wurde besonderer Wert auf
+einfache Bedienung gelegt: innerhalb von wenigen Minuten kann schon ge-
+schrieben werden und auf dem Bildschirm sieht man direkt, was mit dem Text
+passiert. Das Schreiben und die Korrektur werden durch einige wenige, aber
+leistungsstarke Funktionstasten unterstützt.
+
+Anfänger sollten zumindest das erste Kapitel lesen, bevor mit dem Schreiben
+begonnen wird. Dort wird geschildert, wie auf einfache Weise Texte ge-
+schrieben und geändert werden können. Die beschriebenen Tätigkeiten sollte
+man an einem kleinen Probetext erst einmal ausprobieren. Lesen und an-
+schließendes Ausprobieren eines der hier beschriebenen Vorgänge beschleunigt
+stark das Erlernen der Funktionen des Editors.
+
+Weitere Fähigkeiten des Editors werden in den folgenden Kapiteln erläutert.
+Diese Kapitel sollte man lesen, wenn die ersten Texte geschrieben worden
+sind. Die dort erklärten Möglichkeiten des Editors kann man dann bei Bedarf
+nachlesen, erlernen und einsetzen. Im letzten Kapitel werden Programmierern
+Hinweise gegeben, wie sie die Benutzerschnittstelle des Editors an indivi-
+duelle Bedürfnisse anpassen können.
+
+Einige Gestaltungsmöglichkeiten für Texte kann man nicht auf dem Terminal
+"sehen", wie z.B. Proportionalschriften, Fettdruck usw.. Solche Leistungen
+können durch Anweisungen an die Textkosmetik-Programme und den EUMEL-Drucker
+angefordert werden. Diese Anweisungen müssen in den Text eingefügt werden.
+Dazu sollte das Kapitel über die Textkosmetik gelesen werden.
+
+is nämlich alles ohne Radiergummi-Abbildung !!!
+
+
+
+1. Einführung in die Benutzung des Editors
+
+In diesem Kapitel beschreiben wir das Tastenfeld eines EUMEL-Terminals, weil
+es hier einige Tasten gibt, die auf einer Schreibmaschine nicht vorhanden
+sind. Anschließend erklären wir, wie der Editor ein- und ausgeschaltet wird,
+wie Texte geschrieben und auf einfache Weise korrigiert werden können. Eine
+kurze Erklärung des Tabulators beendet die Einführung.
+
+
+
+Das Tastenfeld
+
+In diesem Abschnitt wird das Tastenfeld eines EUMEL-Terminals erklärt. Es
+wird erläutert, wo sich die Tasten befinden und wie man Umlaute schreibt.
+
+Das Tastenfeld eines EUMEL-Terminals entspricht weitgehend dem einer
+Schreibmaschine. Wir finden also die Buchstaben a-z und die Ziffern 0-9 auf
+Tasten. Mit der SHIFT-Taste und gleichzeitigem Drücken einer anderen Taste
+können die großen Buchstaben und eine Reihe von speziellen anderen Zeichen,
+die Sonderzeichen genannt werden, geschrieben werden. Die "Zwischenraum-
+taste" oder Leertaste erzeugt immer ein Leerzeichen.
+
+Nun gibt es in der Praxis zwei unterschiedliche Tastaturen. Zum einen
+existiert die EDV-Tastatur, die zum Schreiben von Programmen benutzt wird.
+Sie erkennt man daran, daß keine Umlaute (ä, ü, ö) und kein ß auf den Tasten
+eingraviert sind. Dafür gibt es Tasten für eckige und geschweifte Klammern.
+Sollen auf einer solchen Tastatur die Umlaute geschrieben werden, muß man
+sich eines Tricks bedienen: mit der Taste ESC und nachfolgendem Betätigen
+einer anderen Taste erhalten wir den entsprechenden Umlaut.
+Diese Tasten sind standardmäßig vorbelegt, können aber von Benutzern und in
+Anwenderprogrammen geändert werden.
+
+ ESC a bringt ä, ESC A bringt Ä
+ ESC u bringt ü, ESC U bringt Ü
+ ESC o bringt ö, ESC O bringt Ö und
+ ESC s bringt ß.
+
+In der Regel kann man die Umlaute auf dem Bildschirm eines solchen EDV-
+Terminals nicht sehen, sondern sie erscheinen als a, u, usw.. Beim Druck
+eines Textes werden sie aber richtig dargestellt.
+
+Die andere Tastatur entspricht in der Tastenbelegung weitgehend einer deut-
+schen Schreibmaschine und besitzt Tasten für die Umlaute und ß. Sollen vor-
+wiegend deutsche Texte geschrieben werden, empfiehlt es sich, solch ein
+Terminal zu verwenden.
+
+Neben diesen "einfachen" Tasten gibt es noch einige wenige Tasten, die zur
+Bedienung des Editors (aber auch anderer Programme) notwendig sind. Wo die
+Tasten auf Ihrem Gerät liegen, hängt von dem jeweiligen Gerätetyp ab. Die
+Wirkung der Tasten erklären wir in den anschließenden Abschnitten.
+Es kann sein, daß die Tasten nicht richtig beschriftet sind. Dann sollten Sie
+den Betreuer ihrer Installation bitten, diese zu beschriften. Zusätzlich zu
+den hier beschriebenen können sich noch weitere Tasten auf ihrem Terminal
+befinden, die aber keine besondere Bedeutung für den Editor haben.
+
+Taste Bedeutung
+-----------------------------------------------------------------------------
+SHIFT Umschalttaste.
+ Für Großbuchstaben statt Kleinbuchstaben und Sonderzeichen
+ statt Ziffern.
+
+RETURN Beginn einer neuen Zeile (Absatz).
+ Die RETURN-Taste ist oft mit einem geknicktem Pfeil nach
+ links gekennzeichnet. Im Kommandomodus (also bei "gib
+ kommando :") wird ein gegebenes Kommando ausgeführt.
+
+LINKS Tasten für die Positionierung.
+RECHTS
+OBEN
+UNTEN
+ Positionierung der Schreibmarke (Cursor) in die jeweilige
+ Richtung (auf den Tasten oft auch durch Pfeile dargestellt).
+
+HOP "Verstärkertaste": Wirkt als Vorschalttaste.
+
+RUBOUT Löschtaste.
+
+RUBIN Ein- bzw. Ausschalten des Einfügezustandes.
+
+TAB Tabulatortaste.
+
+MARK Ein- bzw. Ausschalten der Markierung.
+
+ESC Kommandotaste.
+
+Merke: Das Tastenfeld eines EUMEL-Terminals ist in der Regel wie das einer
+Schreibmaschine und kann ebenso bedient werden. Umlaute müssen bei EDV-
+Tastaturen mit Hilfe der Taste ESC geschrieben werden. Einige Spezialtasten
+werden benutzt, um die Textbearbeitung des Editors zu steuern.
+
+Weitere Kommandotasten:
+ SV Supervisor-Taste im Mehrbenutzer-Betrieb ("multi-user").
+ Diese Taste bewirkt den Aufruf des Supervisors und ist keine
+ spezielle Editor-Taste.
+ STOP Anhalten eines Programms.
+ Wird die Taste aus Versehen betätigt (erkennbar daran, daß
+ der Editor nicht "reagiert"), muß WEITER betätigt werden.
+ WEITER Programm soll weiterlaufen.
+
+
+
+Speicherung von Texten
+
+In diesem Abschnitt wird der Begriff "Datei" erklärt und erläutert, wie
+unterschiedliche Texte auseinandergehalten werden können.
+
+Das EUMEL-System speichert einmal geschriebene Texte, bis sie vom Benutzer
+gelöscht werden. In der Regel wird nicht nur ein (langer) Text oder ein Pro-
+grammtext geschrieben, sondern mehrere und unterschiedliche. Um diese aus-
+einanderhalten zu können, versehen wir sie jeweils mit einem Namen, der frei
+gewählt werden kann. Beispiele für Namen:
+
+ "Brief vom 1.8.83"
+ "1. Kapitel meines Buches"
+
+Eine Sammlung von Zeichen (also im Normalfall unsere geschriebenen Texte),
+die mit einem Namen versehen worden ist, nennt man eine 'Datei' ('file'). Der
+Editor erstellt also eine Datei, wenn wir einen Text schreiben. Eine Datei
+kann bis zu 4 000 Zeilen fassen, wobei eine Zeile bis zu 32 000 Zeichen lang
+sein darf.
+
+Mit Hilfe des (Datei-) Namens kann man den Text (immer) wieder ansprechen,
+solange, bis die Datei gelöscht wird. Bei der Bearbeitung einer Datei durch
+den Editor wirkt sich jede Änderung des Textes auf dem Bildschirm sofort bis
+in die gespeicherte Datei aus. Eine Datei kann durch Kommandos verarbeitet
+werden. Eine Auswahl (Vergl. dazu die Beschreibung des Monitors):
+
+edit (Datei bearbeiten), rename (Datei umbenennen), copy (Duplizieren der
+Datei), to archive (Archivieren), lineform bzw. autoform (Zeilen
+formatieren), pageform (Seiten formatieren), print (Drucken) usw.
+
+Merke: Ein Text wird im EUMEL-System in einer Datei gehalten. Eine Datei
+faßt bis zu 4000 Zeilen Text. Eine Datei kann über den Dateinamen ange-
+sprochen werden, der frei gewählt werden kann.
+
+
+
+Ein- und Ausschalten des Editors
+
+Hier beschreiben wir, wie der Editor ein- und ausgeschaltet wird und wie
+der Editor eine Datei einrichtet. Zusätzlich wird das Ausschalten des auto-
+matischen Wortumbruchs erklärt.
+
+Wenn auf dem Bildschirm die Aufforderung
+
+ gib kommando :
+
+erscheint, befindet man sich in der Monitor-Ebene. Durch
+
+ edit ("dateiname")
+
+kann der EUMEL-Editor eingeschaltet (programmtechnisch: "aufgerufen")
+werden. Ist die Datei noch nicht vorhanden, d.h. kein Text unter dem ange-
+gebenen Namen im System gespeichert, folgt eine Anfrage, ob eine neue Datei
+eingerichtet werden soll. Dies dient zur Kontrolle von Schreibfehlern, die
+besonders bei ähnlichen Dateinamen auftreten. Man kann dann das Einrichten
+der Datei ablehnen, den Dateinamen verbessern und das Kommando erneut geben.
+
+Der Editor zeigt jetzt in der obersten Zeile des Bildschirms die Titelzeile,
+die den Dateinamen und die Zeilennummer enthält, die gerade bearbeitet wird.
+Im Fall einer bereits beschriebenen Datei zeigt der Editor das zuletzt bear-
+beitete Textstück. Bei einer neuen Datei ist der Bildschirm unterhalb der
+Titelzeile leer. Dieser Teil dient als "Schreibfläche". Der Cursor, so nennt
+man die blinkende Schreibmarke, steht dann direkt unter der Titelzeile. Er
+zeigt immer die aktuelle Schreibposition an. Jetzt kann sofort mit dem
+Schreiben begonnen werden, ganz wie mit einer normalen Schreibmaschine.
+
+Beenden der Schreibarbeit und Ausschalten des Editors erfolgt durch Drücken
+der beiden Tasten
+
+ ESC q
+
+nacheinander. Man befindet sich wieder in der alten Kommando-Ebene.
+
+Es ist aber auch möglich, während der Schreibarbeit (also bei eingeschalte-
+tem Editor) durch zweimaliges Drücken von ESC in die (Editor) Kommando-
+Ebene zu gelangen. Nach Abarbeitung des Kommandos gelangt man wieder in den
+normalen Schreibzustand.
+
+Der Editor ist auf das Schreiben von "normalen" Texten eingestellt. Bei
+"normalen" Texten soll ein Wort, welches über das Ende einer Zeile gehen
+würde, automatisch in die nächste Zeile gebracht werden. Dies wird
+"Wortumbruch" genannt.
+
+Ist kein Wortumbruch erwünscht, so gibt man das Kommando
+
+ word wrap (false)
+
+In diesem Fall schreibt der Editor bis zum Zeilenende und springt dann auto-
+matisch (u.U. mitten im Wort) auf die nächste Zeile. Der Wortumbruch kann
+durch
+
+ word wrap (true)
+
+wieder eingeschaltet werden.
+
+Merke: Der Editor wird durch das Kommando 'edit ("name")' aufgerufen und
+und wird durch ESC q wieder verlassen. Der Cursor zeigt die aktuelle
+Schreibposition an. Der Editor ist auf automatischen Wortumbruch eingestellt.
+
+
+
+Schreiben eines Textes
+
+In diesem Abschnitt wird erklärt, wie ein Text geschrieben wird und was es
+mit Absätzen auf sich hat.
+
+Nach dieser etwas langen Vorrede können wir endlich losschreiben. Wird ein
+Zeichen geschrieben, rückt der Cursor automatisch nach rechts auf die
+nächste Schreibstelle. Durch den automatischen Wortumbruch werden ange-
+fangene Worte, die über ein Zeilenende hinausgehen würden, ohne Silbentren-
+nung in die nächste Zeile gebracht.
+Nehmen Sie bitte keine Silbentrennung "per Hand" vor (wie in dieser An-
+leitung).Eingebrachte Trennstriche gelten als Bindestrich und bleiben somit
+auch bei Umformatierungen erhalten, was unerwünscht ist. Für diese mühevolle
+Aufgabe gibt es in der Textkosmetik ein Programm!
+
+Die RETURN-Taste (bei einer Schreibmaschine bedeutet sie "Wagenrücklauf")
+braucht also nur noch betätigt zu werden, wenn eine Zeile vorzeitig beendet
+werden soll: also bei einem Absatz oder einer Leerzeile. Der Cursor wird da-
+bei an den Anfang der nächsten Zeile positioniert. Gleichzeitig erscheint in
+der vorherigen Zeile am rechten Rand des Bildschirms eine Markierung, die
+anzeigt, daß hier ein Absatz gemacht wurde.
+
+Diese Absatzkennzeichnung ist wichtig: Sie bedeutet u.a. eine "Grenze" für
+die Textkosmetik-Programme beim (optimalen) Auffüllen von Zeilen. Für den
+Drucker bedeutet ein Absatz, keinen rechten Randausgleich (druckertechnisch:
+"Blocksatz") in dieser Zeile vorzunehmen.
+Die Absatzkennzeichnung besteht aus einem Leerzeichen in der Datei ("blank";
+im Unterschied zur Schreibmaschine ist das Leerzeichen in der EDV auch ein
+Zeichen und wird gespeichert). Absatzkennzeichen können gelöscht oder auch
+hinzugefügt werden (wie das gemacht wird, erfahren Sie in den nächsten Ab-
+schnitten). Ist der Wortumbruch ausgeschaltet, erscheint keine Absatzkenn-
+zeichnung beim Betätigen der RETURN-Taste.
+
+Darum ist das Betätigen der RETURN-Taste bei Tabellenzeilen und Programm-
+texten besonders wichtig, denn hier soll ja jede Zeile separat bleiben.
+
+Ein Bildschirm faßt (neben der Titelzeile) üblicherweise 23 Zeilen, die mit
+Text beschrieben werden können. Ist die letzte Zeile voll und muß eine neue
+Zeile begonnen werden, "rutscht" der Bildschirminhalt automatisch um eine
+Zeile nach oben. Damit ist Platz für eine Leerzeile, die nun ebenfalls be-
+schrieben werden kann usw.. Keine Angst: die so verschwundenen Zeilen sind
+natürlich nicht "weg". Da ein Bildschirm immer nur eine beschränkte Anzahl
+von Zeilen hat, kann der Editor nur einen Ausschnitt aus der Datei zeigen.
+In unserem Fall, wo wir zunächst nur am Ende der Datei schreiben, werden
+also immer die letzten Zeilen der Datei angezeigt.
+
+Merke: Ist der Wortumbruch eingeschaltet, wird ein angefangenes Wort, das
+über das Zeilenende gehen würden, an den Anfang der neuen Zeile gebracht.
+Die RETURN-Taste wird nur bei Absätzen, Tabellenzeilen oder Leerzeilen be-
+tätigt. In diesem Fall erscheint eine Absatzkennzeichnung am rechten Rand
+des Bildschirms. Ist der Bildschirm vollgeschrieben, werden beim fort-
+laufenden Schreiben alle Zeilen um eine Zeile nach oben gerückt.
+
+
+
+Einrückungen
+
+Hier wird die Einrückungsautomatik erklärt.
+
+Soll ein Text eingerückt werden (wie in den obigen "Merke"-Zeilen) oder bei
+Aufzählungen, so wird die in der ersten Zeile geschriebene Einrückung auto-
+matisch in den folgenden Zeilen beibehalten, bis sie durch die Posi-
+tionierungstasten wieder aufgehoben wird. Es gibt also kein Einrückkommando.
+Wie der rechte Rand (also die Zeilenbreite) eingestellt wird, erklären wir
+später.
+Dies kann für die gesamte Datei (und somit für den gesamten Text) durch ein
+ein Kommando erfolgen, mit welchem man den Editor auf diese Zeilenbreite
+einstellt. Um den rechten Rand nur für einige Zeilen zu verändern (wie z.B.
+bei unseren "Merke"-Zeilen) kann ein 'limit'-Kommando der Textkosmetik
+verwandt werden.
+
+Merke: Einrückungen werden automatisch beibehalten.
+
+
+
+Einfaches Positionieren und das Editor-Fenster
+
+Um Korrekturen (Überschreiben, Löschen oder Einfügen) vorzunehmen, muß der
+Cursor, der die aktuelle Schreibposition anzeigt, bewegt werden können. Bei
+längeren Texten ist es möglich, den Cursor auch auf Zeilen zu positionieren,
+die sich (noch nicht) auf dem Bildschirm befinden. Somit zeigt der Editor
+nicht nur immer das Ende einer Datei, sondern einen beliebigen Ausschnitt,
+der auf dem Bildschirm im sogenannten Fenster sichtbar ist.
+
+Ist eine Korrektur notwendig, muß der Cursor (blinkende Schreibmarke) auf die
+Stelle positioniert werden, an der die Korrektur vorgenommen werden soll.
+Dazu verwenden wir die Positionierungstasten LINKS, RECHTS, OBEN und UNTEN.
+LINKS und RECHTS bewegen den Cursor innerhalb einer Zeile. Stößt man mit
+RECHTS an das Ende einer Zeile, wird der Cursor an den Anfang der nachfol-
+genden Zeile bewegt. (Positionierungen jenseits des linken Randes sind nicht
+möglich).
+
+Ein Zeilenwechsel kann einfacher mit den Tasten OBEN und UNTEN vorgenommen
+werden. Die Taste OBEN bewegt den Cursor eine Zeile nach oben, die Taste
+UNTEN entsprechend eine Zeile tiefer.
+
+Was passiert nun, wenn der untere oder der obere Rand des Bildschirms er-
+reicht wird und es wird darüber hinaus positioniert? In diesem Fall wird der
+Text zeilenweise nach oben oder nach unten verschoben und es erscheint die
+gewünschte Zeile, wobei andere am anderen Rand "verschwinden". Wir sehen
+also, daß wir mit den Positionierungstasten den Bildschirm als Fenster über
+die Datei hinweggleiten lassen können (Fachausdrücke: "roll up" oder "roll
+down"). Den Text selbst können wir uns auf einem langen Band geschrieben
+vorstellen. Die Zeilennummer, in der der Cursor steht, wird stets in der
+Titelzeile angezeigt.
+
+Innerhalb einer Zeile ist es etwas anders: Positionieren wir bei einer Zeile,
+die breiter als der Bildschirm ist, nach rechts, wird das Fenster nur für
+diese Zeile verschoben (Fachausdruck: "scrolling").
+
+Merke: Mit Hilfe der vier Positionierungstasten kann man den Cursor auf dem
+Bildschirm bewegen. Außerdem ist es möglich, das Fenster mittels der
+Positionierungstasten über den Text zu bewegen.
+
+
+
+Einfache Korrekturen: Zeichen überschreiben, löschen und einfügen
+
+In diesem Abschnitt wird erklärt, wie einfache Korrekturen durch Über-
+schreiben von Zeichen, Löschen von Zeichen und Einfügen von Zeichen vorge-
+nommen werden können.
+
+Es können Korrekturen gleich beim Schreiben vorgenommen werden, indem die
+zuletzt geschriebenen Zeichen mit der RUBOUT-Taste gelöscht werden. Häufig
+merkt man aber Schreibfehler erst etwas später, so daß man diese Fehler nicht
+so leicht korrigieren kann. Für solche Zwecke muß man den Cursor an die Text-
+stelle bewegen, an dem korrigiert werden soll. Wie man das macht, haben wir
+im letzten Abschnitt geschildert.
+
+Die einfachste Möglichkeit der Korrektur ist das Überschreiben. Soll z.B. ein
+Zeichen durch ein anderes ersetzt werden, so positioniert man den Cursor
+genau über dieses und tippt das richtige Zeichen ein.Das kann natürlich auch
+mit mehreren Zeichen nacheinander erfolgen.
+
+Will man ein Zeichen löschen, so positioniert man auch hier den Cursor auf
+dieses Zeichen und betätigt die Taste RUBOUT. Das Zeichen verschwindet und
+die Restzeile rückt heran. Sollen mehrere Zeichen gelöscht werden, muß die
+RUBOUT-Taste entsprechend oft gedrückt werden.
+
+Steht der Cursor hinter dem letzten Zeichen der Zeile, wird immer das letzte
+Zeichen der Zeile gelöscht. Man kann also mit dieser Eigenschaft eine Zeile
+"von hinten wegradieren".
+
+Fehlende Zeichen kann man genauso einfach einfügen. Man bringt den Cursor
+auf das Zeichen, vor das eingefügt werden soll. Dann drückt man die Taste
+RUBIN. Der Editor gelangt in den Einfüge-Zustand, was in der Titelzeile durch
+RUBIN angezeigt wird. Er fügt alle Zeichen ein, die jetzt getippt werden (an-
+statt zu überschreiben). Der Teil der Zeile rechts vom Cursor rückt jeweils
+um entsprechend viele Stellen nach rechts.
+
+Wichtig ist, daß im RUBIN-Zustand der Editor genauso funktioniert wie im
+Normal-Zustand (natürlich mit der Ausnahme, daß eingefügt statt überschrieben
+wird).
+
+Ein neuerliches Betätigen der RUBIN-Taste beendet den Einfüge-Zustand. Die
+RUBIN-Taste wirkt also wie ein Schalter, der den Einfüge-Zustand ein- und
+ausschaltet. Allerdings kann man nur so viele Zeichen in eine Zeile einfügen,
+bis das letzte Wort der Zeile an das Zeilenende stößt. Das angefangene Wort
+wird am Anfang der folgenden Zeile eingefügt, sofern dort noch Platz ist und
+es nicht offensichtlich ein Absatzende kennzeichnet. Andernfalls wird auto-
+matisch eine neue Zeile für das angefangene Wort eingefügt.
+
+Im eingeschalteten RUBIN-Zustand können keine Zeichen verloren gehen. Viele
+Benutzer lassen darum den RUBIN-Zustand immer eingeschaltet, um sich vor dem
+unbeabsichtigten Überschreiben von Texten zu schützen. Es wird korrigiert,
+indem man die Verbesserung einfügt und den alten Text löscht.
+
+Merke: Mit Hilfe der Positionierungstasten LINKS, RECHTS, OBEN und UNTEN
+kann eine Stelle in der Datei ausgewählt werden, an der eine Korrektur vor-
+genommen werden soll. Die einfachste Korrektur ist das Überschreiben von
+fehlerhaften Zeichen. Zeichen löschen erfolgt mit der Taste RUBOUT. Mit
+RUBIN kann der Einfüge-Zustand ein- und ausgeschaltet werden. Im Einfüge-Zu-
+stand wird nicht überschrieben, sondern es wird vor der Cursor-Position das
+getippte Zeichen eingefügt.
+
+
+
+Springen, Zeilen einfügen/löschen mittels HOP-Taste
+
+Bewegungen des Cursors sind mit den Positionierungstasten bei größeren "Ab-
+ständen" etwas mühsam, ebenso bei umfangreichen Löschungen und Einfügungen.
+Die "Verstärkertaste" HOP ermöglicht es, diese Operationen auf einfache
+Weise zu beschleunigen. Mit der HOP-Taste kann man das Fenster über der
+Datei nicht nur zeilenweise, sondern auch um jeweils eine Fensterlänge ver-
+schieben. Das nennt man Blättern.
+
+Wird die HOP-Taste vor einer anderen der schon erklärten Funktionstasten
+gedrückt, verstärkt sie deren Wirkung. Die HOP-Taste ist eine "Präfix"-Taste:
+sie wird vor (und nicht gleichzeitig, wie z.B. die Umschalttaste SHIFT) einer
+anderen Taste gedrückt. Zuerst das springende Positionieren:
+Weitere wichtige Anwendungen der HOP-Taste beschreiben wir in den nächsten
+Abschnitten.
+
+HOP RECHTS Sprung an das rechte Zeilenende.
+ Falls die Zeile länger als das Fenster breit ist, wird seitlich
+ geblättert.
+
+HOP LINKS Sprung an den Zeilenanfang (ggf. seitlich blätternd).
+
+HOP OBEN Sprung auf die erste Zeile des Bildschirms.
+ Nochmaliges Betätigen dieser Tastenkombination positioniert den
+ Cursor (und damit das Fenster in der Datei) um ein Fenster
+ zurück.
+
+HOP UNTEN Sprung auf die letzte Zeile des Bildschirms.
+ Das Blättern erfolgt analog HOP OBEN.
+
+HOP RETURN Macht die aktuelle Zeile zur ersten des Fensters.
+ Die Zeile, in der sich der Cursor befindet, wird die erste
+ Zeile des Fensters.
+
+Die HOP-Taste in Verbindung mit RUBIN und RUBOUT wird zum "verstärkten"
+Löschen und Einfügen verwandt:
+
+HOP RUBIN Einfügen von Textpassagen:
+ Ab der aktuellen Position des Cursors verschwindet der rest-
+ liche Text. Es kann wie bei der anfänglichen Texteingabe fort-
+ gefahren werden. Die Anzeige REST in der Titelzeile erinnert
+ daran, daß noch ein Resttext existiert. Dieser erscheint nach
+ einem neuerlichen Betätigen der beiden Tasten HOP RUBIN wieder
+ auf dem Bildschirm (die Anzeige REST verschwindet dann wieder).
+
+HOP RUBOUT Löscht Zeile ab Cursor-Position bis Zeilenende:
+ Löscht die Zeile rechts vom Cursor. Steht der Cursor am Zeilen-
+ anfang, wird dementsprechend die ganze Zeile gelöscht und die
+ Lücke durch Nachrücken der Folgezeilen geschlossen.
+
+Merke: Die HOP-Taste dient in Verbindung mit den Positionierungstasten zum
+"Springen" oder zum "Blättern" innerhalb der Datei. Vor der Taste RUBOUT ge-
+drückt, bewirkt sie die Löschung von Zeilen. Mit HOP RUBIN kann man längere
+Texte in einen Text einfügen.
+
+
+
+Der Tabulator
+
+Eine weitere wichtige Positionierungshilfe ist die TAB-Taste. Sie wird zum
+Schreiben von Tabellen benötigt. Wie bei einer Schreibmaschine können Ta-
+bulatormarken gesetzt bzw. gelöscht werden.
+
+Der Tabulator hat eine wichtige Funktion für das schnelle Positionieren, auch
+wenn keine Marken eingestellt wurden. Voreingestellte Tabulatormarken sind
+nämlich der Textanfang einer Zeile (Einrückung; falls vorhanden) und die
+Stelle direkt hinter dem letzten Zeichen der Zeile. Betätigt man also die
+Taste TAB, dann springt der Cursor an die nächste dieser voreingestellten
+Positionen. So kann man schnell an den Anfang oder das Ende einer Zeile mit
+dem Cursor gelangen (und z.B. am Zeilenende Zeichen "von hinten" löschen
+oder dort weiterschreiben).
+
+Nun zum Setzen des Tabulators: Er wird gesetzt, indem man den Cursor auf die
+Zeilenposition bringt, in der die Marke plaziert werden soll. Hier betätigt
+man nun HOP TAB. Die Tabulatorsetzung kann man in der Titelzeile an einer
+Markierung ("Dach"-Zeichen) sehen (falls sie im Fensterbereich ist und die
+aktuelle Zeile nicht seitlich verschoben ist). Betätigt man nun an irgend-
+einer Position innerhalb einer Zeile die TAB-Taste, wird der Cursor auf die
+Position der nächsten Tabulatormarkierung (die sich rechts vom Cursor be-
+findet) oder eine der voreingestellten Positionen bewegt.
+
+Gesetzte Tabulatormarken können gelöscht werden, indem man mit der TAB-
+Taste die Position der Tabulatormarke einstellt und dann HOP TAB betätigt.
+Die Marke ist dann gelöscht (das Dach verschwindet in der Titelzeile).
+
+Tabulatormarkierungen hinterlassen keine Spuren in der Datei, sondern dienen
+nur als Positionierungshilfen.
+
+Werden Tabulatormarken gesetzt (HOP TAB), gelten die voreingestellten Tabu-
+latormarken (Anfang und Ende einer Zeile) nicht mehr. Dies ist z.B. bei dem
+Schreiben von Tabellen notwendig. Andererseits möchte man beim Schreiben von
+"normalen" Text wieder die voreingestellten Tabulatormarken bedienen können.
+Mit den Tasten
+
+ ESC TAB
+
+kann man die gesetzten Tabulatormarken (erkenntlich an dem "Dach"-Zeichen in
+der Kopfzeile) verschwinden lassen. Dann gelten wieder die voreingestellten
+Marken. Erneutes ESC TAB stellt die gesetzten Tabulatormarken wieder her
+usw.
+
+Merke: Das Einstellen und Löschen von Tabulatormarken erfolgt mit HOP TAB;
+das Positionieren auf diese mit TAB. Voreingestellte Tabulatormarken sind
+Zeilenanfang und -ende. ESC TAB wirkt wie ein Umschalter zwischen voreinge-
+stellten und gesetzten Tabulatormarken.
+
+
+
+2. Beschreibung weiterer Funktionen
+
+In diesem Kapitel werden weitere Funktionen des Editors beschrieben, die bei
+dem Erstellen von Texten und Korrekturen sinnvoll einsetzbar sind. Die
+Kenntnis der hier beschriebenen Funktionen sind für erste Arbeiten nicht
+notwendig (dafür reicht das erste Kapitel). Man sollte aber dieses Kapitel
+zumindest überfliegen, damit bei Bedarf die zusätzlichen Möglichkeiten des
+Editors erlernt und angewandt werden können.
+
+
+
+Zeilen aufbrechen und Rückumbruch
+
+Um grössere Textpassagen einzufügen, betätigt man HOP RUBIN nacheinander.
+Diese Tastenfolge kann benutzt werden, um eine Zeile zu spalten (Zeile auf-
+zubrechen). HOP RUBOUT am Ende einer Zeile macht einen Rückumbruch.
+
+Wie bereits beschrieben, bewirkt HOP RUBIN in einer Zeile, daß der Zeilenrest
+rechts vom Cursor und alle Zeilen unterhalb der aktuellen Zeile scheinbar
+verschwinden. REST in der Titelzeile erinnert daran, daß ein Teil der Datei
+nicht sichtbar ist.
+
+Wird unmittelbar nach HOP RUBIN wiederum HOP RUBIN betätigt, wird der vor-
+herige Zeilenrest als eigenständige Zeile dargestellt. Es ist damit eine Auf-
+spaltung einer Zeile in zwei Zeilen vollzogen.
+
+Der umgekehrte Fall, nämlich zwei Zeilen zu einer zusammenzufassen (sog.
+Rückumbruch), ist durch HOP RUBOUT hinter dem letzten Zeichen einer Zeile
+möglich. (Hinter das letzte Zeichen einer Zeile kann einfach mit dem
+Tabulator positioniert werden).
+
+Das Aufbrechen einer Zeile und der Rückumbruch zusammen angewandt stellen
+also den ursprünglichen Zustand wieder her. Beispiel: Mit HOP RUBIN bricht
+man eine Zeile auf (der Rest der Zeile und nachfolgende Zeilen verschwinden
+vom Bildschirm). Erneutes HOP RUBIN stellt den rechten Zeilenteil auf der
+nächsten Zeile und die nachfolgenden Zeilen auf dem Bildschirm wieder dar. Da
+der Cursor sich noch immer am rechten Rand der aufgebrochenen Zeile befindet,
+kann man mit HOP RUBOUT den ursprünglichen rechten Zeilenteil wieder re-
+kombinieren.
+
+Merke: Zweimaliges HOP RUBIN spaltet eine Zeile auf; HOP RUBOUT hinter dem
+Ende einer Zeile fügt die nachfolgende Zeile an die aktuelle an (Rück-
+umbruch).
+
+
+
+Zahlentabellen schreiben: Dezimaltabulator
+
+Beim Schreiben von Zahlentabellen sollen die Zahlen oft rechtsbündig im Text
+erscheinen. Dazu bietet der Editor den Dezimaltabulator an.
+
+Für jede Zahlenkolonne wird die gewünschte Position der Einerstelle (also der
+letzten Stelle) mit Hilfe eines Tabulators eingestellt. Mit TAB wird der
+Cursor zur jeweils nächsten Tabulatormarke vorgerückt. Werden nun Ziffern
+geschrieben, so schreibt man nicht - wie gewohnt - nach rechts, sondern die
+Ziffern werden nach links eingerückt. Etwas genauer: Beim Drücken einer
+Zifferntaste wird, solange links vor der Zahl noch ein Blank, eine Zahl, "+",
+"-" oder ein Punkt sichtbar ist, diese gelöscht und die hierdurch neu ent-
+standene Ziffernfolge rechtsbündig an der Tabulatorposition geschrieben.
+Zahlenkolonnen können so leicht und rechtsbündig geschrieben werden.
+Wird eine Proportionalschrift (Schrift, bei der die Zeichen unterschiedliche
+Breiten haben) verwandt, sollte man zwischen den einzelnen Zahlenkolonnen
+mindestens zwei Leerzeichen schreiben. Andernfalls bekommt man - auf Grund
+der unterschiedlicher Zeichenbreiten - keine rechtsbündigen Kolonnen ge-
+druckt.
+
+ 12 12345,78
+ 1 0,23
+ 12345 1234,00
+
+Merke: Ziffern werden bei Einsatz des Tabulators automatisch rechtsbündig ab
+der Tabulatormarke geschrieben.
+
+Es gibt somit vier nützliche Automatiken: neben dem automatischen Dezimal-
+tabulator der Wortumbruch, die Einrückautomatik und die Zeileneinfügeauto-
+matik beim einfügenden Schreiben.
+
+
+
+Den Editor lernen lassen
+
+Beliebige Folgen von Tastenbetätigungen können gelernt und Tasten zugeordnet
+werden. Das ist sinnvoll, wenn wiederholt immer die gleichen Tastenbe-
+tätigungen ausgeführt werden müssen, wie z.B. in Tabellenzeilen etwas ein-
+fügen oder wenn des öfteren gleiche Texte geschrieben werden müssen, wie
+z.B. ein Absender, Grußformeln usw.
+
+Der Lernmodus wird durch Betätigen der Tasten ESC HOP eingeschaltet (es
+erscheint LEARN als Kontrolle in der Titelzeile). Alle Tastenanschläge (auch
+Tastenanschläge wie RETURN: man kann also auch mehrere Zeilen lernen lassen)
+werden jetzt gelernt bis zum expliziten Ausschalten des Lernmodus.
+
+Das Beenden oder Ausschalten des Lernmodus erfolgt durch Drücken der drei
+Tasten ESC HOP 'taste'. Dabei wird die gelernte Tastenanschlagsfolge, auch
+Lernsequenz genannt, der Taste 'taste' zugeordnet.
+
+Durch späteres Betätigen der Tastenfolge ESC 'taste' kann der gelernte Text
+an jeder Stelle der Datei geschrieben werden. Beispiel: Ein "Schreiberling"
+hat jeden Tag 27 mal die Worte 'Hochschulrechenzentrum der Universität
+Bielefeld' zu tippen. Er läßt diese Worte den Editor lernen mit
+
+ ESC HOP Hochschulrechenzentrum der Universität Bielefeld
+ ESC HOP b
+
+Die Worte liegen jetzt auf der Taste 'b'. Wird 'b' gedrückt, erscheint ein
+'b' auf dem Bildschirm. Mit ESC 'b' erscheinen die obigen Worte. ESC ist
+also notwendig, um das normale 'b' von der Lernsequenz zu unterscheiden.
+
+Bei einigen Terminaltypen gibt es Tasten, die vom EUMEL-System nicht benutzt
+werden. Bei diesen kann man ESC beim Aufruf der Lernsequenz weglassen.
+
+Welche Tasten dürfen zum Lernen belegt werden? Alle Tasten, außer
+
+- vom System benutzte Tasten, wie SV, CTRL;
+- vom Editor (je nach Anwendung) vorbelegte Tasten, wie die Tasten q oder
+ ESC und HOP;
+- durch Programmierung (siehe dieses Kapitel) fest belegte Tasten.
+
+Praktische Tips: Man sollte die Tastatur nicht mit Lernsequenzen überlasten,
+weil man sich viele Tasten nicht merken kann. Besser ist es, einige wenige
+Tasten fest zu belegen und andere für momentane Aufgaben einzusetzen.
+
+Der Einsatz von Lernsequenzen ist besonders sinnvoll zum Schreiben von An-
+weisungen für die Textkosmetik. Anweisungen wie z.B. 'unterstreichen ein-
+schalten', Schrifttyp-Anweisung usw. werden zweckmäßigerweise auf Tasten
+gelegt.
+
+Hat man sich einmal beim Lernen verschrieben, so ist das nicht weiter
+schlimm: es kann ohne Bedenken korrigiert werden (z.B. mit der Taste RUBOUT).
+Solche Tastenanschläge werden dann allerdings auch gelernt, was man aber
+beim Einsetzen der Lernsequenz kaum sieht.
+
+Merke: Tastenanschläge werden mit ESC HOP gelernt und mit ESC HOP 'taste'
+auf eine Taste gelegt. Mit ESC 'taste' kann die Lernsequenz jederzeit abge-
+rufen werden.
+
+
+
+Mehrere Zeilen auf einmal verarbeiten: Markieren
+
+Oft ergibt sich die Notwendigkeit, mehrere Zeilen oder ganze Textpassagen zu
+löschen oder zu verschieben. Hierbei hilft die Taste MARK, mit der man Texte
+markieren (also kennzeichnen) kann. Die so markierten Texte können dann auf
+verschiedene Weisen als Ganzes verarbeitet werden.
+
+Durch Drücken der Taste MARK wird die Markierung eingeschaltet und - bei
+erneuter Betätigung - wieder ausgeschaltet. Der Anfang der Markierung wird
+"festgehalten" und man kann nun das Markierende durch die Positionierungs-
+tasten und die HOP-Taste in Richtung auf das Dateiende verschieben, wobei
+die dazwischen liegenden Zeichen markiert (in der Regel "video-invertiert"
+dargestellt) werden. Ein so markierter Text kann mit ESC RUBOUT gelöscht
+werden. Markieren und löschen mit ESC RUBOUT ist eine bequeme und sichere
+Löschmethode, da man genau sieht, was gelöscht wird.
+
+Der gelöschte Abschnitt ist aber nicht vollständig gelöscht, sondern er kann
+an anderer (oder an der gleichen) Stelle im Text durch ESC RUBIN wieder ein-
+efügt werden. Dies gilt aber nur für den zuletzt gelöschten Text. Auf diese
+Art kann ein Textabschnitt beliebiger Länge an eine andere Stelle des Textes
+sicher, schnell und bequem verschoben werden. Zusätzlich ist das nachträg-
+liche Korrigieren von fehlerhaften Löschungen leicht möglich, weil der Text
+wieder mit ESC RUBIN leicht reproduziert werden kann.
+
+Mit eingeschalteter Markierung kann auch geschrieben werden. Das markierende
+Schreiben ist eine besonders vorsichtige Art der Texterstellung, denn der
+Texteinschub bleibt erst durch Ausschalten der Markierung (MARK) wirklich
+bestehen. Er kann wieder gelöscht werden (ESC RUBOUT) und an eine andere
+Stelle gebracht werden (ESC RUBIN). Beim markierenden Schreiben wirkt
+RUBOUT immer auf das zuletzt geschriebene Zeichen.
+
+Die Markierung kann auch dazu verwendet werden, auf markierte Textabschnitte
+eigene Benutzerprogramme anzuwenden.
+
+Merke: Die Markierung schaltet man durch die Taste MARK ein und aus. Ein
+markierter Abschnitt kann gelöscht werden (ESC RUBOUT) und an einer anderen
+Stelle wieder eingefügt werden (ESC RUBIN). Mit eingeschalteter Markierung
+kann auch geschrieben werden. Die Markierung dient ebenfalls als Parameter
+für Textverarbeitungsprogramme.
+
+
+
+Zwei einfache Kommandos
+
+Einige Operationen kann man nur mühselig mit den bis jetzt beschriebenen
+Tasten durchführen. Z.B. ist es sehr zeitaufwendig, eine bestimmte Text-
+stelle zu finden. Andere Operationen sind mit den im vorigen Kapitel be-
+schriebenen Tasten überhaupt nicht möglich, wie etwa die Zeilenbreite ein-
+zustellen oder Programme aufzurufen, die die zu editierende Datei ver-
+arbeiten. Solche Operationen werden durch Kommandos ermöglicht, die man vom
+Editor aus geben kann.
+
+Durch zweimaliges Betätigen von ESC erfolgt die Aufforderung
+
+ gib kommando :
+
+Es erscheint auf dem Bildschirm eine Kommandozeile, in der der Benutzer
+Kommandos (d.h. ELAN-Programme) schreiben kann. Durch Betätigen der Taste
+RETURN wird das Kommando ausgeführt. Beispiel:
+
+ ESC ESC (* es erscheint 'gib kommando :' *)
+ "diese Zeichen"
+ RETURN
+
+Durch die Angabe eines TEXTes in Anführungstrichen wird nach dem einge-
+schlossenen TEXT 'diese Zeichen' ab der aktuellen Cursor-Position gesucht.
+Wird 'diese Zeichen' gefunden, bleibt der Cursor auf dem gesuchten Text
+stehen. Andernfalls steht der Cursor hinter dem Ende der letzten Zeile der
+Datei. Weiteres Beispiel:
+
+ ESC ESC
+ 127
+ RETURN
+
+Durch dieses Kommando wird auf die 127. Zeile positioniert.
+
+Diese beiden häufig benötigten Kommandos haben eine Sonderstellung und
+werden speziell behandelt, weil sie nicht der allgemeinen ELAN-Syntax ent-
+sprechen. Darum dürfen sie auch nicht in Verbindung mit anderen Kommandos
+verwendet werden (siehe nächsten Abschnitt). Alle anderen Kommandos, die wir
+in den nächsten Abschnitten beschreiben, entsprechen der ELAN-Syntax und
+sind somit allgemeine Kommandos.
+
+Merke: Kommandos nach man nach zweimaligen Betätigen der ESC-Taste schreiben.
+Mit RETURN wird die Ausführung des Kommandos ausgelöst. Durch Angabe eines
+TEXTes wird ab der aktuellen Cursor-Position nach diesem TEXT gesucht. Durch
+die Angabe einer ganzen Zahl (INT) wird auf die entsprechende Zeilennummer
+in der Datei positioniert.
+
+
+
+Beliebige Kommandos
+
+Beliebige Kommandos (siehe Monitor-Beschreibung) und ELAN-Programme sind
+zulässig.
+
+Die Kommandozeile kann wie eine "normale" Textzeile editiert werden (Posi-
+tionieren, Überschreiben, Einfügen, Löschen und Markieren). Erzeugt ein
+Programm eine Ausgabe oder rufen fehlerhafte Kommandos Fehlermeldungen
+hervor, werden diese in der ersten Zeile des Bildschirms angezeigt. Danach
+ist man wieder im Editor und kann wie gewohnt arbeiten.
+
+Die oben beschriebenen zwei Spezial-Kommandos kann man nicht mit anderen
+Kommandos zusammen verbinden (mit ';'). Deshalb gibt es für sie auch eine
+ELAN-Form, die es erlaubt, sie mit anderen Kommandos zusammen zu verwenden:
+
+a) TEXT suchen ab der aktuellen Cursor-Position (D ist eine Abkürzung für
+ 'DOWN'):
+
+ "diese Zeichen" (* Spezial-Version *)
+ D "diese Zeichen" (* Allgemeine Version *)
+
+b) Auf eine Zeile Positionieren (T ist eine Abkürzung für TO LINE):
+
+ 127 (* Spezial-Version *)
+ T 127 (* Allgemeine Version *)
+
+Es können mehrere Kommandos in der Kommandozeile angegeben werden. Die ein-
+zelnen Kommandos müssen in diesem Fall mit ';' voneinander getrennt werden.
+Beispiel:
+
+ ESC ESC
+ T 1; D "noch Zeichen" RETURN
+
+Diese zwei Kommandos werden nacheinander ausgeführt. Zuerst wird auf die
+erste Zeile positioniert und dann (von der ersten Zeile) nach 'noch Zeichen'
+gesucht. Damit ist es möglich, die Datei nicht nur von der aktuellen Zeile zu
+durchsuchen, sondern die gesamte Datei. Soll nicht in Richtung auf das Datei-
+ende, sondern in Richtung auf den Dateianfang (also nach "oben") gesucht
+werden, kann man das U-Kommando (Abkürzung für UP) verwenden:
+
+ ESC ESC
+ U "noch'n Text" RETURN
+
+Ein weiteres Kommando ist das C-Kommando (Abkürzung für 'CHANGE'), mit
+welchem man einen TEXT sucht und diesen dann ersetzen kann. Beispiel:
+
+ ESC ESC
+ "alte Zeichen" C "neue Zeichen" RETURN
+
+Es wird ab der aktuellen Cursor-Position nach 'alte Zeichen' gesucht. Wird
+der TEXT gefunden, wird er durch 'neue Zeichen' ersetzt. Der Cursor befindet
+sich in diesem Fall nach dem ersetzten TEXT. Wird 'alte Zeichen' dagegen
+nicht in der Datei gefunden, befindet sich der Cursor (wie beim erfolglosen
+Suchen mit D) am Ende der letzten Zeile der Datei.
+
+Wie alle andern Kommandos kann auch das C-Kommando mit anderen Kommandos
+verbunden werden. Beispiel:
+
+ ESC ESC
+ T 500; "Schreibfelher" C "Schreibfehler" RETURN
+
+Hier wird ab der 500. Zeile der Datei nach 'Schreibfelher' gesucht und ggf.
+ersetzt. Soll ein TEXT nicht nur einmal, sondern bei jedem Auftreten ersetzt
+werden, benutzt man das CA-Kommando (Abkürzung für CHANGEALL):
+
+ ESC ESC
+ "dieser alte Text" CA "dieser neue Text" RETURN
+
+Dadurch wird 'dieser alte Text' bei jedem Auftreten ab der aktuellen Cursor-
+Position durch 'dieser neue Text' ersetzt.
+
+Merke: Mehrere Kommandos werden mit ';' verbunden.
+
+
+
+Kommandos auf Tasten legen
+
+Oft benutzte Kommandos können auf Tasten gelegt werden. Damit ist es möglich,
+den Editor auf spezielle Bedürfnisse eines Benutzers zu modifizieren.
+
+Anstatt der Taste RETURN beim Abschluß können oft benutzte Kommandos mit der
+Drei-Tastenfolge ESC ! 'taste' auf eine Taste gelegt werden. Beispiel:
+
+ ESC ESC (* es erscheint die Kommandozeile *)
+ D "Schreibfehler"
+ ESC ! s (* das Kommando 'DOWN "Schreibfehler"' ist
+ nun auf die Taste 's' gelegt *)
+
+Wird nun die Taste 's' gedrückt, erscheint das Zeichen 's' auf dem Bildschirm.
+Mit ESC s wird das D-Kommando ausgeführt. Natürlich können auch komplizier-
+tere ziertere Kommandos auf Tasten gelegt werden.
+
+Einige Tasten sind bereits mit Kommandos belegt (man kann sie aber ver-
+ändern). Will man ein Kommando, welches auf eine Taste gelegt wurde, ver-
+ändern oder löschen, drückt man im Kommandodialog (!) die Drei-Tastenfolge
+ESC ? 'taste'. Beispiel:
+
+ ESC ESC (* in den Kommandodialog gehen *)
+ ESC ? s (* es erscheint nun: 'D "Schreibfehler"' *)
+
+Dieses Kommando kann nun z.B. verändert und ausgeführt (durch RETURN) oder
+wiederum auf die gleiche oder eine andere Taste gelegt werden (durch
+ESC ! 'taste').
+
+Die Ausführung eines Kommandos kann meist mit ESC abgebrochen werden,
+z.B. wenn ein Suchkommando unerwünscht weit reicht.
+
+Merke: Kommandos können auf Tasten gelegt werden (wie beim Lernen). Das
+letzte Kommando kann durch ESC f wiederholt werden.
+
+
+
+Die wichtigsten Kommandos zur Textverarbeitung
+
+Einige Kommandos sind speziell für die Textverarbeitung im Editor program-
+miert. Die wichtigsten werden hier vorgestellt.
+
+Kommando Bedeutung
+-----------------------------------------------------------------------------
+"text" Text suchen:
+D "text" Der zu suchende Text muß in Anführungszeichen geschrieben
+ werden (damit werden auch Leerzeichen innerhalb des ge-
+ suchten Textes wichtig). Es wird ab der Stelle in der
+ Datei in Richtung auf das Dateiende hin gesucht (also
+ "nach unten"), an der sich der Cursor befindet. Wird der
+ Text gefunden, positioniert der Editor den Cursor direkt
+ dahinter. Beispiel:
+
+ D "Autor"
+
+ sucht nach dem ersten Auftreten von 'Autor'. Beachte, daß
+ bei der Suche nach Zeichen, die man nicht direkt mit der
+ Tastatur schreiben kann, der Codewert angegeben werden
+ muß (vergl. dazu die EUMEL-Codetabelle). Beispiel:
+
+ DOWN ""217"" (* sucht ein ä *)
+ DOWN "Diesen Text mu"251" man finden"
+
+ (Ein Codewert innerhalb eines Textes muß in " einge-
+ schlossen werden).
+ Wird nur ein Text gesucht, kann man auch nur diesen
+ angeben. Beispiel:
+
+ "diesen fehler"
+
+D nummer (Relatives) Positionieren in Richtung auf das Dateiende.
+ Beispiel:
+
+ D 75
+
+ positioniert um 75 Zeilen in Richtung auf das Dateiende.
+
+U "text" Analog D, aber in Richtung auf den Dateianfang ("nach
+ oben").
+
+U nummer Analog D, aber in Richtung auf den Dateianfang.
+
+nummer Absolutes Positionieren:
+T nummer Durch Angabe einer Zahl, wird auf die entsprechende
+ Zeile der Datei positioniert. Beispiel:
+
+ T 317
+ 317
+
+ Ist die Datei bereits vor der Zeile '317' zu Ende, wird
+ auf die letzte Zeile der Datei positioniert.
+
+"alt" C "neu" Suchen und Ersetzen eines Textes: Sucht nach dem Text
+ 'alt'. Falls vorhanden, wird 'alt' durch 'neu' ersetzt.
+ Beispiel:
+
+ "einfach" C "leicht"
+
+ ersetzt 'einfach' durch 'leicht'.
+
+"alt" CA "neu" Suchen aller 'alt' ab der aktuellen Position bis zum
+ Dateiende und ersetzen durch 'neu'.
+
+type ("text") Schreiben eines 'text' durch ein Kommando. Das type-Kom-
+ mando wird häufig benutzt, um Zeichen zu schreiben, die
+ nicht auf der Tastatur zu finden sind. In diesem Fall muß
+ der Codewert des Zeichens angegeben werden (jeweils in
+ doppelten "). Beispiel (vergl. auch EUMEL-Codetabelle):
+
+ type (""251"")
+
+ schreibt ein ß an die aktuelle Position der Zeile.
+
+Merke: Durch das D- bzw. U-Kommando kann ein Text in der Datei gesucht
+werden. Mit C kann ein Text gesucht und ersetzt werden. "alt" CA "neu" er-
+setzt alle 'alt' durch 'neu'. 'type' schreibt ein Zeichen (oder einen Text).
+Durch T kann auf eine bestimmte Zeile der Datei positioniert werden.
+
+
+
+Texte aus anderen Dateien einfügen oder in andere Dateien schreiben
+
+Manchmal ist es notwendig, einen Text in eine andere Datei zu schreiben
+(z.B. wenn man diesen Text noch einmal verwenden will) oder einen Text einer
+anderen Datei in den zu bearbeitenden Text einzufügen. Die GET- und PUT-
+Kommandos bieten die Möglichkeit, Texte zwischen Dateien auszutauschen
+(vergl. auch Paralleleditor).
+
+Das Kommando GET 'dateiname' holt den Text der Datei "dateiname" an die
+aktuelle Schreibposition. Beispiel:
+
+ GET "absender"
+
+holt den Text 'absender'. Wenn also des öfteren Briefe geschrieben werden,
+braucht man sich den Absender nur einmalig in die Datei 'absender' zu schrei-
+ben und kann diesen mit dem Kommando GET (was man auf eine Taste legen kann)
+u.U. mehrmals an verschiedenen Stellen in die Datei einfügen.
+
+Das Kommando PUT (abgekürzt: P) schreibt einen vorher markierten Text in
+eine Datei. Beispiel:
+
+ PUT "Tabelle"
+
+schreibt einen markierten Text in die Datei 'Tabelle'. 'Tabelle' wird ggf.
+eingerichtet. Ist die Datei 'Tabelle' bereits vorhanden, so wird erfragt, ob
+die Datei gelöscht werden kann, um den markierten Text aufzunehmen (über-
+schreiben). Andernfalls wird der markierte Text an den bereits vorhandenen
+Text in 'Tabelle' angefügt. Es ist somit durch mehrmaliges markieren und dem
+PUT-Kommando möglich, Texte aus einer Datei aufzusammeln und in eine neue
+Datei zu geben.
+
+Merke: Die GET- und PUT-Kommandos schreiben bzw. holen Texte aus Dateien.
+
+
+
+Breitere Zeilen bearbeiten
+
+Der Editor ist auf eine Zeilenbreite von 77 Zeichen eingestellt. Oft ist es
+notwendig, mit einer anderen Zeilenbreite zu schreiben, welches man mit dem
+LIMIT-Kommando einstellen kann. Aber auch die Positionierung innerhalb einer
+Zeile wird dadurch etwas anders, weil bei breiteren Zeilen als die Bild-
+schirmbreite die Zeile nicht auf einmal auf den Bildschirm paßt. In diesem
+Fall wird gerollt.
+
+Eine andere Zeilenbreite stellt man durch 'limit' ein. Beachte, daß die somit
+eingestellte Zeilenbreite für die gesamte Datei gilt. Beispiel:
+(Soll eine veränderte Zeilenbreite nur für einen Abschnitt gelten, muß man
+eine Textkosmetik-Anweisung einfügen, welches erst nach Anwendung von
+'lineform' wirkt.)
+
+ limit (180)
+
+Nun kann man wie gewohnt schreiben. Allerdings wird die aktuelle Zeile, in
+der man sich befindet, nicht wie gewohnt am Bildschirmende umgebrochen,
+sondern erst an der Spalte 180 (sofern sie nicht vorher durch die RETURN-
+Taste beendigt wird). Wird über das rechte Bildschirmende hinaus geschrieben,
+bleibt die Cursor-Position am Ende des Bildschirms erhalten, aber die Zeile
+wird beim weiteren Schreiben nach links verschoben, "rollt" also nach links
+(der Anfang der Zeile verschwindet scheinbar nach links).
+
+Mit der Positionierung verhält es sich ähnlich. Wird über den rechten Bild-
+schirmrand mit RECHTS positioniert, wird die Zeile ebenfalls gerollt. HOP
+RECHTS dagegen bewirkt ein Blättern nur innerhalb dieser Zeile nach rechts.
+Analog verläuft es bei verschobener Zeile, wenn nach links (LINKS bzw. HOP
+LINKS) positioniert wird.
+
+Beim Schreiben von Tabellen kann es sinnvoll sein, das Fenster vorübergehend
+auf eine andere Anfangsposition (als 1) einzustellen. Das kann mit dem
+'margin'-Kommando erfolgen. Beispiel:
+
+ margin (50)
+
+Das Fenster des Editors zeigt nun einen Ausschnitt aus der Datei, beginnend
+ab Spalte 50. In der Titelzeile wird "M50" angezeigt.
+
+Merke: Eine veränderte Zeilenbreite wird mit dem limit-Kommando eingestellt.
+Wird über den Bildschirmrand positioniert, wird die Zeile gerollt. Mit dem
+'margin'-Kommando kann spaltenmäßig ein Anfangspunkt des Fensters einge-
+stellt werden.
+
+
+
+Paralleles Editieren (Fenstereditor)
+
+Oft ist notwendig, mit mehreren Dateien gleichzeitig zu arbeiten, z.B. wenn
+aus einer Datei etwas in eine andere kopiert werden muß, wenn Fehler durch
+die Textkosmetik-Programme oder einen Compiler gefunden werden oder wenn man
+kurz etwas in einer andern Datei nachschauen will. Zu diesem Zweck bietet der
+Editor die Möglichkeit, zwei (oder mehr) Dateien zur gleichen Zeit zu be-
+arbeiten.
+
+Um ein neues Editor-Fenster einzuschachteln, betätigt man im Editor
+
+ ESC e
+
+Dies eröffnet ein Fenster auf eine andere Datei, deren Name interaktiv er-
+fragt wird. Die obere linke Ecke des Fensters befindet sich an der aktuellen
+Cursor-Position. Dabei darf sich der Cursor nicht zu sehr am rechten oder
+unteren Rand befinden (weil das Fenster sonst zu klein würde). In diesem
+"Fenster" auf eine andere Datei kann man genauso arbeiten, wie im "normalen"
+Editor. ESC q verläßt den aktuellen Fenstereditor (und alle darin einge-
+schachtelten Fenster).
+
+Mit der Tastenfolge
+
+ ESC w
+
+kann man von einem Fenster in das benachbarte wechseln (zyklisch). Insbeson-
+dere kann ein markierter Teil einer Datei mit dem Kommando
+
+ ESC p (* oder: PUT "" *)
+
+in eine temporäre Datei geschrieben und nach ESC w mit
+
+ ESC g (* oder: GET "" *)
+
+in die andere Datei eingefügt werden.
+
+Betätigt man ESC e ungefähr in der Mitte des Bildschirms, hat man das Fenster
+auf die neue Datei in der unteren Hälfte des Bildschirms und die "alte" Datei
+in der oberen Bildschirmhälfte. Dies nennt man "Paralleleditor", weil zwei
+Dateien zur gleichen Zeit editiert werden können. Der Paralleleditor wird
+auch von anderen Programmen benutzt, wie z.B. dem ELAN-Compiler, um Fehler-
+meldungen bequem anzuzeigen.
+
+Das Notizbuch schlägt man mit
+
+ ESC n
+
+auf. In diesem Notizbuch werden Informationen durch die Prozedur
+
+ note
+
+geschrieben.
+
+Merke: Der Fenstereditor wird durch ESC e aufgerufen und mit ESC q verlassen.
+Mit ESC w kann zwischen Dateien umgeschaltet werden. In jeder Datei stehen
+die gleichen Funktionen wie im "einfachen" Editor zur Verfügung. Man kann
+markierte Texte mit PUT bzw. GET von einer Datei in die andere bringen
+(Kopieren).
+
+
+
+Arbeiten mit dem Zeileneditor
+
+Der Zeileneditor erlaubt ein Editieren einer Eingabe mit allen Editor-
+Funktionen.
+
+Der Zeileneditor (auch "Feldeditor" genannt) wird über die Prozedur
+
+ editget
+
+aufgerufen. Durch diese Prozedur kann eine Zeile vom Terminal wie im Editor
+eingegeben werden, d.h. es können u.a. Einfügungen bzw. Löschungen in der
+Zeile vorgenommen werden. 'editget' dient darum als Grundlage für alle 'get'-
+Prozeduren. Beispiel:
+
+ TEXT VAR eingabe :: "";
+ put ("Bitte geben Sie einen Wert ein:");
+ editget (eingabe);
+ line
+
+'editget' kann aber auch einen Wert ausgeben, den ein Benutzer ggf.
+verändern kann. Beispiel:
+
+ TEXT VAR eingabe :: "trium10");
+ put ("Bitte Schrifttyp angeben:");
+ editget (eingabe);
+ line
+
+Hier kann ein Benutzer den TEXT 'trium10' verändern oder nur RETURN betäti-
+gen.
+
+Es gibt noch weitere Versionen von 'editget', bei denen man die Zeilenbreite,
+reservierte Tasten u.a.m. angeben kann.
+
+Merke: 'editget' ist der Zeileneditor.
+
+
+
+3. Vorbelegung von Tasten
+
+Wie schon beschrieben, können Lernsequenzen und Kommandos (d.h. ELAN-
+Programme) Tasten zugeordnet werden. Da einige Funktionen häufig benötigt
+werden, sind diese standardmäßig bestimmten Tasten zugeordnet.
+
+
+
+Kommandodialog
+
+ESC ESC Kommandodialog einschalten.
+
+ESC ! taste Im Kommandodialog: geschriebenes Kommando auf Taste legen.
+
+ESC ? taste Im Kommandodialog: Auf 'taste' gelegtes Kommando anzeigen zum
+ Editieren.
+
+ESC k Im Kommandodialog: Das zuletzt editierte ELAN-Programm an-
+ zeigen.
+
+
+
+Lernen
+
+ESC HOP Lernen einschalten.
+
+ESC HOP taste Lernsequenz auf 'taste' legen.
+
+
+
+Operationen auf Markierungen
+
+ESC RUBOUT Markiertes "vorsichtig" löschen.
+
+ESC RUBIN Vorsichtig Gelöschtes einfügen.
+
+ESC p Markiertes in die Scratch-Datei kopieren (PUT ""), an
+ schließend löschen (kann mit ESC g an anderer Stelle re-
+ produziert werden).
+
+ESC d Duplizieren: Markiertes in die Scratch-Datei kopieren
+ (PUT ""), anschließend die Markierung abschalten. (Kann mit
+ ESC g beliebig oft reproduziert werden).
+
+ESC g MIT ESC p gelöschtes oder mit ESC d dupliziertes an aktuelle
+ Cursor-Stelle schreiben, d.h. Scratch-Datei an aktueller
+ Stelle einfügen (GET "").
+
+
+
+Weitere Operationen
+
+ESC q Verlassen des Editors.
+
+ESC e Fenstereditor einschalten.
+
+ESC n Notizbuch "aufschlagen".
+
+ESC w Dateiwechsel beim Fenstereditor.
+
+ESC f Nochmalige Ausführung des letzten Kommandos
+
+ESC b Das Fenster wird auf den linken Rand der aktuellen (ggf.
+ verschobenen) Zeile gesetzt.
+
+ESC RECHTS Zum nächsten Wortanfang.
+
+ESC LINKS Zum vorigen Wortanfang.
+
+ESC 1 Zum Anfang der Datei.
+
+ESC 9 Zum Ende der Datei.
+
+
+
+Zeichen schreiben
+
+ESC a Schreibt ein ä.
+ESC A Schreibt ein Ä.
+ESC o Schreibt ein ö.
+ESC O Schreibt ein Ö.
+ESC u Schreibt ein ü.
+ESC U Schreibt ein Ü.
+ESC s Schreibt ein ß.
+ESC ( Schreibt eine [.
+ESC ) Schreibt eine ].
+ESC < Schreibt eine {.
+ESC > Schreibt eine }.
+ESC \# Schreibt ein \#, was auch gedruckt werden kann.
+ESC blank Schreibt ein (geschütztes) Leerzeichen.
+
+
+
+4. Komplexere Kommandos (ELAN-Programme)
+
+In diesem Kapitel finden Sie (neben den bereits in den vorherigen Kapiteln
+beschriebenen) eine Übersicht über die vorgefertigten Kommandos. Weitere
+können leicht vom Benutzer und Programmierer selbst erstellt werden.
+
+
+
+Wiederholungen schreiben
+
+In der Programmiersprache ELAN gibt es ein Sprachmittel, um Anweisungen
+wiederholen zu lassen. Dieses Sprachmittel nennt man Wiederholungsanweisung
+oder Schleife. Durch dieses Sprachmittel ist es leicht möglich, eine oder
+mehrere Kommandos mehrmals ausführen zu lassen.
+
+Eine Wiederholung, meist Schleife genannt, wird durch die Worte REP (steht
+für 'REPEAT', was soviel wie 'wiederhole' heißt) und PER (die Umkehrung von
+REP) oder END REP gebildet. Alle Anweisungen, die zwischen diesen Worten
+stehen, werden wiederholt ausgeführt (bis das Ende der Datei erreicht ist).
+Damit kann man einen Text in der gesamten Datei ändern. (In den folgenden
+Beispielen schreiben wir die Kommandozeile der besseren Übersichtlichkeit
+halber in mehreren Zeilen). Beispiel:
+
+ T 1;
+ WHILE NOT eof REP
+ "alter text" C "neuer text"
+ PER
+
+Durch die erste Anweisung wird zur ersten Zeile der Datei positioniert. Dann
+steht im Programm eine sogenannte "abweisende Schleife", die durch 'WHILE
+bedingung' eingeleitet wird (die Schleife wird solange ausgeführt, bis die
+Bedingung nicht mehr erfüllt ist). Die Bedingung besteht hier aus einer Ab-
+frage auf das Dateiende der bearbeiteten Datei ('eof'). Nach Eintritt in die
+Schleife wird nach 'alter text' gesucht. Falls gefunden, wird er durch
+'neuer text' ersetzt. Das Suchen und ersetzen wird solange durchgeführt, bis
+das Dateiende erreicht wird. Falls 'alter text' nicht gefunden wird, steht
+man auf dem letzten Zeichen der letzten Zeile der Datei (wie bei einer er-
+folglosen wiederholten letzten Suche), so daß die nächste WHILE-Überprüfung
+die Schleife abbricht.
+
+Die meisten der oben beschriebenen Kommandos gibt es nicht nur als Operato-
+ren, sondern auch als Prozeduren. Beispiele:
+
+ T 1 ==> toline (1)
+ D "text" ==> down ("text")
+ U "text" ==> up ("text")
+ D 17 ==> down (17)
+ U 18 ==> up (18)
+ "alt" C "neu" ==> change to ("alt", "neu")
+ "alt" CA "neu" ==> change all ("alt", "neu")
+
+Man kann also das obige Beispiel auch folgendermaßen programmieren:
+
+ toline (1);
+ WHILE NOT eof REP
+ change to ("alter text", "neuer text")
+ PER
+
+Durch dieses zusammengesetzte Editor-Kommando können also ein oder mehrere
+Worte in der gesamten Datei auf einfache Weise geändert werden.
+Natürlich kann man das obige Beispiel einfacher schreiben:
+
+ toline (1); change all ("alter text", "neuer text")
+
+Was muß man nun programmieren, um eine Ersetzung nur einmal pro Zeile vor-
+zunehmen? Erinnern wir uns: nach einer Ersetzung steht der Cursor hinter dem
+ersetzten Text. Somit finden wir bei der erneuten Suche unter Umständen den
+Text nochmals in der aktuellen Zeile. Wenn wir nach einer Ersetzung aber um
+eine Zeile vorwärts positionieren (mit 'down (1)'), kann dies nicht ge-
+schehen. Leider wird durch die Vorwärts-Positionierung die Position des
+Cursors nicht verändert. Somit kann die erneute Suche einen Text in der
+nächsten Zeile verpassen. Man muß also neben der Vorwärts-Positionierung um
+eine Zeile zusätzlich auch noch an den Anfang der Zeile gehen. Für die
+Positionierung innerhalb einer Zeile gibt es die Prozedur
+
+ col (17) (* Positioniert auf die 17. Spalte
+ der aktuellen Zeile *)
+
+Damit können wir nun eine einmalige Ersetzung in einer Zeile programmieren:
+
+ toline (1);
+ WHILE NOT eof REP
+ col (1);
+ change to ("alter text", "neuer text");
+ down (1);
+ PER
+
+Es wird erst auf die erste Zeile, erste Spalte positioniert. Dann wird 'alter
+text' gesucht und ggf. durch 'neuer text' ersetzt. Danach wird eine Zeile
+vorwärts positioniert, wiederum auf Spalte 1. Dadurch ist gewährleistet, daß
+eine Ersetzung nur einmal pro Zeile vorgenommen wird und immer von der
+ersten Spalte einer Zeile aus gesucht wird. Dies geschieht solange, bis das
+Ende der Datei erreicht ist.
+
+Manchmal ergibt sich die Notwendigkeit, in Tabellen in jeder Zeile noch Leer-
+spalten einzufügen oder zu entfernen. Auch dies kann mit der Schleife leicht
+erledigt werden:
+
+ toline (1);
+ WHILE NOT eof REP
+ col (48);
+ "" C " ";
+ down (1)
+ PER
+
+Hier werden in jeder Zeile an der Spalte 48 drei Leerzeichen eingefügt. In
+diesem Fall suchen wir ab der Spaltenposition 48 einen sogenannten "Niltext"
+("leerer Text"). Dieser Text wird natürlich immer gefunden. Aber man muß
+hier aufpassen, denn der gesuchte Text sollte in dieser Zeile vorhanden sein,
+sonst wird in einer der nächsten Zeilen ein TEXT ersetzt, der nicht unbe-
+dingt an der Spaltenposition 48 steht!
+
+Wie bereits angemerkt, sollten in den zu verändernden Zeilen an der Position
+48 ein Leerzeichen stehen, sonst wird das C-Kommando fehlerhaft bei dem
+nächsten TEXT ausgeführt. Das kann man verhindern, indem man folgendes
+programmiert:
+
+ toline (1);
+ WHILE NOT eof REP
+ down (" "); (* sucht das naechste Blank ab Spalte 48 *)
+ IF col = 48
+ THEN change to (" ", " ");
+ FI
+ END REP
+
+Die Prozedur 'col' (ohne Parameter) liefert die aktuelle Spaltenposition
+innerhalb einer Zeile.
+
+Manchmal soll eine Änderung nur in einem bestimmten Bereich vorgenommen
+werden. Dazu gibt es die Prozedur 'line no', mit der man die aktuelle Zeilen-
+nummer erfragen kann. Beispiel:
+
+ toline (50);
+ WHILE NOT eof REP
+ aenderungen
+ UNTIL line no = 100 END REP
+
+In diesem Beispiel werden 'aenderungen' im Zeilenbereich 50 - 100 vorgenom-
+men. 'line no' liefert die aktuelle Zeilennummer des FILEs, welches gerade
+vom Editor bearbeitet wird.
+
+Weitere Beispiele:
+
+ (* suchen in Spalte 17: *)
+ REP
+ down ("muster")
+ UNTIL eof OR col = 17 END REP
+
+ (* in Spalte 1 ersetzen: *)
+ REP
+ down ("alt");
+ IF col = 1
+ THEN "alt" C "neu"
+ FI
+ UNTIL eof END REP
+
+Merke: Eine Wiederholung REP ... PER führt die in ihr enthaltenen An-
+weisungen wiederholt aus. Eine Abfrage auf das Dateiende der bearbeiteten
+Datei ist durch 'eof' möglich.
+
+
+
+Das Notizbuch
+
+Im Notizbuch kann man sich Notizen über den Ablauf von Kommandos machen.
+
+Die Prozedur
+
+ note
+
+schreibt einen INT- oder TEXT-Parameter in eine Zwischendatei. Diese Datei
+kann man sich mit
+
+ ESC n
+
+anschauen. Beispiel:
+
+ (* ersetzen und notieren: *)
+ REP
+ "alt" C "neu";
+ note (line no) (* Zeilennummer der Ersetzung notieren *)
+ UNTIL eof END REP
+
+Merke: Die Prozedur 'note' schreibt in das Notizbuch. Mit ESC n kann man
+sich das Notizbuch anschauen.
+
+
+
+Neue Editor-Kommandos bereitstellen
+
+Sollen neue Editor-Kommandos bereitgestellt werden, muß man dem Editor ggf.
+mitteilen, ob und wie das Fenster auf die Datei auf dem Bildschirm neu ge-
+schrieben werden muß.
+
+Neue Editor-Kommandos kann man allen Benutzern bereitstellen, in dem ein
+Programm geschrieben wird. Beispiel:
+
+ PROC datum schreiben:
+ type (datum).
+
+ datum:
+ date (clock (1)). (* Siehe auch TEIL 8: Standardpakete *)
+ END PROC datum schreiben
+
+Diese Prozedur (oder mehrere) muß noch in ein PACKET "gekleidet" und dann
+insertiert werden. Dann steht 'datum schreiben' allen Benutzern dieser Task
+oder dessen Sohn-Task zur Verfügung (siehe dazu auch TEIL 5: ELAN-Compiler).
+
+Bei etwas komplizierteren Prozeduren sollte man dem Editor mitteilen, ob und
+wie er das Fenster auf die Datei auf dem Bildschirm neu schreiben muß.
+Normalerweise schreibt der Editor nach einem Kommando den gesamten Bild-
+schirm neu. Dies kann man verhindern, indem man die Prozedur
+
+ nichts neu
+
+aufruft. Sie teilt dem Editor mit, daß das Fenster nicht neu geschrieben
+werden muß. Weitere Prozeduren teilen dem Editor mit, daß Teile des Fensters
+neu geschrieben werden müssen:
+
+ satznr neu (* Zeilennummer links oben *)
+ ueberschrift neu
+ zeile neu
+ abschnitt neu
+ bild neu
+
+Dabei kann man die Prozeduren in beliebiger Reihenfolge aufrufen, wobei
+jeweils immer die größte Änderung dominiert. Beispiel:
+
+ nichts neu;
+ ...
+ zeile neu;
+ ...
+ bild neu;
+ ...
+ ueberschrift neu
+ ...
+
+'bild neu' dominiert über 'zeile neu',
+'zeile neu' dominiert über 'ueberschrift neu';
+'ueberschrift neu' dominiert über 'nichts neu'.
+
+Im obigen Beispiel 'datum schreiben' würde es also ausreichen, am Anfang der
+Prozedur 'nichts neu' und am Ende 'zeile neu' aufzurufen, damit nur die
+aktuelle Zeile neu geschrieben wird.
+
+Manchmal ist es notwendig, dem Benutzer bei einer Kommandoverarbeitung neue
+Zustände direkt anzuzeigen. Dafür gibt es die Prozeduren
+
+ satznr zeigen
+ ueberschrift zeigen
+ bild zeigen
+
+Beispiel:
+
+ satznr zeigen (line no)
+
+zeigt bei einer Kommandoverarbeitung die aktuelle Zeilenummer.
+
+Merke: Normalerweise baut der Editor nach einer Kommandoausführung das
+Fenster auf dem Bildschirm neu auf. Mit 'nichts neu' kann das verhindert
+werden. Weitere Prozeduren teilen dem Editor mit, welche Fensterteile neu
+geschrieben werden müssen. Das Schreiben von Fensterteilen kann auch direkt
+ausgelöst werden.
+
+
+
+Die ELAN-Notation
+
+Kommandos werden in ELAN-Notation beschrieben. Dabei bedeuten:
+
+OP Operator.
+ Der Name des Operators muß mit grossen Buchstaben vor oder
+ zwischen die Operanden geschrieben werden. Beispiele:
+ OP C (TEXT CONST muster, pattern)
+ --> "alt" C "neu"
+
+PROC Prozedur.
+ Der Name der Prozedur muß klein geschrieben werden. Die
+ Parameter werden in Klammern angefügt. Beispiele:
+ PROC getchar (TEXT VAR zeichen)
+ --> getchar (character)
+ PROC edit (TEXT CONST datei,
+ INT CONST x, y, xsize, ysize)
+ --> edit ("meine datei", 1, 1, 79, 24)
+
+INT Ganze Zahl ('Integer').
+ Der Wert ist eine ganze Zahl (ohne Dezimalpunkt!).
+
+BOOL Wahrheitswert ('Boolean').
+ Hat zwei Werte: TRUE ('Wahr') und FALSE ('Falsch').
+
+TEXT Text.
+ Muß in Anführungszeichen geschrieben werden. Soll das
+ '"'-Zeichen in einem Text vorkommen, muß es doppelt
+ geschrieben werden.
+
+VAR Veränderbarer Wert.
+ Wert kann von der Prozedur oder dem Operator verändert
+ werden.
+
+CONST Unveränderbarer Wert.
+ Wert kann von der Prozedur oder dem Operator nicht ver-
+ ändert werden.
+
+
+
+Kommando-Übersicht
+
+In dieser Übersicht werden Editor-Kommandos, die in der Regel nur in Pro-
+grammen verwendet werden, mit (P) gekennzeichnet. "Nicht-Programmierer"
+brauchen also nur die nicht gekennzeichneten Kommandos zu lesen. Alle hier
+aufgeführten Kommandos arbeiten auf die vom Editor bearbeitete Datei
+('editfile'). Einige der Prozeduren stehen auch zur allgemeinen Dateiver-
+arbeitung zur Verfügung (siehe TEIL 7), allerdings dann mit einem zusätz-
+lichen FILE-Parameter.
+
+abschnitt neu (P)
+ PROC abschnitt neu (INT CONST von zeile, bis zeile)
+ Zweck: Mitteilung an den Editor, daß der entsprechende Abschnitt
+ auf dem Bildschirm neu geschrieben werden muß.
+
+at (P)
+ BOOL PROC at (TEXT CONST muster)
+ Zweck: Feststellen, ob der Editor auf 'muster' steht. Die Cursor-
+ Position wird dabei nicht verändert.
+
+bild neu (P)
+ PROC bild neu
+ Zweck: Mitteilung an den Editor, daß das Bild nach Kommandover-
+ arbeitung neu geschrieben werden muß.
+
+bild zeigen
+ PROC bild zeigen
+ Zweck: Mitteilung an den Editor, daß das Bild sofort neu geschrieben
+ werden muß.
+
+C
+ OP C (TEXT CONST muster, pattern)
+ Zweck: Wie D "muster" mit anschließender Ersetzung desselben durch
+ 'pattern'.
+
+change to (P)
+ PROC change to (TEXT CONST muster, pattern)
+ Zweck: Analog C.
+
+ PROC change to (TEXT CONST muster, pattern, INT CONST number)
+ Zweck: Analog C, aber nur 'number' Zeilen weit.
+
+CA
+ OP CA (TEXT CONST source, destination)
+ Zweck: Arbeitet ab der aktuellen Position wie
+
+ WHILE NOT eof REP
+ "source" C "destination"
+ END REP
+
+change all (P)
+ PROC change all (TEXT CONST source, destination)
+ Zweck: Analog CA.
+
+col (P)
+ PROC col (INT CONST pos)
+ Zweck: Positioniert auf die Spalte 'pos' der aktuellen Zeile.
+ Beispiel:
+
+ col (37)
+
+ positioniert auf die 37. Spalte der aktuellen Zeile.
+
+ INT PROC col
+ Zweck: Liefert die aktuelle Position des Cursors innerhalb einer Zeile.
+
+D
+ OP D (INT CONST n)
+ Zweck: Positioniert das Fenster n Zeilen vorwärts in Richtung auf das
+ Dateiende.
+
+ OP D (TEXT CONST muster)
+ Zweck: Sucht 'muster' vorwärts in Richtung auf das Dateiende. Die Suche
+ beginnt direkt hinter der aktuellen Cursor-Position. Wird 'muster'
+ nicht gefunden, steht der Cursor hinter dem letzten Zeichen der
+ Datei. Wird 'muster' gefunden, steht der Cursor direkt auf dem
+ ersten Zeichen von 'muster'.
+
+down (P)
+ PROC down (INT CONST n)
+ Zweck: Analog D.
+
+ PROC down (TEXT CONST muster)
+ Zweck: Analog D.
+
+ PROC down (TEXT CONST muster, INT CONST n)
+ Zweck: Analog D, jedoch geht die Suche nur 'n' Zeilen.
+
+downety (P)
+ PROC downety (TEXT CONST muster)
+ Zweck: Im Gegensatz zu 'down' beginnt die Suche mit dem aktuellen Zeiche
+ n, d.h. der Aufruf führt zu einer leeren Leistung, wenn der Cursor schon
+ auf 'muster' steht. Deshalb bei der Programmierung vorsichtig verwenden.
+
+ PROC downety (TEXT CONST muster, INT CONST n)
+ Zweck: Analog 'downety', jedoch geht die Suche nur 'n' Zeilen und
+ beginnt bei der aktuellen Cursor-Position (siehe oben).
+
+editfile (P)
+ FILE PROC editfile
+ Zweck: Liefert die aktuell editierte Datei.
+
+eof
+ BOOL PROC eof
+ Zweck: Abfrage auf das Dateiende der zu bearbeitenden Datei.
+
+GET
+ OP GET (TEXT CONST dateiname)
+ Zweck: Kopiert den Inhalt der Datei mit dem angegebenen Namen vor die
+ aktuelle Cursor-Position. Ist die Quelldatei kopiert, wird nur
+ der markierte Teil kopiert.
+
+ OP G (TEXT CONST dateiname)
+ Zweck: Wie GET.
+
+len (P)
+ INT PROC len
+ Zweck: Liefert die Länge der aktuellen Zeile.
+
+limit
+ OP limit (INT CONST limit)
+ Zweck: Setzt die rechte Schreibgrenze auf 'limit'. Beispiel:
+
+ limit (120)
+
+ stellt den Editor auf eine Zeilenlänge von 120 Zeichen.
+
+ INT PROC limit
+ Zweck: Liefert die eingestellte Zeilenbreite.
+
+line no (P)
+ INT PROC line no
+ Zweck: Liefert die aktuelle Zeilennummer der editierten Datei.
+
+margin
+ PROC margin (INT CONST anfang)
+ Zweck: Alle Zeilen erscheinen erst ab Spalte 'anfang' im Sichtfenster.
+ Beispiel:
+
+ margin (50)
+
+ legt das Fenster ab Spalte 50 fest.
+
+ INT PROC margin
+ Zweck: Liefert den eingestellten linken Rand.
+
+mark (P)
+ PROC mark (BOOL CONST an)
+ (Zweck: Schaltet die Markierung an der aktuellen Stelle ein bzw. aus.
+ Beispiel:
+
+ mark (true) (* schaltet Markierung an *)
+ mark (false) (* schaltet Markierung aus *)
+
+ BOOL PROC mark
+ Zweck: Liefert TRUE, sofern die Markierung eingeschaltet ist.
+
+nichts neu (P)
+ PROC nichts neu
+ Zweck: Mitteilung an den Editor, daß nach Kommandoverarbeitung das Bild
+ nicht neu geschrieben werden muß.
+
+note (P)
+ PROC note (INT CONST wert)
+ Zweck: Schreibt 'wert' in das Notizbuch.
+
+ PROC note (TEXT CONST message)
+ Zweck: Schreibt 'message' in das Notizbuch.
+
+pattern found (P)
+ BOOL PROC pattern found
+ Zweck: Gibt an, ob der letzte Suchprozeß erfolgreich war.
+
+PUT
+ OP PUT (TEXT CONST dateiname)
+ Zweck: Richtet eine Datei mit dem angegebenen Namen ein, kopiert den
+ markierten Textabschnitt in diese.
+
+ OP P (TEXT CONST dateiname)
+ Zweck: Wie PUT.
+
+satznr neu (P)
+ PROC satznr zeigen
+ Zweck: Mitteilung an den Editor, daß nach Kommandoverarbeitung die
+ Zeilennummer rechts oben neu geschrieben werden muß.
+
+satznr zeigen (P)
+ PROC satznr zeigen (INT CONST nr)
+ Zweck: Mitteilung an den Editor, die Zeilennummer 'nr' sofort neu zu
+ schreiben.
+
+T
+ OP T (INT CONST n)
+ Zweck: Positioniert auf die Zeile 'n'.
+
+toline (P)
+ PROC toline (INT CONST n)
+ Zweck: Analog T.
+
+type (P)
+ PROC type (TEXT CONST t)
+ Zweck: Trägt 't' in den Eingabestrom ('f kommando') des Editors ein.
+ Beispiel:
+
+ type (text (sqrt (2.0)))
+
+ fügt an die aktuelle Cursor-Position den Wert 1.41... ein.
+ Beispiel:
+
+ INT VAR i;
+ FOR i FROM 1 UPTO 10 REP
+ type (text (i) + " ")
+ END REP
+ (* Ausgabe: 1 2 3 4 5 6 7 8 9 10 *)
+
+U
+ OP U (INT CONST n)
+ Zweck: Positioniert das Fenster n Zeilen rückwärts in Richtung auf den
+ Dateianfang.
+
+ OP U (TEXT CONST muster)
+ Zweck: Sucht 'muster' rückwärts in Richtung auf den Dateianfang. Die
+ Suche beginnt links neben der aktuellen Cursor-Position. Vergl. D
+
+ueberschrift neu (P)
+ PROC ueberschrift neu
+ Zweck: Mitteilung an den Editor, daß nach Kommandoverarbeitung die
+ Überschriftszeile neu zu schreiben ist.
+
+ueberschrift zeigen (P)
+ PROC ueberschrift zeigen
+ Zweck: Mitteilung an den Editor, daß sofort die Überschriftszeile neu
+ zu schreiben ist.
+
+up (P)
+ PROC up (INT CONST n)
+ Zweck: Analog U.
+
+ PROC up (TEXT CONST muster)
+ Zweck: Analog U.
+
+ PROC up (TEXT CONST muster, INT CONST n)
+ Zweck: Analog U, aber nur 'n' Zeilen weit.
+
+uppety (P)
+ PROC uppety (TEXT CONST muster)
+ Zweck: Im Gegensatz zu 'up' beginnt die Suche direkt auf der aktuellen
+ Cursor-Position. Vergl. 'down'.
+
+ PROC uppety (TEXT CONST muster, INT CONST n)
+ Zweck: Analog 'uppety', aber nur 'n' Zeilen weit.
+
+word (P)
+ TEXT PROC word
+ Zweck: Liefert das Wort von der aktuellen Position bis zum nächsten
+ Blank bzw. Zeilenende. Die Cursor-Position wird nicht verändert.
+
+ TEXT PROC word (TEXT CONST muster)
+ Zweck: Liefert das Wort von der aktuellen Position bis zum nächsten Auf-
+ treten von 'muster' (ausschließlich) bzw. Zeilenende. Die Cursor-
+ Position wird nicht verändert.
+
+ TEXT PROC word (INT CONST laenge)
+ Zweck: Liefert das Wort von der aktuellen Position in der angegebenen
+ 'laenge' bzw. bis zum Zeilenende. Die Cursor-Position wird nicht
+ verändert.
+
+word wrap
+ PROC word wrap (BOOL CONST an)
+ Zweck: Schaltet den automatischen Wortumbruch an (voreingestellt) bzw.
+ aus. Beispiel:
+
+ word wrap (true) (* angeschaltet *)
+ word wrap (false) (* ausgeschaltet *)
+
+zeile neu (P)
+ PROC zeile neu
+ Zweck: Mitteilung an den Editor, daß nach Kommandoverarbeitung die
+ aktuelle Zeile neu zu schreiben ist.
+
+
+
+5. EUMEL-Zeichensatz
+
+Das EUMEL-System definiert einen Zeichensatz, der gewährleistet, daß Zeichen
+auf allen Maschinen überall gleich codiert werden. Dadurch ist es z.B. mög-
+lich, Dateien und Programme ohne Konvertierungen zwischen EUMEL-Systemen
+unterschiedlicher Hersteller zu übertragen. Der EUMEL-Zeichensatz beruht auf
+dem ASCII-Zeichensatz (DIN 66 003) mit Erweiterungen.
+
+
+
+Darstellbare Zeichen
+
+Die genaue Darstellung der einzelnen Zeichen hängt vom Endgerät ab. Die hier
+aufgeführten Zeichen sind i.A. auf allen Geräten vorhanden. Ein erweiterter
+Zeichensatz (mit mathematischen, diakritischen und griechischen Zeichen) ist
+nur auf Spezialgeräten verfügbar und wird deshalb hier nicht angegeben.
+
+Beispiele zum Lesen der Tabelle:
+
+ code (" ") -> 32
+ code ("m") -> 109
+
+ |3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
+-+-------------------------------------------------------------------
+0| ( 2 < F P Z d n x k
+ |
+1| ) 3 = G Q [ e o y - ß
+ |
+2|SP * 4 > H R \\ f p z \#
+ |
+3|! + 5 ? I S ] g q { SP
+ |
+4|" , 6 § J T ^ h r | Ä
+ |
+5|\# - 7 A K U _ i s } Ö
+ |
+6|$ . 8 B L V ` j t ~ Ü
+ |
+7|% / 9 C M W a k u ä
+ |
+8|& 0 : D N X b l v ö
+ |
+9|' 1 ; E O Y c m w ü
+
+Anmerkungen:
+1) SP bedeutet Leerzeichen ("blank").
+2) Die Zeichen 'k', '-' und 'SP' mit den Codes 220, 221, 223 werden für die
+ Zwecke der Textkosmetik benötigt (Trenn 'k' bei der Umwandlung von 'ck' in
+ 'kk'; Trennzeichen; geschütztes Leerzeichen).
+3) Das Zeichen '\#' (Code 222) ist druckbar, während das Zeichen '\#' (Code 35)
+ nicht druckbar ist (Einleitungszeichen für Anweisungen der Textkosmetik
+ und Drucker).
+4) Das Zeichen SP (Code 223) wird zur besseren Identifizierung als Unter-
+streichungsstrich auf dem Terminal dargestellt. Im einem Ausdruck erscheint
+es als ein Leerzeichen.
+
+
+
+Steuerzeichen und -tasten
+
+Das EUMEL-System definiert neben den darstellbaren Zeichen auch Steuer-
+zeichen, die entsprechend der angeschlossenen Geräte ggf. jeweils umcodiert
+werden.
+
+Das EUMEL-System definiert (Ausgabe-) Steuerzeichen mit ihren (ausgabesei-
+tigen) Wirkungen. Diese Steuerzeichen sind geräteunabhängig und werden vom
+EUMEL-System automatisch für die jeweiligen Geräte passend umcodiert. Bei
+Standard-Geräteschnittstellen ist die Wirkung anderer Steuerzeichen nicht
+definiert. Für den Anschluß von Druckern, für Datenfernübertragung u.ä.
+können sogenannte "Transparent"-Schnittstellen verwandt werden. Bei diesen
+Schnittstellen ist die Wirkung aller Steuerzeichen undefiniert (vom ange-
+schlossenen Gerät abhängig); es wird aber garantiert, daß alle Zeichen ohne
+Code-Umsetzung direkt ausgegeben werden.
+
+
+
+Ausgabesteuerzeichen
+
+Wert | Bezeichnung | Wirkung
+------+--------------+-----------------------------------------
+ 0 | NUL | keine Wirkung, Füllzeichen
+ 1 | HOME | Cursor auf linke obere Ecke des Bildschirms
+ 2 | RECHTS | Cursor eine Stelle nach rechts
+ 3 | OBEN | Cursor eine Zeile nach oben
+ 4 | CL EOP | Löschen von Cursor-Position bis Bildschirmende
+ 5 | CL EOL | Löschen von Cursor-Position bis Zeilenende
+ 6 | CPOS | Cursor positionieren, nächstes Ausgabezeichen be-
+ | | stimmt die y-Position (0 <= code (y) <= 23), darauf-
+ | | folgendes Ausgabezeichen die x-Position
+ | | (0 <= code (x) <= 78).
+ 7 | BELL | akustisches Signal
+ 8 | LINKS | Cursor eine Stelle nach links
+10 | UNTEN | Cursor eine Zeile nach unten bzw. 'roll up', falls
+ | | der Cursor schon in der letzten Zeile stand
+13 | RETURN | Cursor an den Anfang der aktuellen Zeile
+14 | ENDMARK | Ende des zu markierenden Bereichs
+15 | BEGINMARK | Anfang des zu markierenden Bereichs
+
+
+
+Eingabe-Steuertasten
+
+Für die Eingabeseite sind im EUMEL ebenfalls Steuertasten definiert. Diese
+Tasten sollten am angeschlossenen Gerät vorhanden sein oder bereitgestellt
+werden (z.B. durch Überkleben von Tasten) oder müssen mit Hilfe der
+CONTROL-Taste simuliert werden. Das EUMEL-System führt entsprechend der
+folgenden Tabelle evtl. notwendige Umcodierungen der Eingabe durch. Weitere
+vorhandene Spezialtasten erzeugen gerätespezifische Codes. Bei der "Transpa-
+rent"-Schnittstelle werden - symmetrisch zur Ausgabeseite - alle hereinkom-
+menden Zeichen ohne Code-Umsetzung weitergereicht.
+
+Wert | Bezeichnung
+------+------------
+ 1 | HOP
+ 2 | RECHTS
+ 3 | OBEN
+ 8 | LINKS
+ 9 | TAB
+10 | UNTEN
+11 | RUBIN
+12 | RUBOUT
+13 | RETURN
+16 | MARK
+27 | ESC
+
+
+
+6. Der Editor als Unterprogramm
+
+Um eine Anpassung der Benutzerschnittstelle an spezielle Bedürfnisse vor-
+nehmen zu können, werden einige noch nicht erläuterte ELAN-Prozeduren zur
+Verfügung gestellt. Mit diesen kann für jede Anwendung ein Spezialprogramm
+zur Verfügung gestellt werden, das den Editor als Unterprogramm aufruft. Für
+den "normalen" Editor-Benutzer ist dieses Kapitel somit nicht weiter von
+Interesse.
+
+
+
+Tastenverwaltung
+
+kommando auf taste legen
+ PROC kommando auf taste legen (TEXT CONST taste, elan programm)
+ Zweck: Belegt die Taste 'taste' mit dem ELAN-Programm 'elan programm'.
+ Beispiel:
+
+ kommando auf taste legen
+ ("v", "edit (""meine datei"")")
+
+ belegt die Taste 'v' mit der 'edit'-Prozedur.
+
+kommando auf taste
+ TEXT PROC kommando auf taste (TEXT CONST taste)
+ Zweck: Liefert den Quelltext des auf die Taste 'taste' gelegten ELAN-Pro-
+ gramms oder niltext, wenn diese nicht entsprechend belegt ist.
+
+lernsequenz auf taste legen
+ PROC lernsequenz auf taste legen (TEXT CONST taste, lernsequenz)
+ Zweck: Belegt die Taste 'taste' mit den Zeichen 'lernsequenz'. Beispiel:
+
+ lernsequenz auf taste legen ("a", ""217"")
+
+ belegt die Taste 'a' mit dem 'ä'.
+
+lernsequenz auf taste
+ TEXT PROC lernsequenz auf taste (TEXT CONST taste)
+ Zweck: Liefert die auf 'taste' gelegte Tastenanschlagsfolge
+ oder niltext, wenn diese nicht entsprechend belegt ist.
+
+taste enthaelt kommando
+ BOOL PROC taste enthaelt kommando (TEXT CONST taste)
+ Zweck: Liefert TRUE, wenn 'taste' mit einem ELAN-Programm belegt ist.
+
+std tastenbelegung
+ PROC std tastenbelegung
+ Zweck: Belegt die Tasten mit der Standardbelegung.
+
+
+
+Aufruf des Editors, Zeilen- und Fenstereditors
+
+edit
+ PROC edit
+ Zweck: a) Im Monitor:
+ Ruft den Editor mit den zuletzt verwandten Dateinamen auf.
+ b) Im Editor:
+ Der Dateiname wird erfragt.
+ Für jedes 'edit' gilt:
+ Wurde der 'edit' zum ersten mal aufgerufen, nimmt das Fenster
+ den gesamten Bildschirm ein. Bei erneuten 'edit'-Aufruf wird
+ ein Fenster nach rechts unten ab aktuellen Cursor-Punkt eröffnet.
+
+ PROC edit (TEXT CONST datei)
+ Zweck: Ruft den Editor mit 'datei' auf.
+
+ PROC edit (TEXT CONST datei, x, y, xsize, ysize)
+ Zweck: Wie obiger 'edit'-Aufruf, jedoch kann das Fenster, in der 'datei'
+ editierbar ist, gesetzt werden. Die Parameter definieren ein
+ Editor-Fenster mit der linken oberen Ecke auf den Bildschirmkoor-
+ dinaten 'x' und 'y' und einer Zeilenbreite 'xsize' und 'ysize'
+ Zeilen. Wird der Editor mit 'edit ("datei")' aufgerufen, wird
+ implizit 'edit ("datei", 1, 1, 79, 24)' aufgerufen.
+
+ PROC edit (FILE VAR f)
+ Zweck: Vergl. obige 'edit'-Prozedur.
+
+ PROC edit (THESAURUS CONST t)
+ Zweck: Editieren aller in dem Thesaurus 't' enthaltenen Dateien nachein-
+ ander. Beispiel:
+
+ edit (ALL myself)
+
+ PROC edit (FILE VAR f, INT CONST x, y, xsize, ysize)
+ Zweck: Vergl. obige 'edit'-Prozedur.
+
+editget
+ PROC editget (TEXT VAR editsatz)
+ Zweck: Eingabe mit Editiermöglichkeit von 'editsatz' vom Terminal an der
+ aktuellen Bildschirmposition. 'editsatz' wird ausgegeben. Die
+ Eingabe wird mit RETURN beendet. Im Gegensatz zu 'get' ist hier
+ auch eine leere Eingabe (RETURN) erlaubt.
+
+ PROC editget (TEXT VAR editsatz, INT CONST editlimit, editlaenge,
+ TEXT CONST sep, res, TEXT VAR exit char)
+ Zweck: Wie oben. Dabei bedeuten:
+
+ editsatz: TEXT, der zum Editieren ausgegeben wird.
+ editlimit: Einstellung des 'limit's der Zeile (max. Anzahl von Zeichen).
+ Bei obiger 'editget'-Prozedur wird 'editlimit' mit
+ 'maxtextlength' aufgerufen.
+ editlaenge: Breite des Zeilenfensters, bevor gerollt wird (bei leerer
+ Zeile ist dies 77).
+ sep: Zeichen, bei denen die Eingabe (zusätzlich zu RETURN)
+ beendet werden soll.
+ res: Angabe von reservierten Tasten. Wird einer dieser Tasten mit
+ ESC betätigt, wird die Eingabe beendet. In
+ exit char: steht dann ESC und das Zeichen, mit dem der Editor verlassen
+ wurde.
+
+ PROC editget (TEXT VAR editsatz, INT CONST editlimit,
+ TEXT VAR exit char)
+ Zweck: Siehe oben.
+
+ PROC editget (TEXT VAR editsatz, TEXT CONST sep, res,
+ TEXT VAR exit char)
+ Zweck: Siehe oben.
+
+show
+ PROC show (FILE VAR f)
+ Zweck: Zeigt eine Datei 'f' auf dem Bildschirm. Wie beim Editor kann mit
+ Hilfe der Positionierungstasten UNTEN bzw. OBEN oder HOP UNTEN bzw.
+ HOP OBEN oder HOP RETURN "geblättert" werden. Die Datei 'f' muß
+ deshalb mit der Verarbeitungsart 'modify' assoziiert worden sein.
+ Soll die Prozedur 'show' verlassen werden, müssen - wie beim Editor
+ - die zwei Tasten ESC und q betätigt werden. Die Datei kann nicht
+ schreibend verändert werden.
+
+ PROC show (TEXT CONST filename)
+ Zweck: Wie obige Prozedur.
+
+
+
+Zeichen verarbeiten
+
+getchar
+ PROC getchar (TEXT VAR zeichen)
+ Zweck: Holt das nächste Eingabezeichen von der Tastatur.
+
+is incharety
+ BOOL PROC is incharety (TEXT CONST zeichen)
+ Zweck: Ist das nächste Eingabezeichen der Tastatur 'zeichen', liefert
+ 'is incharety' TRUE. In diesem Fall wird 'zeichen' von der Eingabe
+ verschluckt. Ist das nächste Zeichen von der Tastatur nicht 'zei-
+ chen', liefert 'is incharety' FALSE. Die Eingabe bleibt unver-
+ ändert.
+
diff --git a/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil4 b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil4
new file mode 100644
index 0000000..ecca7e6
--- /dev/null
+++ b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil4
@@ -0,0 +1,2306 @@
+ EUMEL-Benutzerhandbuch
+
+ TEIL 4: Textkosmetik und Druck
+
+TEIL 4: Textkosmetik und Druck
+
+
+Vorwort
+
+Die Textkosmetik-Programme des EUMEL-Systems bieten eine einfach zu er-
+lernende und zu bedienende Möglichkeit, Texte für den endgültigen Druck zu
+gestalten (Programmtechnisch: #ib#formatieren#ie#). Die Textkosmetik ermög-
+licht zusätzlich, Texte in einer Art und Weise zu manipulieren, die auf
+preiswerten Terminals zur Zeit nicht darstellbar ist, wie z.B. verschieden-
+artige Schriften. "Nebenbei" erledigt die Textkosmetik aufwendige Routine-
+arbeiten, wie z.B. Seitennumerierung und die Plazierung von Fußnoten.
+
+Die Textkosmetik-Programme bearbeiten Dateien, die durch den EUMEL-Editor
+erstellt wurden. Darum sollte man sich zuerst mit dem EUMEL-Editor vertraut
+machen.
+
+Für die meisten Aufgaben ist kein Benutzereingriff erforderlich, darum sind
+die Programme so konstruiert, daß sie durch in den Text eingefügte Anweisun-
+gen gesteuert werden. Einige Arbeiten erfordern den Benutzereingriff, wie
+z.B. die Kontrolle von Silbentrennungen bei fremdsprachigen Texten und die
+Plazierungen von Seitenenden. Diese Arbeiten werden auf einfache Weise
+interaktiv vorgenommen. Die Form der Anweisung ist für die Textkosmetik und
+den EUMEL-Drucker gleich und entspricht der ELAN-Syntax. Man beachte den
+Unterschied zwischen einem Kommando und einer Text-Anweisung: während ein
+Kommando direkt ausgeführt wird, wird eine im Text eingebettete Text-Anwei-
+sung (im weiteren kurz "#ib#Anweisung#ie#" genannt) erst nach dem Aufruf von
+Textkosmetik-und Drucker-Programmen wirksam.
+
+Die Wirkungsweise der Textkosmetik-Anweisungen ist leicht zu erlernen und
+kann vor allen Dingen stufenweise erfolgen. Deshalb ein guter Rat für An-
+fänger: Lesen Sie diesen Teil des Benutzer-Handbuchs erst oberflächlich, so
+daß Sie ungefähr Bescheid wissen, welche Möglichkeiten die Textkosmetik-Pro-
+gramme bieten. Dann können Sie diejenigen Teile der Textkosmetik auswählen
+und bei Bedarf anwenden, die sie für Ihre spezielle Anwendung benötigen.
+
+Zum Schluß noch eine Warnung: Die Regeln, Konventionen und Wirkungsweisen
+des EUMEL-Systems und der Textkosmetik-Programme muß ein Nutzer beherrschen,
+will er das System gut nutzen. Der Lernaufwand erfordert etwas Zeit und Mühe,
+der aber bei der Benutzung einer jeden Maschine erforderlich ist. Soll nur
+ein kurzer Brief geschrieben werden, ist man mit einer Schreibmaschine
+besser bedient. Beherrscht man dagegen die Benutzung des EUMEL-Systems
+einigermaßen, so kann auch die Erstellung eines kurzen Briefes schneller
+erfolgen als auf einer Schreibmaschine.
+
+
+
+1. Einführung in die Benutzung der Textkosmetik
+
+In diesem Kapitel wird eine Übersicht über die verfügbaren Programme der
+Textkosmetik gegeben.
+
+
+
+Schreiben, Gestalten und Drucken von Texten
+
+Im EUMEL-System unterscheiden wir zwischen drei Stufen einer Textbehandlung:
+Erstellung, Gestaltung und Druck. Die Trennung in verschiedene Arbeitsstufen
+hat den Vorteil, daß man sich zu einem Zeitpunkt nur auf einen Arbeits-
+schritt konzentrieren muß.
+
+
+a) Texterstellung bzw. Textbearbeitung
+
+Das Schreiben von Texten wird mit Hilfe des Editors erledigt. In dieser Stufe
+der Texterstellung kann ein Benutzer sich ausschließlich auf das Schreiben
+und die inhaltliche Korrektheit seines Textes konzentrieren. Wird ein Text
+ohne Anweisungen gedruckt, dann erscheint er so, wie er mit dem Editor ge-
+schrieben wurde. Bei der Erstellung des Textes können bereits Textkosmetik-
+Anweisungen in den Text eingefügt werden.
+
+Texte sollten im 'Fließtext'-Modus erstellt werden, d.h. Worte, die über
+Zeilengrenzen gehen würden, werden ohne Silbentrennung vom Editor in die
+nächste Zeile gebracht.
+
+
+b) Textkosmetik bzw. Textgestaltung
+
+Nachdem ein Text geschrieben wurde, kann man ihn mit Textkosmetik-Programmen
+gestalten, ohne ihn inhaltlich zu verändern. Dies kann auch vor oder nach
+eventuellen Korrekturen erfolgen. Die Textkosmetik bietet zur Zeit drei
+Programme an, die je nach Bedarf eingesetzt werden können:
+
+I) 'autoform/lineform' formatiert einen Text zeilenweise und vollzieht
+ eine Silbentrennung. Weiterhin erlaubt 'autoform/lineform' die Verwen-
+ dung unterschiedlicher Schrifttypen und Schrifthöhen.
+
+II) 'pageform' gestattet die Formatierung eines Textes in Seiten (drucktech-
+ nisch: "Paginieren"). Es ist mit 'pageform' u.a. möglich, die Seiten-
+ einteilung zu bestimmen, eine Seite in Spalten zu formatiern ("Zeitungs-
+ format"), Zeilen am Anfang bzw. Ende jeder Seite einfügen zu lassen,
+ eine Seitennummerierung zu erhalten und Fußnoten zu gestalten.
+
+III) 'index' erlaubt die Erstellung von Stichwort- und Inhaltsverzeichnissen.
+
+
+c) Drucken
+
+Zu jedem Zeitpunkt der Textbehandlung kann gedruckt werden. Um Drucker mit
+unterschiedlichen Eigenschaften betreiben zu können, wurde der (Fachausdruck:
+"virtuelle") EUMEL-Drucker als Schnittstelle zwischen dem EUMEL-System und
+(echten) Druckern geschaffen. Der EUMEL-Drucker beachtet die gleichen An-
+weisungen wie die Textkosmetik-Programme und noch einige zusätzliche, die
+nur für die Druckaufbereitung notwendig sind. Spezielle Druckleistungen, wie
+z.B. verschiedenartige Schrifttypen, können nur auf besonderen Druckern er-
+zeugt werden. Verfügt ein Drucker nicht über eine bestimmte Hardware-Eigen-
+schaft, wird die vom Benutzer geforderte Leistung ignoriert. Somit ist es
+möglich, Probedrucke für Korrekturen auch auf preiswerten Druckern herzu-
+stellen.
+
+Merke: Der EUMEL-Editor übernimmt die Texterstellung; 'lineform' formatiert
+zeilenweise; 'pageform' formatiert seitenweise; 'index' erstellt Stich- und
+Inhaltsverzeichnisse; der EUMEL-Drucker ist eine Software-Anpassung an
+unterschiedliche Ausgabe-Geräte.
+
+
+
+Anweisungen für die Textkosmetik und den Drucker
+
+In diesem Abschnitt wird beschrieben, wie Anweisungen für die Textkosmetik-
+Programme in einen Text eingefügt werden.
+
+Die Ausführung von 'lineform', 'pageform', 'index' und EUMEL-Drucker wird
+mit Hilfe von Anweisungen gesteuert, die man in den Text an geeigneter
+Stelle einfügt. Anweisungen haben die Form
+
+ #kommando#
+
+Beachte, daß jede Anweisung von #-Zeichen eingeschlossen sein muß, damit
+die Anweisung vom eigentlichen Text unterschieden werden kann. Beispiele:
+
+ #page# (* aber auch z.B.: # page # *)
+ #free (3.0)#
+ #type ("elitedeutsch")#
+
+Das "#"-Zeichen darf nur für Anweisungen verwandt werden, also sonst nicht
+im Text vorkommen. (Wird das "#"-Zeichen benötigt, muß das Zeichen mit ESC #
+geschrieben werden. Vergl. auch die Tastenbelegung in der Editor-Beschrei-
+bung).
+
+Die von '#'-Zeichen eingeschlossenen Anweisungen sind so konstruiert, daß
+sie - wie alle anderen Kommandos im EUMEL-System auch - der ELAN-Syntax
+entsprechen (u.a. müssen sie klein geschrieben werden; Parameter in runden
+Klammern; mehrere Parameter werden durch Kommata getrennt; TEXT-Parameter
+in Anführungsstrichen; REAL-Parameter mit Dezimalpunkt usw.). Leerzeichen
+spielen (außer in TEXT-Parametern) keine Rolle und können zur besseren Les-
+barkeit beliebig verwandt werden.
+
+Man beachte den Unterschied zwischen einer Anweisung und einem Kommando:
+während es nur eine beschränkte Anzahl von Anweisungen gibt, die nur von den
+Textkosmetik-Programmen ausgeführt werden (also sonst nicht in Programmen
+oder Monitor benutzt werden können), kann ein Benutzer ein Kommando in der
+Regel in einem Programm, im Editor oder im Monitor verwenden. Hinzu kommt,
+daß neben dem vom EUMEL-System zur Verfügung gestellten Kommandos in der
+Regel noch installationsspezifische und/oder benutzereigene Kommandos gibt.
+
+Anweisungen dürfen im allgemeinen überall auf einer Zeile stehen (wie z.B.
+in der nächsten Zeile). #on("underline")#Ausnahmen#off("underline")# werden
+bei der Beschreibung der Anweisungen speziell erwähnt. Alle Anweisungen
+werden zum frühest möglichen Zeitpunkt ausgeführt, haben also u.U. bereits
+Auswirkungen auf die Zeile, in der sie stehen.
+
+Die Zeichen, aus denen eine Anweisung besteht, werden bei der Formatierung
+einer Zeile oder Seite nicht mitgezählt und vom EUMEL-Drucker nicht gedruckt.
+Eine Zeile, die nur aus Anweisungen besteht, wird ebenso behandelt.
+
+Merke: Anweisungen steuern die Verarbeitung der Textkosmetik-Programme. Sie
+müssen in '#'-Zeichen eingeschlossen sein und dürfen in der Regel überall
+auf einer Zeile stehen. Sie werden an der Stelle ausgeführt, an der sie
+stehen.
+
+
+
+Aufruf der Textkosmetik-Programme
+
+In diesem Abschnitt wird beschrieben, wie die Textkosmetik-Programme
+aktiviert werden.
+
+Die Textkosmetik-Programme werden durch Kommandos aktiviert (d.h. in der
+'gib kommando:'-Ebene). Die Aktivierung (Fachausdruck: "Aufruf") erfolgt -
+ebenso wie beim Editor - durch den Namen des Programms und die Angabe
+der Datei. Beispiele:
+
+ autoform ("meine datei")
+ lineform ("text1");
+ pageform ("1. Kapitel")
+ index ("Buch.p")
+
+Das Programm 'pageform' erzeugt aus der Eingabedatei eine Druckdatei, die
+entsprechend umgeformt wird (Fußnoten werden an die richtige Stelle plaziert,
+Seitenummern eingesetzt u.a.m.). Diese Druckdatei bekommt den Namen der
+angegebenen Eingabedatei mit dem Zusatz '.p'. Beispiel: 'pageform ("text")'
+erzeugt eine Datei 'text.p'. Es ist auch erlaubt, 'pageform' durch die Angabe
+eines zweiten Parameters mitzuteilen, wie die Druckdatei heißen soll:
+
+ pageform ("mein text", "erste Druckdatei")
+
+Ähnlich verhält es sich mit dem Programm 'index', welches bis zu 9 Stichwort-
+bzw. Inhaltsverzeichnisse erstellen kann. Da in den Verzeichnissen die
+Seitennummern aufgeführt werden, kann 'index' nur Druckdateien bearbeiten.
+Beispiel:
+
+ index ("handbuch.p")
+
+Das Programm 'index' erstellt die angeforderten Verzeichnisse in Dateien,
+die mit dem Zusatz '.i<nummer>' gekennzeichnet werden. Beispiele (für den
+obigen Aufruf):
+
+ 'Handbuch.i1', 'Handbuch.i2'
+
+usw..
+
+Merke: Die Textkosmetik-Programme werden durch Kommandos aufgerufen mit der
+Angabe der Dateinamen als Parameter.
+
+
+
+Vorzeitiger Abbruch und Fehlermeldungen
+
+Alle Textkosmetik-Programme können vorzeitig vom Benutzer abgebrochen werden.
+Eventuelle Fehlermeldungen werden durch den Paralleleditor angezeigt.
+
+Durch die Taste SV und das Supervisor-Kommando 'halt' können die Textkosme-
+tik-Programme jederzeit vorzeitig abgebrochen werden. Die Eingabedatei steht
+dann unverändert zur Verfügung. Ein vorzeitiger Abbruch kann notwendig sein,
+wenn ein Programm mit einer falschen Datei aufgerufen wurde oder zu viele
+Fehler gemeldet wurden.
+
+Alle Textkosmetik-Programme melden Fehler, wenn eine oder mehrere Anweisun-
+gen falsch benutzt werden. Die Fehlermeldungen werden auf dem Bildschirm
+angezeigt. Bei Beendigung eines Programms wird - falls Fehler entdeckt
+wurden - die Fehlermeldungen im oberen Fenster des Paralleleditors angezeigt,
+während im unteren Fenster die Eingabedatei zur Korrektur angeboten wird.
+
+Merke: Vorzeitiger Abbruch eines Programms durch SV und 'halt'. (Die Eingabe-
+datei steht unverändert zur Verfügung.) Fehlermeldungen werden im Parallel-
+editor angezeigt.
+
+
+
+2. Zeilenweises formatieren: 'autoform/lineform'
+
+Die Programme 'autoform' oder 'lineform' formatieren einen Text zeilenweise
+(ggf. mit Silbentrennung), unter Berücksichtigung von Schrifttyp und Zeilen-
+breite.
+
+
+
+Eine Datei formatieren: 'autoform/lineform'-Kommando
+
+Die Programme 'lineform/autoform' werden unter Angabe der Datei aufgerufen.
+Beispiel:
+
+ lineform ("meine datei")
+ autoform ("Brief vom 24.12.")
+
+
+
+Unterschied von 'autoform' und 'lineform'
+
+Zur Zeilenformatierung werden zwei Programme angeboten, die sich nur in der
+Art der Behandlung von Silbentrennungen unterscheiden:
+
+a) autoform:
+ Zeilenformatierung mit automatischer Silbentrennung. 'autoform' sollte
+ nur bei deutschen Texten eingesetzt werden, weil die Silbentrennung bei
+ fremdsprachigen Texten nach anderen Regeln erfolgen muß.
+
+b) lineform:
+ Zeilenformatierung mit Silbentrennung "per Hand", wobei (nach deutschen
+ Trennregeln) ein sinnvoller Trennvorschlag gemacht wird. Die Trennstelle
+ kann interaktiv soweit verschoben werden, wie das zu trennende Wort noch
+ auf die Zeile paßt.
+
+Merke: 'autoform' nimmt eine automatische Silbentrennung vor, während
+'lineform' die #ib#Silbentrennung "per Hand"#ie# erlaubt.
+
+
+
+Übersicht über 'autoform'/'lineform'
+
+'autoform'/'lineform' formatieren eine Datei zeilenweise. Dabei werden
+Zeilen möglichst vollständig aufgefüllt.
+
+'autoform'/'lineform' haben im wesentlichen vier Aufgaben:
+
+a) Auffüllen von Zeilen:
+ 'autoform'/'lineform' können besonders gut nach Korrekturen eingesetzt
+ werden, bei denen - nach Einfügungen oder Löschungen - nicht vollstän-
+ dige oder zu lange Zeilen in der Datei stehen bleiben können.
+
+b) Erstellen von Zeilen mit unterschiedlichen Schrifttypen:
+ Werden in einer Datei mehrere Schriftarten ('type'-Anweisung) verwandt,
+ berechnen 'autoform'/'lineform' nach der eingestellten Zeilenbreite die
+ Anzahl Zeichen, die auf eine Zeile passen.
+
+c) Erstellen von unterschiedlichen Zeilenlängen:
+ Manchmal ist es notwendig, die Breite von Zeilen zu verändern ('limit'-
+ Anweisung). Dies wird von 'autoform'/'lineform' berücksichtigt.
+
+d) Silbentrennung:
+ Automatische ('autoform') und interaktive Silbentrennung ('lineform').
+ Sofern notwendig, werden Silbentrennungen rückgängig gemacht.
+
+'autoform'/'lineform' beachten nur wenige Anweisungen:
+
+Anweisung Zweck
+
+ limit Zeilenbreite einstellen
+ off Schrifttyp-Modifikation ausstellen
+ on Schrifttyp-Modifikation einstellen
+ type Schrifttyp einstellen
+
+
+'autoform'/'lineform' akzeptieren als Eingabe eine Datei und verändern diese.
+Dafür wird eine (interne) Zwischendatei benötigt. Deshalb ist darauf zu
+achten, daß noch ausreichend Platz auf dem System ist, der jedoch nur
+zwischenzeitig für den Formatierungsschritt benötigt wird.
+
+'autoform'/'lineform' fragen nach ihrem Aufruf an, auf welche Zeilenbreiten
+und mit welchem Schrifttyp die Datei formatiert werden soll. Diese Informa-
+ionen werden von 'autoform'/'lineform' in Form von 'limit'- und 'type'-An-
+weisungen in der Datei vermerkt, so daß die Anfragen bei weiteren Datei-
+Bearbeitungen entfallen.
+
+Bei Zeilen, die länger als die angegebene Zeilenbreite sind, werden die-
+jenigen Worte, die über die Zeilenbreite hinausgehen, in die nächste Zeile
+umgebrochen. Kürzere Zeilen werden aus der nachfolgenden Zeile bis zur
+Zeilenbreite aufgefüllt. Worte werden jedoch nicht über Absatzgrenzen hinweg
+verschoben. Deshalb ist vor Anwendung von 'lineform' darauf zu achten, daß
+Absätze richtig markiert wurden. Fehlende Markierungen sollte man nachträg-
+lich einfügen (RETURN am Ende einer Zeile), andernfalls werden Zeilen über
+Absatzgrenzen zusammen gezogen. Dies gilt insbesondere für Tabellenzeilen.
+
+Einrückungen (Leerzeichen am Anfang einer Zeile) werden von 'autoform'/'line-
+form' ebenfalls bei der Formatierung von Zeilen eingehalten.
+Dabei behandelt die Prozedur 'autoform'/'lineform' Einrückungen in einem
+speziellen Fall nicht so, wie ein Benutzer es erwarten würde. Bei ein-
+zeiligen Absätzen wird - falls die Zeile länger als das eingestellte Limit
+ist und der "überschüssige" Teil in eine neue Zeile umgebrochen werden muß
+- die Einrückung der aktuellen Zeile beibehalten. Das ist meist das
+"richtige" Verhalten, während es bei Aufzählungen falsch ist, weil die
+zweite Zeile einer Aufzählung oft eingerückt wird. Beispiel:
+
+ - Diese Zeile war zu lang und wurde unter
+ das "-"-Zeichen umgebrochen.
+
+Man sollte daher - nach Verarbeitungsende - die Datei nach solchen Fällen
+durchsuchen.
+
+Merke: 'autoform'/'lineform' vervollständigen zu kurze Zeilen oder brechen
+zu lange Zeilen um. Dabei werden Absätze beachtet.
+
+
+
+Interaktive Silbentrennung mit 'lineform'
+
+'lineform' trennt Silben interaktiv. 'lineform' sollte deshalb für fremd-
+sprachige Texte angewandt werden.
+
+Paßt ein Wort nicht mehr ganz auf eine Zeile, dann wird dieses Wort inter-
+aktiv zur Trennung angeboten. Die Umgebung dieses Wortes wird zur Er-
+leichterung des Trennvorgangs mit angezeigt. Das Trennzeichen erscheint an
+einer sinnvollen Stelle im zu trennenden Wort. Beispiel:
+
+ Text vor dem Trennwort; das
+ Trenn-wort steht mit nachfolgendem Text in dieser Zeile
+
+Der Benutzer hat die Möglichkeit, das Trennzeichen mit Hilfe der Positionie-
+rungstasten innerhalb des "Trennbereichs" (das ist der markierte Bereich, der
+noch auf die Zeile passen würde), zu verschieben. An der gewünschten Trenn-
+position (der Wortteil, der noch auf die Zeile kommen soll, steht links vom
+Trennstrich) kann die RETURN-Taste betätigt werden. RETURN zeigt dem Pro-
+gramm 'lineform' an, daß an dieser Stelle die Trennung erfolgen soll. 'line-
+form' fügt an den ersten Teil des Wortes das "-"-Zeichen an und schreibt den
+abgetrennten Wortteil in die nächste Zeile.
+Hinweis: Das Trennzeichen "-" hat einen anderen Code als der "normale"
+Bindestrich (vergl. dazu die Codetabelle), da Trennungen ggf. bei erneuten
+Änderungen wieder rückgängig gemacht werden müssen.
+
+Es stehen folgende Operationen bei der interaktiven Trennung zur Verfügung:
+
+ Taste Bedeutung
+
+ RETURN Trennen.
+ LINKS Trennstelle um ein Zeichen nach links verschieben.
+ RECHTS Trennstelle um ein Zeichen nach rechts verschieben.
+ HOP LINKS Trennstelle vor das Wort setzen (das Wort wird an dieser
+ Position nicht getrennt).
+ HOP RECHTS Trennstelle in die ursprüngliche Position setzen.
+ BLANK Trennzeichen wird von "-" auf " " umgeschaltet.
+ Dies kann verwandt werden, um Worte, die nicht zusammen
+ geschrieben werden sollen, beim Trennvorgang in zwei
+ Worte aufzuspalten.
+ - Schaltet das Trennzeichen von Leerzeichen (" ") wieder auf
+ den Trennstrich ("-") um.
+
+Zwei Sonderbedingungen sind bei der interaktiven Trennung noch zu beachten:
+
+ - Bei Worten mit Bindestrich wird die Trennstelle hinter dem Bindestrich als
+ Leerzeichen angezeigt. Die Trennstelle vor dem Bindestrich wird bei
+ weiterem Positionieren nach links übersprungen. Das verhindert, daß Worte
+ mit führendem Bindestrich im Text erscheinen.
+
+ - Bei einer Trennposition zwischen den Zeichen "ck" wird das Zeichen "c" in
+ ein "k" umgewandelt. Beispiel:
+
+ Druk-ker
+Hinweis: Das umgewandelte "k" hat einen anderen Code als das "normale"
+"k" (vergl. dazu die Codetabelle). Das ist notwendig, um bei späteren
+Änderungen solche Trennungen wieder rückgängig machen zu können.
+
+Sofern für die Zeilenformatierung notwendig, macht die Prozedur 'lineform'
+bereits erfolgte Trennungen rückgängig (das Trennzeichen wird entfernt und
+die Wortteile wieder zusammengefügt), wenn sich das getrennte Wort nicht mehr
+am Zeilenende (etwa durch Korrekturen oder Veränderungen der Zeilenbreite)
+befinden sollte.
+
+Merke: 'lineform' bietet Worte zur Silbentrennung an. Die "Trennstelle" kann
+durch den Nutzer verschoben werden.
+
+
+
+Automatische Silbentrennung mit 'autoform'
+
+'autoform' arbeitet wie 'lineform', nur werden die Silbentrennungen auto-
+matisch vorgenommen.
+
+Ist eine Silbentrennung bei der Formatierung notwendig, übernimmt 'autoform'
+diese automatisch und gibt diese zur Kontrolle auf dem Bildschirm aus. Die
+automatische Silbentrennung arbeitet mit einer hohen Trenngüte; allerdings
+nur für deutsche Texte. Trotzdem kann es vorkommen, daß einige Trennungen
+(insbesondere bei Fremdworten) falsch vorgenommen werden. In diesem Fall
+muß man diese nachträglich mit dem Editor korrigieren. Dabei sollte man das
+oben erwähnte Trennzeichen verwenden (ESC -).
+
+
+Wenige oder viele Silbentrennungen: Trennpunkt einstellen
+
+Viele Silbentrennungen in einem Text erschweren das Lesen. Würde man nun
+keine Silbentrennungen vornehmen, wird der rechte Rand stark "ausgefranst"
+oder beim Blocksatz ("rechter Randausgleich") müssen viele Zwischenräume
+zwischen den Worten eingefügt werden. Durch das Kommando
+
+ hyphenation width (prozentuale angabe)
+
+kann der Trennpunkt, ab dem die Silbentrennung einsetzen soll, eingestellt
+werden. Die Angabe erfolgt in Prozenten der Zeilenbreite. Beispielsweise
+stellt 'hyphenation width (5)' den Trennpunkt auf 5% der Zeilenbreite ein
+(Voreingestellt ist 7). Bei einer Angabe von 20 werden sehr wenige Worte zur
+Silbentrennung angeboten, während bei einer Angabe von '3' ungefähr jede
+dritte Zeile eine Silbentrennung versucht wird. Die Einstellung des Trenn-
+punktes bestimmt also, ab wann ein Wort zur Silbentrennung untersucht wird.
+Andererseits bestimmt die Einstellung auch, wieviel Zwischenraum zwischen
+Worten eingefügt werden muß, um einen rechten Randausgleich zu erzielen.
+
+Merke: 'hyphenation width' bestimmt, an welchem Punkt Worte zur Silbentren-
+nung angeboten werden.
+
+
+Mit unterschiedlichen Schriften schreiben: 'type'
+
+Unterschiedliche Schrifttypen#ie# werden mit der 'type'-Anweisung ange-
+fordert.
+
+Es ist möglich, mit 'lineform' verschiedenartige Schrifttypen (kurz Typen
+genannt) verarbeiten zu lassen. Jeder Typ hat - neben dem speziellen Aus-
+sehen der Zeichen - die Eigenschaft, daß jedes Zeichen eine bestimmte Breite
+und Höhe hat.
+
+Es gibt zwei Arten von Schriften: bei äquidistanten Schriften sind alle
+Zeichen gleich breit (wie bei einer "normalen" Schreibmaschine). Proportio-
+nalschrift findet man in gedruckten Büchern. Hier haben unterschiedliche
+Zeichen auch unterschiedliche Breiten. Die Zeichen ".", "i", "!" sind z.B.
+schmaler als die Zeichen "w", "o", "m" usw.
+
+Mit der Anweisung
+
+ type ("schriftname")
+
+kann auf einen anderen Schrifttyp umgeschaltet werden (auch mehrmals inner-
+halb einer Zeile). Dieser Typ gilt solange, bis wieder ein neue 'type'-An-
+weisung gegeben wird. Beispiel:
+
+ \#type("basker12")\#Jetzt schreiben wir in einer Schrift. Und jetzt
+ schalten wir um auf\#type ("modern12")\# noch eine andere Schrift.
+
+Welche Schriftarten zur Verfügung stehen, hängt natürlich von dem verfügbaren
+Drucker ab. Sie können die Schrifttypen bei Ihrer EUMEL-Installation er-
+fragen.
+Schrifttypen können modifiziert gedruckt werden (vergl. dazu den nächsten Ab-
+schnitt). Durch die Angabe einer 'type'-Anweisung werden alle Modifikationen
+ausgeschaltet.
+
+Merke: Eine 'type'-Anweisung gibt einen gewünschten Schrifttyp an.
+
+
+
+Kursiv, fett, unterstrichen, revers drucken: 'on/off'
+
+Mit der 'on'- und 'off'-Anweisung ist es möglich, einen Schrifttyp zu modi-f
+izieren. Die Schrift wird zwar nicht gewechselt, aber verändert gedruckt.
+Zur Zeit ist unterstrichen, fett, kursiv und der Druck von weiß auf schwarz
+möglich (abhängig vom eingesetzten Drucker).
+
+Die 'on'/'off'-Anweisung wirkt wie ein Schalter, der die gewünschte Schrift-
+typ-Modifikation ein- bzw. ausschaltet. Beispiel:
+
+... Das EUMEL-System ermöglicht es,
+\#on("italic")\#kursiv\#off("italic")\#
+und
+\#on("underline")\#unterstrichen\#off("underline")\#
+und
+\#on("bold")\#fett\#off("bold")\#
+und
+\#on("revers")\#revers\#off("revers")\#
+zu schreiben.
+
+Die Anweisung 'on' schaltet die Modifikation ein, 'off' schaltet sie aus.
+Folgende Modifikationen sind z.Zt. implementiert:
+
+ bold (Fettdruck)
+ italic (Kursivdruck)
+ underline (Unterstreichung)
+ revers (Weiß auf Schwarz)
+
+Dabei ist folgendes zu beachten:
+
+a) Ein 'type'-Anweisung schaltet eine Modifikation immer aus.
+
+b) Eine Modifikation sollte nicht über einen Absatz gehen ('lineform' er-
+ zeugt eine Warnung). Somit ist es gewährleistet, daß das Ausschalten
+ einer Modifikation nicht vergessen wird.
+
+c) Nicht alle Drucker können die hier angegebenen Modifikationen auch
+ drucken. Bitte erkundigen Sie sich bei Ihrer Installation.
+
+d) Welche Modifikationen gleichzeitig eingeschaltet werden können, ist
+ ebenfalls druckerabhängig.
+
+Merke: Die Anweisungen 'on' und 'off' schalten eine Modifikation an- und aus.
+
+
+
+Gesperrt schreiben
+
+Wird ein Wort g e s p e r r t geschrieben, muß natürlich verhindert werden,
+daß dieses Wort beim Formatieren getrennt wird. Andere Worte, wie z.B. in
+Formeln, sollten ebenfalls zusammen auf eine Zeile geschrieben werden (z.B.
+'sin (x)').
+
+Dies kann man erreichen, indem man nicht das Leerzeichen zwischen die Zeichen
+schreibt, denn das Leerzeichen bedeutet für 'autoform'/'lineform' immer das
+Ende eines Wortes. Man nimmt stattdessen ESC blank. ESC blank erscheint auf
+dem Bildschirm zur besseren Identifizierung als Unterstreichungsstrich (oder
+invers:  ) Beim Drucken wird jedoch wieder ein Leerzeichen produziert.
+Beispiel:
+
+ g_e_s_p_e_r_r_t (auf dem Terminal)
+ g e s p e r r t (auf Papier)
+
+Wir nennen dieses Leerzeichen auch "geschütztes Leerzeichen".
+
+Merke: G e s p e r r t wird mit dem geschützten Leerzeichen geschrieben.
+
+
+
+Tabellen und Aufzählungen schreiben
+
+Aufzählungen und Tabellen werden automatisch richtig formatiert und gedruckt,
+wenn man sich an einige einfache Regeln hält.
+
+Verwendet man eine Proportionalschrift beim Tabellenschreiben, so sind die
+Spalten in der Regel unterschiedlich breit, selbst wenn eine gleiche Anzahl
+Zeichen in jeder Spalte geschrieben wird. Dies kann man durch das Schreiben
+von einem "Doppelblank" vermeiden. Beispiel:
+
+ nnnnn | zweite Spalte
+ mmmmm | steht nicht untereinander
+
+aber mit Doppelblank:
+
+ nnnn | zweite Spalte
+ mmmm | stehen jetzt untereinander
+
+Das Doppelblank dient 'lineform/autoform' und dem Drucker als Zeichen, daß
+die Positionen speziell berechnet ('lineform') und beim Druck berücksichtigt
+werden müssen. In seltenen Fällen (insbesondere beim Einsatz von Schriftypen,
+die in der Größe stark voneinander abweichen) kann es vorkommen, daß diese
+Tabellenautomatik nicht funktioniert und Spalten übereinander gedruckt
+werden. In solchen Fällen muß man die Anzahl der trennenden Doppelblanks
+erhöhen.
+
+Praktischer Tip:
+Beachte, daß für das Funktionieren der "Tabellenautomatik" bei proportionalen
+Schriften es erforderlich ist, das jede Tabellenzeile eine Absatzzeile ist.
+Man sollte diese Zeilen vor dem Druck daraufhin überprüfen oder durch 'line-
+form/autoform' die Datei bearbeiten lassen. Sollte durch die zeilenweise
+Formatierung einmal zwei Zeilen zusammengezogen sein (wegen fehlender Absatz-
+kennzeichnung), kann man diese leicht mit dem Editor wieder "auseinander-
+brechen" (zweimaliges HOP RUBIN).
+
+Ähnliches gilt bei Aufzählungen. Beispiel:
+
+ 1) Das ist die erste Aufzählung.
+ Dieser Satz wird bündig gedruckt.
+ 2) Hier auch.
+
+Auch in solchen Fällen wird der gedruckte Text in der Regel richtig einge-
+rückt. Die Aufzählungsautomatik wirkt nur nach einem Absatz und bei Propor-
+tionalschriften. Die Regeln sind etwas kompliziert, so daß sie hier nicht
+einzeln aufgeführt werden (siehe S. #topage("block")# unter dem Kommando
+'block'). Trifft man auf einen der seltenen Fälle, wo die Einrückungsautoma-
+tik nicht funktioniert, kann man immer das Doppelblank der Tabellenautomatik
+verwenden.
+
+Merke: Die Tabellen- und die Aufzählungsautomatik sorgen dafür, daß Tabellen-
+spalten und Aufzählungen bündig gedruckt werden.
+
+
+
+Zeilenbreite einstellen: 'limit'
+
+Mit der 'limit'-Anweisung kann die Zeilenbreite eingestellt werden.
+
+Die 'limit'-Anweisung gibt (in cm) an, wie breit die Zeile sein soll. Be-
+achte, daß die Angabe der Zeilenbreite nichts mit dem LIMIT-Kommando des
+Editors zu tun hat. Dieses gibt an, wieviel Zeichen einer äquidistanten
+Schrift beim Schreiben auf eine Bildschirmzeile passen sollen.
+
+Die Zeilenbreite wird zusammen mit dem Schrifttyp beim erstmaligen Aufruf von
+'autoform'/'lineform' interaktiv erfragt und als 'limit'-Anweisung (zusammen
+mit der 'type'-Anweisung) in die erste Zeile der Datei eingetragen. Es kann
+in einer Datei mehrmals verändert werden. Die Zeilenbreite gilt immer ab der
+Zeile, in der die 'limit'-Anweisung steht. Beispiel:
+
+ \#limit(10.0)\#Mit der 'limit'-Anwei­
+ sung kann man Paragraphen in einem
+ anderen Format leicht gestalten.
+ Die rechte Schreibgrenze wird durch
+ die 'limit'-Anweisung eingestellt,
+ während der linke Rand durch eine
+ entsprechende Einrückung gestaltet
+ wird. \#limit(13.5)\#
+
+Man beachte, daß als Parameter in der 'limit'-Anweisung eine Zahl mit Dezi-
+malpunkt angegeben werden muß.
+
+Die folgende Tabelle gibt sinnvolle 'limit'-Einstellungen für die am
+häufigsten verwandten Papiergrößen an:
+
+
+ Format 'limit' Verbleibender
+ (Zeilenbreite) Rand
+
+ DIN A4 16.0 cm je 2.65 cm
+
+ DIN A5 12.0 cm je 1.42 cm
+
+ DIN A4 quer 25.0 cm je 2.35 cm
+
+Merke: Die 'limit'-Anweisung stellt die Zeilenbreite in cm ein, während das
+'LIMIT'-Kommando des Editors die Zeilenbreite in Anzahl Zeichen angibt.
+
+
+
+3. Seitenweises formatieren: 'pageform'
+
+'pageform' formatiert eine Datei seitenweise, wobei Routinearbeiten, wie
+etwa die Plazierung von Fußnoten, Seitennummerierung usw. ebenfalls von
+'pageform' erledigt werden.
+
+
+
+Eine Datei in Seiten teilen: 'pageform'-Kommando
+
+Das Programm 'pageform' wird mit dem Kommando
+
+ pageform ("Buch")
+
+aufgerufen. 'pageform' erzeugt aus der Eingabedatei (hier: 'Buch') eine
+Druckdatei, deren Name durch ein angehängtes '.p' gebildet wird (in unserem
+Beispiel: 'Buch.p').
+
+
+Übersicht über die Arbeitsweise von 'pageform'
+
+'pageform' erzeugt aus einer Eingabedatei eine Druckdatei, wobei z.B. Fuß-
+noten und Seitennummern an den richtigen Stellen eingefügt werden.
+
+'pageform' akzeptiert als Eingabe eine Datei und produziert eine neue Datei,
+die "Druckdatei". Die Druckdatei besteht aus der Eingabedatei mit ggf. neu
+eingefügten Zeilen. Die eingesetzten Zeilen stammen aus 'head'-, 'bottom'
+oder 'footnote'-Anweisungen. Dadurch erhöht sich die Zeilenanzahl der Datei
+(bis zu 15%).
+
+Durch 'pageform' ist es möglich, am Anfang und am Ende jeder Seite Zeilen
+einfügen zu lassen. Solche Textzeilen aus Kopf- bzw. Fußbereichen sowie
+Zeilen aus Fußnoten werden in der Druckdatei in jede Seite an entsprechender
+Stelle eingefügt.
+
+Es ist möglich, in Kopf- oder Fußzeilen Seitennummern aufzunehmen. Diese Sei-
+tennummern werden von 'pageform' bei Seitenwechseln automatisch erhöht und
+an eine vom Benutzer gekennzeichnete Stelle eingesetzt. Fußnoten können auch
+durch Nummern gekennzeichnet werden. Querverweise sind ebenfalls möglich.
+
+'pageform' berechnet die Anzahl von Zeilen, die auf eine Seite passen sollen,
+aus den Angaben für die Seitenlänge, eingestellten Zeilenvorschub und even-
+tuelle Kopf-, Fuß- und Fußnotenzeilen. Bei der Berechnung wird von der je-
+weiligen Schrifthöhe des eingestellten Schriftyps ('type'-Anweisung) ausge-
+gangen. Dann zeigt 'pageform' das errechnete Seitenende auf dem Bildschirm
+an. Das Seitenende kann interaktiv verschoben werden, um es an eine ge-
+wünschte Stellen zu plazieren oder es können Leerzeilen eingefügt/gelöscht
+werden, um Seiten gleich lang zu machen. Zusätzlich ist es auch möglich,
+Seiten in Spalten ("Zeitungsdruck") aufzuteilen und diese interaktiv zu
+formatieren.
+
+ Anweisungs-Übersicht
+
+ bottom Fußzeilen *)
+ bottomeven " *)
+ bottomodd " *)
+ columns Spaltenformatieren
+ columnsend Spalten ausschalten
+ count Zähler erhöhen und einsetzen
+ end Beendet 'head', 'bottom' und *)
+ 'foot'-Bereiche
+ foot Fußnote *)
+ free Zeilen freilassen *)
+ goalpage Seitenverweis (Ziel)
+ head Kopfzeilen *)
+ headeven " *)
+ headodd " *)
+ linefeed Zeilenabstand *)
+ page Neue Seite anfangen *)
+ pagelength Seitenlänge setzen
+ pagenr Seitennummer bzw. -zeichen
+ setcount Zähler setzen
+ topage Seitenverweis (Ursprung)
+ value Wert des Zählers einsetzen
+
+*) Diese Anweisungen dürfen nur allein oder als letztes auf einer Zeile stehen.
+
+
+Merke: 'pageform' erlaubt nicht nur eine Seitenformatierung, sondern auch
+Spaltenformatierung, Fußnoten-Plazierung, Kopf- und/oder Fußzeilen, Seiten-
+numerierung und Querverweise. 'pageform' erzeugt eine neue Datei, die
+"Druckdatei" mit dem Namen der Eingabedatei, an den ".p" angefügt wird.
+
+
+
+Seitenende interaktiv verschieben#ie# mit 'pageform'
+
+In diesem Abschnitt wird beschrieben, welche interaktiven Möglichkeiten
+'pageform' bietet, um Seiten zu gestalten.
+
+Auf dem Bildschirm wird das von 'pageform' errechnete jeweilige Seitenende
+unter Angabe der aktuellen Seitennummer angezeigt. Das Seitenende erscheint
+ungefähr in der Mitte des Bildschirmes und wird durch eine von 'pageform' ge-
+kennzeichnete Zeile markiert, die auch - nach erfolgter Seitenformatierung -
+in der Druckdatei zu sehen ist. (Der EUMEL-Drucker druckt diese Zeile nicht.)
+Beispiel:
+
+\#page\#\#--------------------- Ende Seite 1 ---\#
+
+Über der Markierung erscheinen die letzten Zeilen der bereits verarbeiteten
+Seite, darunter Zeilen der nächsten Seite. Es ist nun mit Hilfe der Positio-
+nierungstasten möglich, die Markierung und damit das Seitenende nach "oben
+zu verschieben". Somit kann vermieden werden, daß logisch zusammengehörender
+Text auseinandergerissen wird und z.B. "Waisenkinder" entstehen (letzte
+Zeile eines Abschnittes kommt noch auf die neue Seite).
+
+Bei der interaktiven Seitenformatierung kann die Markierung nicht über das
+errechnete Ende einer Seite nach "unten" oder über das vorherige, bereits
+verarbeitete Seitenende nach "oben" verschoben werden. Die Markierung kann
+auch nicht in einen Fußnotenbereich plaziert werden, weil Fußnoten sinn-
+vollerweise nicht geteilt werden sollten.
+
+Entstehen Leerzeilen bei der Seitenformatierung am Anfang einer Seite (z.B.
+durch Plazierung des Seitenendes zwischen zwei Absätzen), so werden diese
+von 'pageform' automatisch aus der Druckdatei entfernt. Will man Leerzeilen
+am Anfang einer Seite#ie#, dann sollte das 'free' in Verbindung mit der
+'page'-Anweisung verwandt werden.
+
+Zusätzlich ist es möglich, Leerzeilen in eine Seite der Druckdatei einzu-
+fügen und/oder beliebige Zeilen zu löschen (vergl. b)).
+
+Folgende Operationen stehen bei der interaktiven Seitenformatierung zur
+Verfügung:
+
+a) Seitenende verschieben:
+
+'pageform' berechnet das "rechnerische" Seitenende und zeigt dieses auf dem
+Bildschirm durch die Markierung an. Die Markierung kann interaktiv verschoben
+werden:
+
+ Taste Bedeutung
+
+ RETURN Seitenende an diese Stelle plazieren.
+ OBEN Seitenende eine Zeile nach oben verschieben.
+ UNTEN Seitenende eine Zeile nach unten verschieben
+ (wenn vorher nach "oben" verschoben).
+ HOP OBEN Seitenende um einen Bildschirm nach oben verschieben.
+ HOP UNTEN Seitenende um einen Bildschirm nach unten verschieben.
+
+b) Leerzeilen einfügen und/oder Zeilen löschen
+
+Ergeben die Berechnungen von 'pageform', daß der bearbeitete Text nicht
+richtig auf der Seite plaziert ist, können in die Seite (der Druckdatei!)
+Leerzeilen eingefügt und/ oder Zeilen gelöscht werden. Dies kann beispiels-
+weise sinnvoll sein, wenn durch die Löschung einer Zeile ein Absatz noch auf
+die Seite passen würde oder durch die Einfügung von Leerzeilen ein Absatz
+auf der letzten Zeile der Seite endet. Oft ist es auch sinnvoll, daß alle
+Seiten gleich lang sind. In diesem Fall sollten vor Kapiteln und Absätzen
+Leerzeilen eingefügt oder gelöscht werden.
+
+Um Leerzeilen einzufügen und/oder Zeilen zu löschen, muß die Markierung (wie
+unter a) beschrieben) an die Stelle plaziert werden, an der die Änderung
+vorgenommen werden soll. Abschließend berechnet 'pageform' die Seite erneut.
+
+ Taste Bedeutung
+
+ HOP RUBIN Leerzeilen einfügen.
+ Anstatt der Markierung können durch (u.U. mehrmaliges)
+ RETURN Leerzeilen eingefügt werden. HOP RUBIN beendet
+ den Vorgang (wie Zeileneinfügen im Editor).
+
+ HOP RUBOUT Zeile löschen.
+ Die Zeile unmittelbar oberhalb der Markierung wird
+ gelöscht.
+
+'page'-Anweisung bestätigen/löschen
+
+Wird von der Prozedur 'pageform' eine 'page'-Anweisung angetroffen, so wird
+das so gewünschte Seitenende auf dem Bildschirm des Benutzers angezeigt. Die
+'page'-Anweisung kann entweder bestätigt oder gelöscht werden.
+
+ Taste Bedeutung
+
+ RETURN Seitenende bestätigen.
+
+ RUBOUT 'page'-Anweisung ignorieren. Die Prozedur 'pageform'
+ bearbeitet in diesem Fall die Datei weiter, als ob
+ keine 'page'-Anweisung angetroffen wurde.
+
+Merke: Ein Seitenende wird von 'pageform' auf dem Bildschirm angezeigt. Dies
+kann man mit den Positionierungstasten verschieben. Es können in die Seite
+Leerzeilen eingefügt oder Zeilen gelöscht werden. Eine 'page'-Anweisung kann
+man bestätigen oder löschen.
+
+
+
+Seitenlänge einstellen: 'pagelength'
+
+'pageform' ist auf eine Seitenlänge von 25.0 cm eingestellt (entspricht
+einem DINA4-Schreibfeld). Ist eine andere Seitenlänge erwünscht, muß die
+'pagelength'-Anweisung in den Text eingefügt werden.
+
+Beispiel:
+
+ \#pagelength (20.0)\#
+
+stellt die Seitenlänge auf 20 cm ein. Man beachte, daß der Dezimalpunkt bei
+der Seitenlänge mit angegeben werden muß.
+
+Die folgende Tabelle gibt die Seitenlänge für die am häufigsten gewählten
+Papiergrößen an:
+
+ Format Seitenlänge oberer und
+ (in cm) unterer Rand
+
+ DIN A4 25.0 je 2.35 cm
+
+ DIN A5 18.0 je 2.15 cm
+
+ DIN A4 quer 18.0 je 2.15 cm
+
+Merke: Mit der 'pagelength'-Anweisung kann die Seitenlänge (in cm) einge-
+tellt werden.
+
+
+
+Zeilenabstand einstellen: 'linefeed'
+
+Die 'linefeed'-Anweisung stellt einen Zeilenvorschub relativ zu der Schrift-
+höhe des eingestellten Schrifttyps ein.
+
+'pageform' berechnet die Anzahl Zeilen/Seite immer in Abhängigkeit vom einge-
+stellten Schrifttyp. Hat man z.B. eine Schrift gewählt, die doppelt so hoch
+wie z.B. eine Schreibmaschinenschrift ist, bekommt man auch entsprechend
+weniger Zeilen auf eine Seite. Um diesen Berechnungsvorgang braucht sich ein
+Nutzer in der Regel nicht zu kümmern.
+
+Anders verhält es sich, wenn ein anderer Zeilenvorschub als der "normale"
+Abstand zwischen Zeilen vorgenommen werden soll. In diesem Fall muß man wis-
+sen, daß die "Höhe" einer Zeile sich aus der Schrifttypgröße errechnet plus
+(ca.) 10%, welches den Abstand zwischen den Zeilen darstellt.
+
+Soll nun ein anderer Abstand eingestellt werden, wird die 'linefeed'-An-
+weisung eingesetzt. Der Parameter gibt an, um wieviel eine Zeilenhöhe erhöht
+oder verringert werden soll. Beispiel:
+
+ \#linefeed (2.0)\#
+
+Nach Antreffen dieser Anweisung wird die Zeilenhöhe durch 2 * eingestellte
+Schrifttypgröße errechnet. Es wird also der Zeilenabstand zwischen den Zeilen
+entsprechend vergrößert, da die Schriftgröße gleich bleibt. Dies entspricht
+dem zweizeiligen Schreiben bei einer Schreibmaschine (wenn man davon absieht,
+daß hier auch unterschiedliche Schrifthöhen berücksichtigt werden). Ein
+1 1/2 zeiliges Schreiben wäre mit
+
+ \#linefeed (1.5)\#
+
+einzustellen.
+
+ \#linefeed (0.5)\#
+
+stellt die Zeilenhöhe = 1/2 * eingestellte Schrifthöhe ein, so daß die Zeilen
+teilweise ineinander gedruckt werden. Bei 'linefeed (0.0)' werden Zeilen
+übereinander gedruckt (druckerabhängig).
+
+Man beachte, daß die Angabe in der 'linefeed'-Anweisung relativ erfolgt. Bei
+allen anderen Anweisungen der Textkosmetik werden Angabe in Zentimeter ver-
+langt. Die 'linefeed'-Anweisung bildet somit eine Ausnahme (von der Regel).
+
+Merke: Wieviel Zeilen auf eine Seite passen, ist von den Höhen der einge-
+stellten Schrifttypen abhängig. Diese Berechnung erfolgt automatisch durch
+'pageform'. Die 'linefeed'-Anweisung stellt einen Zeilenvorschub relativ zum
+eingestellten Schrifttyp ein.
+
+
+
+Platz freihalten: 'free'
+
+Mit der 'free'-Anweisung kann man einen zusammenhängenden Teil auf einer
+Seite freihalten.
+
+Die 'free'-Anweisung wird an solchen Stellen im Text eingesetzt, an denen -
+nach dem Druck - Zeichnungen, Tabellen und ähnliches eingeklebt werden sol-
+len. Es wird der in der 'free'-Anweisung angebene Platz freigehalten. Bei-
+spiel:
+
+\#free (2.0)\#
+hält zwei Zentimeter frei. Paßt der angeforderte Platz nicht mehr auf die
+Seite, so wird der angeforderte Platz auf der nächsten Seite reserviert
+('pageform' plaziert das Seitenende vor die 'free'-Anweisung).
+
+Merke: Die 'free'-Anweisung hält einen Platz auf dem Papier frei (Angabe in
+cm).
+
+
+
+Neue Seite beginnen: 'page'
+
+An einigen Stellen im Text, z.B. zu Beginn eines neuen Kapitels, soll unbe-
+ingt eine neue Seite angefangen werden.
+
+Dies erreicht - wie bereits erwähnt - man mit der 'page'-Anweisung. 'page-
+form' meldet im diesem Fall, nach wieviel cm auf der Seite die Anweisung an-
+getroffen wurde. Man kann nun mit RETURN das Seitenende bestätigen, oder die
+Anweisung (in der Druckdatei) löschen. Im letzteren Fall berechnet 'page-
+form' die Seite neu (als ob die 'page'-Anweisung nicht dagewesen wäre).
+
+Gleichzeitig ist es möglich, mit Hilfe der 'page'-Anweisungs eine neue Sei-
+tennummer#ie# für die neue Seite einzustellen (vergl. die nächsten Ab-
+chnitte).
+
+Merke: Die 'page'-Anweisung bewirkt eine neue Seite und muß beim Formatieren
+bestätigt werden.
+
+
+
+Kopf- und Fußzeilen: 'head/bottom'
+
+Mit den 'head'- und #ib#'bottom'-Anweisung#ie#en ist es möglich, Zeilen am
+Anfang und Ende jeder Seite einfügen zu lassen.
+
+Zeilen am Anfang ("Kopfzeilen") und Ende ("Fußzeilen") jeder Seite werden
+nur einmal geschrieben und mit Anweisungen gekennzeichnet. Diese Zeilen fügt
+'pageform' dann an den entsprechenden Stellen ein. Beispiel:
+
+\#head\#
+ Unser EUMEL-Benutzerhandbuch
+
+\#end\#
+
+Diese zwei Zeilen (also die zwischen den 'head'- und 'end'-Anweisungen ein-
+geschlossenen Zeilen) werden unverändert von 'pageform' an den Anfang jeder
+Seite in die Druckdatei plaziert. Man beachte, daß zweckmäßigerweise (minde-
+stens) eine Leerzeile nach einer solchen Kopfzeile in den 'head'-Bereich ein-
+gefügt werden sollte, um die Kopfzeile von dem eigentlichen Text der Seite zu
+trennen.
+
+Entsprechendes gilt für Fußzeilen, die zwischen 'bottom' und 'end' einge-
+chlossen werden müssen:
+
+\#bottom\#
+ Autor: I. Listig
+\#end\#
+
+Praktischer Tip: Man füge nach einer Schriftzeile mindestens eine Leerzeile
+ein (in einem 'head') bzw. vor der Schriftzeile (in einem 'bottom'), um den
+eigentlichen Text von den Kopf- bzw. Fußzeilen abzuheben.
+
+'pageform' zählt die Seiten, beginnend mit der Seitennummer '1'. (Wie man
+Seitennummern in die Kopf- und Fußzeilen bekommt, verraten wir im nächsten
+Abschnitt). Es ist nun möglich, getrennte Kopf- und Fußzeilen für gerade und
+ungerade Seiten zu gestalten (wie in diesem Benutzerhandbuch). Dies erfolgt
+mit den Anweisungen 'headeven' und 'headodd' für Seiten mit geraden und un-
+geraden Seitennummern; ('bottomeven' und 'bottomodd' dito).
+
+Diese Anweisungen müssen ebenfalls jeweils mit einer 'end'-Anweisung be-
+endet werden.
+
+Es ist möglich, Kopf- und Fußzeilen mehrmals innerhalb einer Datei zu
+wechseln, um unterschiedliche Beschriftungen zu erhalten (z.B. kapitelweise).
+Dies ist jedoch nur sinnvoll, wenn dies auf einer neuen Seite erfolgt, also
+unmittelbar nach einer 'page'-Anweisung in den Text eingefügt wird. Beispiel:
+
+ \#page\#
+ \#head\#
+ Neuer Seiten Kopf
+
+ \#end\#
+
+"Fußzeilen" sollen überall gleiches Aussehen haben, unabhängig davon, welche
+Anweisungen im restlichen Text gegeben werden. Darum werden die bei der De-
+finition einer Fußzeile aktuellen Werte für
+
+ limit
+ type
+ linefeed
+
+bei dem Einsetzen der Zeilen berücksichtigt. Es ist somit erlaubt, einen
+anderen Schrifttyp (z.B. als der restliche Text) für Fußzeilen zu verwenden,
+indem die 'type'-Anweisung innerhalb des 'bottom'-Bereiches gegeben wird.
+Beachte, daß nach 'head'-, 'bottom' und auch 'foot'-Bereiche die o.a. Kom-
+mandos nicht automatisch zurückgestellt werden. Darum sollte vor der 'end'-
+Anweisung wieder auf den im übrigen Text verwandten Schrifttyp zurückge-
+stellt werden. Gleiches gilt für die 'limit'- und 'linefeed'-Anweisung.
+Beispiel:
+
+ \#bottom\#
+ \#type ("besonders schoen")\#
+ Autor: I. Listig
+
+ (Schriftyp zurückstellen): \#type ("normal")\# \#end\#
+
+Merke: Kopf- und Fußzeilen können durch die Anweisungen 'head' bzw. 'bottom'
+oder 'headeven', 'headodd' bzw. 'bottomeven', 'bottomodd' definiert werden.
+Die Zeilen müssen jeweils durch die 'end'-Anweisung beendet werden.
+
+
+
+Seiten numerieren
+
+In den Kopf- und Fußzeilen steht das '%'-Zeichen für die aktuelle Seiten-
+nummer.
+
+Erscheint das '%'-Zeichen innerhalb eines Kopf- oder Fußbereiches, wird von
+'pageform' beim Einsetzen dieser Zeilen auf jeder Seite die aktuelle Seiten-
+nummer#ie# eingesetzt (sind mehrere '%'-Zeichen vorhanden, wird die Seiten-
+nummer mehrmals eingesetzt). Beispiel:
+
+\#head\#
+ Seite: - % -
+
+\#end\#
+
+Durch einen Fußbereich kann man die Seitennummern auch am Ende einer Seite
+haben. Man beachte, daß sich bei mehrstelligen Seitennummern durch das Ein-
+setzen die Zeilenlänge vergrößert.
+
+Manchmal ist es notwendig und sinnvoll, einen Text in mehreren Dateien zu
+halten. Bei einer Folgedatei muß die Seitennummer dann neu gesetzt werden.
+Das erfolgt mit der 'page'-Anweisung. Beispiel:
+
+\#page (4)\#
+
+vollzieht eine neue Seite. Die Seitennummer der neuen Seite ist '4'.
+
+Bei einigen Spezialanwendungen benötigt man mehr als eine Seitennummer.
+Beispielsweise soll ein Text nicht nur absolut, sondern auch jede Seite in
+jedem Kapitel separat durchgezählt werden. Eine andere Anwendung ist die
+Benennung einer Folgeseite, wie in diesem Beispiel:
+
+\#page (4711)\#
+\#head\#
+ Mein Buch Seite: %
+
+\#end\#
+\#pagenr ("$", 4712)\#
+\#bottom\#
+
+ Nächste Seite: $
+\#end\#
+
+Durch die 'pagenr'-Anweisung gibt man ein neues "Seitenzeichen" (hier: '$')
+und den Anfangwert für diese Seitennummer (hier: '4712'), der ebenfalls wie
+das '%'-Seitenzeichen von 'pageform' bei jeder neuen Seite um '1' erhöht und
+ggf. in die Kopf- und Fußzeilen eingesetzt wird. Es sind zwei zusätzliche
+Seitenzeichen (neben dem '%') möglich.
+
+Merke: In den Kopf- und Fußzeilen wird ein '%'-Zeichen von 'pageform' durch
+die aktuelle Seitennummer ersetzt. Die Seitennummer kann durch das 'page'-
+Anweisung neu gesetzt werden.
+
+
+
+Fußnoten schreiben: 'foot'
+
+Fußnoten werden direkt im Text durch die Anweisungen 'foot' und 'end' ge-
+kennzeichnet. Die Fußnoten plaziert 'pageform' an das Ende einer Seite.
+
+Fußnoten werden vom Benutzer direkt in den Text geschrieben, am besten nach
+einem Absatz. Die Fußnote wird von 'pageform' an das Ende einer Seite, ggf.
+vor Fußzeilen plaziert. Für die Kennzeichnung von Fußnoten und die ent-
+sprechende Markierung im Text ist der Benutzer selbst zuständig. Allerdings
+wird von 'pageform' bei dem Einsetzen einer Fußnote am Ende einer Seite
+Unterstreichungsstriche vor die Fußnoten eingefügt, damit Fußnoten vom
+"normalen" Text abgehoben werden.
+
+\#foot\#
+*) Das ist die erste Anmerkung auf dieser Seite.
+\#end\#
+
+Mehrere Fußnoten innerhalb einer Seite werden von 'pageform' in der Reihen-
+folge ihres Auftretens gesammelt und am Ende der Seite plaziert. Für eine
+entsprechende Trennung der Fußnoten voneinander (z.B. durch Leerzeilen) hat
+der Benutzer selbst zu sorgen.
+
+Man sollte eine Fußnote unmittelbar hinter den Absatz schreiben, in der die
+Markierung für die Fußnote erscheint, denn u.U. paßt die Fußnote nicht mehr
+auf die aktuelle Seite und muß somit von 'pageform' auf die nächste Seite
+gebracht werden. 'pageform' geht davon aus, daß die Kennzeichnung der Fuß-
+note in der Zeile unmittelbar vor der Fußnote steht und bringt diese Zeile
+ebenfalls auf die neue Seite.
+
+Merke: Fußnoten werden direkt hinter einem Absatz in den Text mittels der
+Anweisungen 'foot' und 'end' geschrieben, die 'pageform' an das Ende der
+Seite einfügt. Die Kennzeichnung der Fußnoten hat der Benutzer selbst vorzu-
+nehmen oder man kann sie mit Hilfe von 'count'- und 'value'-Anweisungen
+durchnumerieren (siehe nächsten Abschnitt).
+
+
+
+Fußnoten numerieren: Zählen lassen
+
+Bei vielen Fußnoten in einem Text ist es nicht möglich, die Fußnoten beim
+Schreiben des Textes entsprechend zu beschriften. Für diesen Fall und um auf
+die Fußnote im Text nochmals Bezug nehmen zu können, bietet 'pageform' die
+Möglichkeit an, die Fußnoten zu numerieren.
+
+Durch die 'count'-Anweisung wird 'pageform' veranlaßt, einen internen Zähler
+(beginnend bei dem Wert 0) zu erhöhen und diesen Wert anstatt der 'count'-
+Anweisungen in den Text einzusetzen. Beispiel:
+
+\#count\#
+
+setzt den Wert 1 anstatt der Anweisung ein (Anmerkung: trifft 'lineform' auf
+eine 'count'-Anweisung, so wird die Zeile berechnet, als ob drei Ziffern
+anstatt der Anweisung ständen). Jede weitere 'count'-Anweisung erhöht den
+internen Zähler und der Zählerwert wird wiederum eingesetzt:
+
+\#count\#
+
+setzt den Wert 2 ein usw. Dadurch ist es möglich, beliebige Textteile
+(Kapitel, mathematische Sätze u.a.m.) fortlaufend zu numerieren, ohne auf
+die Numerierung beim Schreiben und Ändern des Textes zu achten.
+
+Mit der 'value'-Anweisung kann man den letzten erreichten count-Wert noch-
+mals einsetzen. Das ist insbesondere für Fußnoten sinnvoll einsetzbar.
+Beispiel:
+
+ Bla Bla Bla (\#count\#)
+ \#foot\#
+ Eine Fußnote
+ \#end\#
+ ...
+
+Das Resultat würde folgendermaßen aussehen:
+
+ Bla Bla Bla (3)
+ ....
+
+ _____
+ (3) Eine Fußnote
+
+Man beachte, daß in diesem Fall die 'value'-Anweisung der 'count'-Anweisung
+folgen muß, ohne das eine weitere 'count'-Anweisung dazwischen steht. Das
+liegt - wie bereits erwähnt - daran, daß die 'value'-Anweisung immer den
+letzten 'count' Wert einsetzt.
+
+Das kann man umgehen, indem die 'count'- und 'value'-Anweisungen mit einem
+TEXT-Parameter versehen werden, der als Kennzeichnung dient. Beispiel:
+
+ \#count ("Merk1")\#
+
+arbeitet ebenso wie 'count' ohne Parameter (setzt also hier den Wert 4 ein),
+aber zusätzlich vermerkt 'pageform' den aktuellen Zählerwert neben dem Kenn-
+zeichen. Nun ist es mit der 'value'-Anweisung möglich, den vermerkten Zähler-
+wert durch Angabe des Kennzeichens an beliebigen Stellen im Text zu reprodu-
+zieren (auch wenn der interne Zähler weitergezählt wurde). Beispiel:
+
+ \#count\#\#count\#
+ \#value("Merk1")\#
+
+Die ersten zwei 'count'-Anweisungen produzieren - wie beschrieben - die
+Werte 5 bzw. 6. Die 'value'-Anweisung dagegen setzt den vermerkten Wert 4
+ein.
+
+Dies ist insbesondere sinnvoll, wenn man im Text auf eine Fußnote verweisen
+will. Beispiel:
+
+ Bla Bla. Siehe auch Anmerkung (\#value ("Waldschrat")\#). Bla
+ ...
+ ...
+ Bla Bla Bla (\#count ("Waldschrat")\#)
+ \#foot\#
+ (\#value ("Waldschrat")\#) Waldschrate kommen in vier Farben vor:
+ Rot, schwarz, grün und blau/gelb.
+ \#end\#
+
+Manchmal ist es notwendig (ebenso wie bei der Seitennummer), den internen
+Zähler neu zu setzen. Beispiel:
+
+ \#setcount (13)\#\#count ("aha!")\#
+
+produziert den Wert 13.
+
+Merke: Die 'count'-Anweisung setzt einen internen Zähler in die Druckdatei
+ein. Durch die #ib#'value'-Anweisung#ie# werden gespeicherte Werte einge-
+setzt, was man bei Fußnoten ausnutzen kann.
+
+
+
+Querverweise mit 'topage'/'goalpage'
+
+Mit den Anweisungen 'topage' und 'goalpage' sind Querverweise möglich, die
+von 'pageform' in die Druckdatei eingefügt werden.
+
+Mit Hilfe von Querverweisen soll auf andere Stellen im Text verwiesen werden,
+was nur bei längeren Texten üblich ist. Um dem Leser die mühselige Suche
+nach der Textstelle zu ersparen, gibt man in der Regel die Seitennummer an.
+Leider steht die Seitennummer vor der Fertigstellung des Textes meist noch
+nicht fest. Auch in diesem Fall kann 'pageform' helfen. Die 'topage'- An-
+weisung verweist auf eine andere Seite im Text, an der sich eine Anweisung
+'goalpage' befinden muß. Anstatt der Anweisung 'topage' wird die Seitennum-
+mer der Seite eingesetzt, auf der sich 'goalpage' befindet. Damit jedes
+'topage' auch (sein) entsprechendes 'goalpage' findet, wird bei beiden An-
+weisungen ein TEXT-Parameter angegeben. Beispiel:
+
+ Man schreibt: ... siehe auch auf Seite \#topage("verweis1")\#
+ ...
+ Auf einer anderen Seite befindet sich \#goalpage("verweis1")\#
+
+Nach 'Seite' wird die entsprechende Seitennummer eingesetzt.
+
+Es ist möglich, mehrmals auf die gleiche (Ziel-) Seite zu verweisen, man muß
+nur darauf achten, daß immer das gleiche Merkmal (TEXT-Parameter) verwandt
+wird.
+
+Merke: Mit den 'topage'- und 'goalpage'-Anweisungen sind Seitenquerverweise
+möglich. Für 'topage' wird die Seitennummer eingesetzt, auf der 'goalpage'
+steht.
+
+
+
+Formatierung von Spalten: 'columns'
+
+Mit der 'columns'-Anweisung ist es möglich, einen Text in Spalten zu forma-
+tieren ("Zeitungsdruck").
+
+Durch die Angabe der 'columns'-Anweisung wird 'pageform' aufgefordert, den
+Text in Spalten zu formatieren. Die Spaltenbreite muß der Benutzer mit der
+'limit'-Anweisung einstellen. Beispiel:
+
+ \#limit (18.0)\#
+ ...
+ \#columns (2, 2.0)\#\#limit (8.0)\#
+ ...
+
+Anfangs schreibt der Benutzer mit einer Zeilenbreite von 18 cm. Dann fordert
+er mit der 'columns'-Anweisung zweispaltigen Druck an (zwischen den Spalten
+soll 2 cm Abstand sein). Somit muß die 'limit'-Anweisung auf 8 cm einge-
+stellt werden.
+
+Die interaktive Spaltenformatierung wird von 'pageform' wie gewohnt vorgenom-
+men. Auf dem Bildschirm erscheint nun das Spaltenende, wobei die Nummer der
+Spalte angezeigt wird. Fußnoten werden spaltenweise eingeordnet und müssen
+somit die gleiche Zeilenbreite haben, wie die restlichen Spalten.
+
+'pageform' erzeugt in der Druckdatei die Spalten hintereinander. Das folgende
+Beispiel zeigt einen Ausschnitt aus der Druckdatei mit Kopf- und Fußzeilen
+bei einem zweispaltigen Druck:
+
+ head-Zeilen
+ xx
+ xx
+ xx
+ bottom-Zeilen
+ \#page\#\#------- Ende Seite 1 Spalte 1 ----\#
+ xx
+ xx
+ xx
+ \#page\#\#------- Ende Seite 1 Spalte 2 ----\#
+
+Die zweite Spalte erscheint also ohne Kopf- und Fußzeilen, die jedoch bei der
+Berechnung berücksichtigt werden. Man beachte, daß die Kopf- und Fußzeilen
+über die Spalten gehen können. Dies erreicht man durch geeignete 'limit'-
+Anweisungen in den genannten Bereichen. Hochwertige Drucker plazieren die
+zweite Spalte im Druckbild neben die erste. Bei preiswerteren Druckern muß
+man die Spalten nebeneinander kleben.
+
+Es ist zwar prinzipiell möglich, die Spalten in der Druckdatei nebeneinander
+zu schreiben. Jedoch hätte das Druckerprogramm Schwierigkeiten, diese neben-
+einander zu drucken, ohne daß z.B. ein Schrifttypwechsel in einer Spalte
+Auswirkungen auf eine Benachbarte hat. Praktischer Tip: Bei Druckern mit
+"Traktorführung" kann man erst alle ersten Spalten drucken, dann das Papier
+"von Hand" zurückdrehen und die zweiten Spalten drucken usw.
+
+Alle Anweisungen funktionieren beim spaltenweisen Formatieren wie üblich. Die
+'free'-Anweisung z.B. hält entsprechenden Platz in einer Spalte frei. Eine
+Ausnahme bildet die 'page'-Anweisung. Sie vollzieht hier ein Spaltenende. Die
+'page'-Anweisung mit einem Parameter (welcher die Seitennummer der nächsten
+Seite angibt), vollzieht dagegen ein Seitenende.
+
+Die 'columns end'-Anweisung beendet die spaltenweise Formatierung. Es ist
+zweckmäßig, unmittelbar vor der 'columns'- und hinter der 'columns end'-
+Anweisung eine 'page'-Anweisung zu schreiben.
+
+Überschriften (bzw. Textblöcke) über mehrere Spalten hinweg sind nur in der
+ersten Seite direkt hinter der 'columns'-Anweisung möglich. Beispiel:
+
+ \#page\#
+ \#limit (18.0)\#
+ HEAD
+ Breite Überschrift
+ \#columns (2, ...)\#\#limit (8.0)\#
+ XX
+ XX
+ XX
+ Bottom
+ \#page\#\#------- Ende Seite 1 Spalte 1 ----\#
+ XX
+ XX
+ XX
+ \#page\#\#------- Ende Seite 1 Spalte 2 ----\#
+
+Die Zeilen für die zweispaltige Überschrift werden berücksichtigt. Dies gilt
+jedoch nur unmittelbar hinter der 'columns'-Anweisung. Will man diesen Effekt
+nochmals haben, beendet man mit 'columns end', schreibt die 'page'-Anweisung,
+die breite Überschrift und schaltet die 'columns'-Anweisung wieder ein usw.
+
+Merke: Die Anweisungen 'columns'- und 'columns end' bewirken ein spalten-
+weises Formatieren des Textes durch 'pageform'. Die Spaltenbreite ('limit'-
+Anweisung) hat der Benutzer selbst einzustellen.
+
+
+
+4. Stichwortverzeichnisse erstellen: 'index'-Kommando
+
+Das Programm 'index' kann Stichwort- und Inhaltsverzeichnisse erstellen.
+Stichwortverzeichnisse#ie# können sortiert werden. Mehrere Stichwortver-
+zeichnisse können durch 'index merge' zusammengeführt werden.
+
+
+
+Übersicht über die Arbeitsweise von 'index'
+
+Durch den Aufruf von
+
+ index ("datei.p")
+
+werden durch Indexanweisungen gekennzeichnete Worte in Dateien, den soge-
+nannten Indexdateien, gespeichert.
+
+Anweisung Zweck
+
+ ib Anfang Index
+ (folgende Worte werden bis zur 'ie'-Anweisung in den
+ Index übernommen)
+ ie Ende eines Index
+
+Solche Verzeichnisse von Worten werden im EUMEL-System allgemein als Index
+bezeichnet. Nachdem eine oder mehrere Indexdateien aus einer Druckdatei
+erstellt sind, werden die Indexdateien auf Anfrage alphabetisch sortiert.
+Bei einem Inhaltsverzeichnis sollte man die Sortierung natürlich ablehnen.
+
+Nach der Sortierung werden gleiche Einträge automatisch zusammengefaßt und
+die entsprechenden Seitennummern nacheinander aufgeführt.
+
+Praktischer Tip: Will man nur eine Sortierung, aber keine Zusammenfassung
+von Einträgen, dann lehnt man die Sortieranfrage ab. Anschließend kann man
+die Indexdatei mit 'lex sort ("indexdatei namen")' sortieren. Hierbei
+bleiben gleiche Einträge erhalten.
+
+Das Programm
+
+ index merge ("index.i1", "index.i2")
+
+erlaubt es, zwei durch 'index' erzeugte Verzeichnisse zusammenzuführen.
+'index' kann ebenfalls benutzt werden, um ein Inhaltsverzeichnis und/oder
+ein Verzeichnis aller Abbildungen zu erstellen oder Literaturhinweise zu
+überprüfen.
+
+Die Worte, die durch 'index' in einen Index übernommen werden sollen, müssen
+in der Eingabedatei (der Druckdatei aus 'pageform') für 'index' durch An-
+weisungen gekennzeichnet werden. Die Form der Anweisungen entspricht der
+ELAN-Syntax (analog den Anweisungen für 'lineform', 'pageform' und EUMEL-
+Drucker). Solche #ib(1,"ff")#Indexanweisungen#ie# werden von den anderen
+Textbe- und -verarbeitungs Programmen ('lineform', 'pageform', EUMEL-
+Drucker) ignoriert. Man kann also bei dem Schreiben mit dem Editor gleich
+festlegen, welche Worte in einen Index aufgenommen werden sollen.
+
+
+
+Worte kennzeichnen: 'ib'/'ie'
+
+Da in einem Index - neben dem eigentlichen Worteintrag - die Seitennummer
+enthalten sein soll, arbeitet das Programm 'index' nur mit einer Druckdatei,
+d.h. einer Ausgabedatei von 'pageform'. Die Indexworte werden in Indexda-
+teien gesammelt. Die Indexdateien erhalten den Namen der zu bearbeitenden
+Datei, an den ".i" und die Nummer des Index angefügt wird. Beispiel:
+
+ ... Hier wird eine Eigenschaft des \#ib(1)\#EUMEL-Systems\#ie(1)\# beschrieben.
+
+(Die durch die Anweisungen 'ib' und 'ie' gekennzeichneten Worte werden mit
+der dazugehörigen Seitennummer in die erste Indexdatei geschrieben.)
+
+Die Einträge in einer Indexdatei werden von den Seitennummern durch min-
+destens drei Punkte getrennt.
+
+Werden diese nicht gewünscht, kann man sie leicht mit dem Editor entfernen.
+Beachte, daß man nur bei einer äquidistanten Schrift ein rechtsbündiges
+Verzeichnis erhalten kann.
+
+Es gibt die Möglichkeit, bis zu neun unterschiedliche Indexdateien zu er-
+stellen, z.B. durch
+
+ \#ib (1)\# und \#ie (1)\#
+
+gekennzeichnete Worte gehen in die Indexdatei mit der Nummer 1, durch
+
+ \#ib (9)\# und \#ie (9)\#
+
+gekennzeichnete Worte gehen in die Indexdatei mit der Nummer 9. Als Erleich-
+terung für diejenigen, die nur einen Index erstellen müssen, dürfen die 'ib'-
+und 'ie'-Anweisungen ohne Parameter benutzt werden, welches gleichbedeutend
+ist mit 'ib(1)' und 'ie(1)'.
+
+Die durch 'ib'- und 'ie'-Anweisungen gekennzeichneten Worte können auch über
+Zeilengrenzen (mit Silbentrennungen) gehen. Beispiel:
+
+ .... \#ib\#schöne Index-An-
+ weisungen\#ie\# ...
+
+'index' zieht getrennte Worte zusammen (hier: 'schöne Index-Anweisungen').
+Will man einige Worte in verschiedenen Indexdateien haben, darf man die 'ib'-
+und 'ie'-Anweisungen auch "schachteln". Dies kann man besonders bei Kapitel-
+überschriften nutzen. Beispiel (vergl. auch die Überschrift dieses Ab-
+schnitts):
+
+ \#ib(9)\#Worte kennzeichnen: '\#ib\#ib\#ie\#'/'\#ib\#ie\#ie\#'\#ie(9)\#
+
+In diesem Beispiel wird das Inhaltsverzeichnis in die Indexdatei '9' ge-
+bracht, während der "allgemeine" Index in der Indexdatei '1' gesammelt wird.
+
+
+
+Nebeneinträge erzeugen
+
+Es ist möglich, an die Seitennummer eines Eintrags einen beliebigen Text
+anfügen zu lassen. Beispiele:
+
+ EUMEL-System ... 27ff.
+ Monitor ........ 13(Def.)
+ EUMEL-Editor ... 2(Kap.4)
+
+Dies wird durch die generische Form der 'ib'-Anweisung ermöglicht:
+
+ ... der \#ib(1,"(Kap.4)")\#EUMEL-Editor\#ie\# ist gut geeignet,
+ Texte zu erstellen ...
+
+(erzeugt den letzten obigen Eintrag).
+
+An einen Eintrag kann ein weiterer TEXT angefügt werden, um etwa Unterein-
+träge zu bilden:
+
+ EUMEL-System .............. 27
+ EUMEL-System, kapitales ... 28
+ EUMEL-System, schönes ..... 29
+
+Das wird ebenfalls durch eine andere Form der 'ie'-Anweisung ermöglicht:
+
+ ... ist das \#ib\#EUMEL-System\#ie(1,", schönes")\# wirklich ein
+ schönes System ...
+
+(erzeugt den letzten obigen Eintrag).
+
+Nach der Erstellung einer Indexdatei können - nach interaktiver Anfrage - die
+Einträge sortiert werden. Die Sortierung erfolgt alphabetisch nach DIN 5007,
+Abschnitt 1 und 3.2 (Umlaute werden "richtig" eingeordnet).
+
+Wie bereits erwähnt, kann 'index' vielseitig eingesetzt werden:
+
+a) Erstellung von Stichwortverzeichnissen:
+ Wie bereits beschrieben.
+
+b) Erstellung von Inhaltsverzeichnissen:
+ Kapitelüberschriften mit eigenen Indexanweisungen klammern und durch
+ 'index' wie beschrieben verarbeiten. Beispiel:
+
+ \#ib(8)\#9.1.3 Das abenteuerliche Leben von Micky Maus unter
+ besonderer Berücksichtigung seiner Geburtsstadt Entenhausen\#ie(8)\#
+
+ Dann ist man sicher, daß das Inhaltsverzeichnis bezüglich Seitennummern
+ und Kapitelüberschriften korrekt ist.
+
+c) Erstellung von Abbildungsverzeichnissen:
+ Abbildungsüber- bzw. -unterschriften wie Inhaltsverzeichnisse verarbeiten.
+
+d) Überprüfung von Literaturhinweisen auf Vollständigkeit:
+ Man klammert alle Literaturhinweise mit extra Indexanweisungen (Beispiel:
+ \#ib(9)\#/Meier82/\#ie(9)\#) und überprüft dann mit Hilfe dieser Indexdatei
+ die Literaturverweise. Dann ist man sicher, daß alle Literaturverweise im
+ Text auch in der Literaturaufstellung stehen.
+
+
+
+Indexdateien zusammenführen: 'index merge'
+
+Durch das Programm 'index merge' kann eine Indexdatei in eine zweite "einge-
+mischt" werden. Es ist somit möglich, einen Index zu erstellen, der sich über
+mehrere Dateien erstreckt, indem man 'index' die Druckdateien dieser Dateien
+bearbeiten läßt und anschließend die entstandenen Indexdateien mit 'index
+merge ' zusammenfaßt. Indexdateien können ggf. mit dem Editor bzw. 'lineform'
+und/ oder 'pageform' bearbeitet und anschließend gedruckt werden. Beispiel:
+
+ index merge ("1.kapitel.i1", "2.kapitel.i1")
+
+Hier wird die Indexdatei des '1.kapitel' in die Indexdatei des '2.kapitel'
+eingeordnet und auf Wunsch sortiert.
+
+Beachte, daß 'index' und 'index merge' Kommandos und keine Anweisungen sind.
+
+Merke: 'index' verarbeitet eine Druckdatei (Zusatz: ".p") und erzeugt eine
+oder mehrere Indexdateien (Zusatz: ".i<nummer>"). Die in einen Index zu
+übernehmenden Worte müssen im Text durch die 'ib'- und 'ie'-Anweisungen
+eingefaßt sein.
+
+
+
+5. Drucken: 'print'
+
+Der EUMEL-Drucker, der mit dem Kommando 'print' angesprochen wird, ist eine
+Software-Schnittstelle zu einem angeschlossenem Drucker. In diesem Kapitel
+wird erklärt, wie man mit dem EUMEL-Drucker eine Datei druckt und welche
+speziellen Anweisungen den Drucker steuern.
+
+Jeder Drucker erbringt "hardwaremäßig" unterschiedliche Leistungen (z.B.
+Randausgleich, Unterstreichung). Diese Leistungen werden durch Eingabe
+spezieller Zeichenfolgen veranlaßt, die zwar genormt sind, aber von den Druk-
+kerherstellern nicht eingehalten werden oder unterschiedlich interpretiert
+werden.
+
+Um vom EUMEL-System unterschiedliche Drucker auf gleiche Weise ansprechen
+zu können, wurde eine Software-Schnittstelle geschaffen, die EUMEL-Drucker
+genannt wird. Der EUMEL-Drucker akzeptiert eine Datei und veranlaßt, daß
+diese in geeigneter Weise gedruckt wird. Weiterhin beachtet der EUMEL-
+Drucker die Anweisungen der Textkosmetik. Die Form der Anweisungen der
+Textkosmetik und des EUMEL-Druckers sind gleich.
+
+
+
+Eine Datei drucken: 'print'-Kommando
+
+Mit dem Kommando
+
+ print
+
+kann dem EUMEL-Drucker eine Datei zum Drucken übergeben werden. Beispiel:
+
+ print ("Drucker Beschreibung")
+
+In der Regel ist im EUMEL-System (Multi-User) ein "Spooler" installiert, so
+daß sofort mit der Arbeit fortgefahren werden kann. Der EUMEL-Drucker ar-
+beitet in diesem Fall parallel zu anderen Arbeiten des Nutzers.
+
+
+
+Anweisungen für den EUMEL-Drucker
+
+Ein Text (eine Datei) kann vom Drucker auch ohne Anweisungen gedruckt
+werden, etwa für Probedrucke. Für diesen Fall hat der Drucker vernünftige
+Voreinstellungen. Für einen "normalen" Text braucht ein Benutzer keine spe-
+ziellen Druckeranweisungen in den zu druckenden Text einzufügen, denn die
+Anweisungen für die Textkosmetik reichen zur Druckersteuerung aus. Nur wenn
+besondere Leistungen verlangt werden, wie z.B. Blocksatz oder den gedruckten
+Text an eine bestimmte Stelle zu plazieren, sind Druckeranweisungen notwen-
+dig.
+
+Werden vom Drucker Leistungen verlangt, die hardwaremäßig nicht vorhanden
+sind, so sorgt der EUMEL-Drucker dafür, daß eine möglichst äquivalente
+Leistung erbracht wird. Wird beispielsweise ein nicht vorhandener Schrifttyp
+angefordert, wird mit dem Standard-Schrifttyp der jeweiligen Installation
+gedruckt.
+
+Damit ist es möglich, einen Text auf einem Drucker zu drucken, der den ge-
+forderten Typ nicht kennt und der eigentlich für einen anderen Drucker
+bestimmt ist.
+
+Wie bereits erwähnt, beachtet der EUMEL-Drucker die gleichen Anweisungen wie
+die Textkosmetik-Programme. Eine 'type'-Anweisung beispielsweise, welches
+einen bestimmten Schrifttyp anfordert, wird also auch vom EUMEL-Drucker als
+Befehlsfolge an den angeschlossenen Hardware-Drucker übergeben (sofern der
+Schrifttyp auf dem Drucker realisierbar ist). Wie die Anweisungen ge-
+schrieben werden müssen, wird in der Beschreibung der Textkosmetik ge-
+schildert.
+
+Anweisungen werden nicht gedruckt. Besteht eine Zeile nur aus Anweisungen,
+so wird diese Zeile vom EUMEL-Drucker nicht gedruckt. Im Gegensatz zu den
+Programmen der Textkosmetik werden unbekannte oder fehlerhafte Anweisungen
+vom EUMEL-Drucker ohne Fehlermeldung "verschluckt". Alle Anweisungen werden
+zum frühest möglichen Zeitpunkt ausgeführt, haben also u.U. bereits Aus-
+wirkungen auf die Zeile, in der sie stehen.
+
+Einige Anweisungen sind speziell nur für den EUMEL-Drucker vorhanden.
+Diese werden in diesem Kapitel erklärt bzw. werden in der Anweisungs-Über-
+sicht mit aufgeführt.
+
+Neben den "normalen" Anweisungen, die nur in "\#"-Zeichen eingeschlossen
+werden, gibt es noch zwei andere Formen:
+
+a) Kommentar-Anweisungen:
+ Werden in "\#-" und "\#"-Zeichen eingeschlossen. Solche Anweisungen
+ werden ignoriert. Beispiel:
+
+ \#---- Ende der Seite 1 ---\#
+
+b) Spezielle Druckeranweisungen:
+ Werden in "\#/" und "\#"-Zeichen eingefaßt. Die von diesen Anweisungs-
+ Zeichen eingeschlossenen Druckerbefehlen werden unverändert (ohne die
+ "\#/" und "\#"-Zeichen) an den Drucker weitergereicht. Beispiel:
+
+ \#/C05\# (* C05 geht an den Drucker *)
+
+ Solche Anweisungen werden manchmal benötigt, um spezielle Druckereigen-
+ schaften auszunutzen, die schwer oder garnicht im EUMEL-Drucker reali-
+ sierbar sind.
+
+Anmerkung: Diese Anweisungen werden, wie die normalen Anweisungen auch, bei
+der Berechnung einer Zeile nicht berücksichtigt und nicht gedruckt.
+
+Merke: Der EUMEL-Drucker übernimmt die Anpassung an spezielle Hardware-
+Drucker. Er beachtet die gleichen Anweisungen wie die Textkosmetik-Programme.
+Zusätzlich gibt es noch einige wenige spezielle Druckeranweisungen.
+
+
+
+Blocksatz drucken: 'block'
+
+Die Anweisung 'block' bewirkt einen Blocksatz beim Druck.
+
+Fügt man in den Text (meist am Anfang einer Datei) die Anweisung
+
+ \#block\#
+
+ein, druckt der Drucker ab dieser Stelle alle Zeilen, die nicht mit einem
+Absatzkennzeichen versehen sind, im Blocksatz. Dies heißt, daß durch Ver-
+größern der Wortabstände alle Zeilen an der gleichen Position enden (rechter
+Randausgleich). Preiswerte Drucker können dies nur durch Einfügen ganzer
+Leerzeichen zwischen den Worten vornehmen, was sich oft beim Lesen störend
+bemerkbar macht. Bei qualitativ hochwertigen Druckern wird dagegen der
+Blocksatz durch Einfügen kleinerer Abstände zwischen den Worten oder sogar
+zwischen den Zeichen erreicht.
+
+Merke: Die Anweisung 'block' bewirkt den Blocksatz beim Druck.
+
+
+Schreibfeld verschieben: 'start'
+
+Durch die Anweisung 'start' ist es möglich, das Schreibfeld beim Druck auf
+dem Papier an eine andere Stelle zu plazieren.
+
+Der EUMEL-Drucker plaziert das Schreibfeld auf einem Drucker automatisch der-
+art, daß ein genügender Rand verbleibt. Diese Voreinstellung ist natürlich
+abhängig vom Drucker und der Installation. Mit der 'start'-Anweisung kann
+die automatische Einstellung verändert werden. Beispiel:
+
+ \#start (1.0, 2.0)\#
+
+legt die linke, obere Ecke des Schreibfeldes fest (vom linken Rand 1 cm, vom
+oberen Rand 2 cm).
+
+Merke: Die 'start'-Anweisung legt den linken oberen Rand des Schreibfeldes
+fest.
+
+
+
+Zentrieren
+
+Mit dem '#ib#center#ie#'-Kommando kann man eine Zeile in der Mitte der Zeile
+drucken lassen.
+
+Das 'center'-Kommando zentriert die Schrift einer Zeile. Beispiel:
+
+\#center\#Diese Zeile ist zentriert
+
+Dies Kommando ist nur bei Proportionalschriften sinnvoll einzusetzen, da man
+bei einer äquidistanten Schrift man direkt auf dem Bildschirm sehen kann,
+wie der Text auf einer Zeile plaziert ist.
+
+Merke: 'center' zentriert eine Zeile beim Drucken.
+
+
+
+6. Textkosmetik-Makros
+
+Makros dienen als Abkürzung für immer wiederkehrende Textteile und/oder
+Kommandos.
+
+Textkosmetik-Makros kommen zum Einsatz bei
+
+- immer wiederkehrenden Textteilen;
+
+- immer wiederkehrenden Anweisungssequenzen;
+
+- bei der Erstellung von Manuskripten, deren endgültige Form man anfänglich
+ noch nicht weiß oder die man noch ändern will.
+
+Die Definition von einem oder mehreren Makros wird mit dem Editor vorgenom-
+men. Diese Makro-Datei wird dann geladen. Von diesem Augenblick an "kennen"
+'lineform'/'autoform' und 'pageform' die Makros (d.h. die Textzeilen und/
+oder Anweisungen, die sich unter dem dem Makronamen "verbergen").
+
+'lineform'/'autoform' beachten die Anweisungen, die in den Makros enthalten
+sind. Man beachte, daß die Anweisungen und Textzeilen, die in den Makros ent-
+halten sind, nicht in der Datei erscheinen. Erst 'pageform' setzt diese in
+die Druckdatei ein.
+
+
+Ein Beispiel
+
+Hier wird ein einfaches Beispiel für einen Briefkopf gezeigt.
+
+Angenommen, die Firma 'Meier' schreibt mit dem EUMEL-System ihre Geschäfts-
+briefe. Sie hat einen Drucker zur Verfügung, mit dem man auch die Briefköpfe
+erstellen kann. Für den Briefkopf schreibt die Junior-Chefin ein Makro'kopf'
+in eine Datei 'macro definitionen':
+
+ \#*kopf\#
+ \#type("fett und gross")\# Firma Meier
+ \#type("fett")\# Gemischtwaren in kleinen Mengen
+ \#type("klein")\# Straße
+ Stadt
+ \#type ("normal")\#
+ \#*macro end\#
+
+Der Name des Makros ist 'kopf'. Man beachte, daß eine Makro-Definition mit
+dem Namen des Makros beginnen müssen. Der Makroname muß mit einem '*'
+gekennzeichnet werden, um ihn von "normalen" Text-Anweisungen unterscheiden
+zu können. Jedes Makro wird mit einer 'macro end'-Anweisung beendet
+(es dürfen mehrere Makros hintereinander in die Datei geschrieben werden).
+
+Nun muß die Junior-Chefin das so definierte Makro 'laden':
+
+ load macros ("macro defintionen")
+
+Zur Kontrolle kann sie sich die "geladenen" Makros in einen Datei ausgeben
+lassen:
+
+ list macros ("kontroll datei")
+
+Nun kann die Junior-Chefin ihrem Sekretär sagen, daß er von jetzt ab ein
+neues Kommando zur Verfügung hat, welches einen Briefkopf in jeden Brief
+drucken kann (mit dem Namen 'kopf'). Der Sekretär schreibt also nun
+folgenden Brief:
+
+\#kopf\#
+
+Sehr geehrte Frau ....
+usw.
+
+Nachdem er mit 'lineform' den Brief zeilenweise formatiert hat, kontrolliert
+er die formatierte Datei. Hier hat sich noch nichts verändert, die neue An-
+weisung 'kopf' steht unverändert in der Datei. ('lineform' beachtet zwar
+alle Anweisungen und Textzeilen eines Makros, setzt diese jedoch nicht in
+die Datei ein).
+
+Nun formatiert der Sekretär die Datei, welche den Brief enthält, mit 'page-
+form'. In der Druckdatei ist nun die Anweisung 'kopf' verschwunden, dafür
+stehen aber nun die Zeilen des Makrorumpfes ('pageform' setzt die Zeilen des
+Makros in die Druckdatei ein):
+
+ \#type("fett und gross")\# Firma Meier
+ \#type("fett")\# Gemischtwaren in kleinen Mengen
+ \#type("klein")\# Straße
+ Stadt
+ \#type ("normal")\#
+
+
+ Sehr geehrte Frau ...
+ usw.
+
+Merke: Makros sind bei der Verwendung von wenigen Text- und/oder Anweisungs-
+folgen nützlich, die immer in der gleichen Form benötigt werden.
+
+
+Ein Beispiel mit Makro-Parametern
+
+Unsere Junior-Chefin fällt nun auf, daß sie ihr Makro noch etwas verbessern
+kann. Sie will noch das Datum mit in den Briefkopf aufnehmen. Somit editiert
+sie ihre Makro-Datei folgendermaßen (man beachte die '$'-Zeichen):
+
+ \#*kopf ($1)\#
+ \#type("fett und gross")\# Firma Meier
+ \#type("fett")\# Gemischtwaren in kleinen Mengen
+ \#type("klein")\# Straße
+ Stadtname
+ \#type ("normal")\#
+
+ Stadtname, den $1
+ \#*macro end\#
+
+Damit hat sie dem 'kopf'-Makro einem Parameter gegeben ('$1'; die Parameter
+werden numeriert. Ein zweiter Parameter würde '$2' heißen usw.).
+
+Der Sekretär muß nun die Anweisung 'kopf' mit dem jeweiligen Datum in einen
+Brief schreiben:
+
+ \#kopf ("9.1.1984")\#
+
+'pageform' setzt nun das angegebene Datum direkt hinter 'Stadtname, den' in
+den Briefkopf ein (in der Druckdatei). Beachte, daß nur TEXT-Denoter als
+aktuelle Parameter eines Makros erlaubt sind.
+
+Merke: Durch die Makro-Parameter ist es also möglich, immer wiederkehrende
+Textteile in Schriftstücke einsetzen zu lassen, die sich nur in Kleinigkei-
+ten unterscheiden.
+
+
+Ein Beispiel für Manuskripte
+
+Hier wird gezeigt, wie man mit Makros Anweisungen formulieren kann, die aus-
+sagen, um was es sich bei einem Text handelt und nicht, wie es behandelt
+werden soll.
+
+Bei Manuskripten für Artikel, Bücher und Manuals weiß ein Autor oft vorher
+nicht, in welchem Format das Manuskript gedruckt werden wird. Zu diesem
+Zweck ist es ebenfalls nützlich, die Makros zu verwenden. Beispiel:
+
+ \#*kapitel anfang ($1)\#
+ \#free (2.0)\#
+ \#type ("gross und fett")\#\#ib (9)\#$1\#ie (9)\#\#type ("normal")\#
+
+ \#*macro end\#
+
+In diesem Beispiel wird ein Makro für den Anfang eines Kapitels definiert.
+Zwischen zwei Kapiteln soll hier zwei cm Zwischenraum bleiben, die Kapitel-
+Überschrift (als Parameter) wird in einer grösseren Schrift gedruckt. Zu-
+sätzlich wird die Überschrift in den 9. Index aufgenommen für ein Inhalts-
+verzeichnis. Nach der Überschrift wird eine Leerzeile eingeschoben, bevor
+der "richtige" Text anfängt.
+
+Ein(e) Anwender(in) dieses Makros schreibt also z.B. folgende Anweisung:
+
+ \#kapitel anfang ("Ein Beispiel fuer Manuskripte")\#
+
+(Beachte, daß die Kapitel-Überschrift nicht länger als eine Textzeile sein
+darf. Das liegt daran, das 'lineform'/'autoform' zwar die Zeile bearbeitet,
+aber nicht in den Text einsetzt. 'pageform' setzt also die unveränderte
+- nicht aufgebrochene Textzeile - ein).
+
+Man kann nun Makros für die meisten Textstrukturen definieren. Schreibkräfte
+brauchen dann in der Regel die meisten der Text-Anweisungen nicht zu kennen,
+sondern nur noch eine Anzahl von einfachen Makro-Anweisungen.
+
+Die Makro-Definitionen können jederzeit geändert werden, um wechselnden
+Bedürfnissen angepaßt zu werden (z.B. wenn ein Verlag ein bestimmtes
+Schreibformat verbindlich vorschreibt). In diesem Fall brauchen nicht alle
+Text-Dateien geändert zu werden, sondern nur die Makro-Definitionen.
+
+Ein weiterer Vorteil einer solchen Vorgehensweise ist, daß die Makro-Anwei-
+sungen in diesem Fall angeben, was eine bestimmte Text-Struktur ist, und
+nicht, wie die Struktur behandelt werden soll.
+
+Anmerkung:
+In eine Makro-Definition sollte man ggf. 'limit'-, 'type'- und 'linefeed'-
+Angaben einsetzen, um die Makros unabhängig von der Aufrufstelle zu machen.
+Ggf. sollte man die Datei vorher mit 'lineform' bearbeiten, um Trennungen
+vorzunehmen.
+
+Merke: Makros dienen zur flexiblen Behandlung von Text-Strukturen, indem
+Makros definiert werden, die angeben, um was es sich dabei handelt.
+
+
+
+Beschreibung der Makro-Kommandos
+
+Mit dem Kommando
+
+ load macros ("macro datei")
+
+kann eine Datei, in denen die Makro-Definitionen enthalten sind, in den
+Makro-Speicher des Textsystems geladen werden. Ist dies fehlerfrei erfolgt,
+kann man 'lineform'/'autoform' Dateien übergeben, die die definierten Makro-
+Anweisungen "kennen" und befolgen. 'pageform' setzt bei Antreffen einer
+Makro-Anweisung den Makrorumpf in die Ausgabe-Datei ein.
+
+Die Definition eines Makros erfolgt mit dem Makronamen, der von Anweisungs-
+zeichen eingeschlossen ist. Um Makro-Anweisungen von "normalen" Textkosmetik-
+Anweisungen zu unterscheiden, müssen diese nach dem ersten Anweisungszeichen
+mit einem '*' gekennzeichnet werden. Beispiel:
+
+ \#*macro eins\#
+ Makrorumpf mit "normalen" Kommandos, wie z.B.
+ \#type ("x")\#
+ \#*macro end\#
+
+Der Aufruf eines Makros, welcher z.B. in einer von 'lineform' zu bearbeiten-
+den Datei steht, unterscheidet sich nicht von einer "normalen" Textanweisung.
+Beispiel:
+
+ ... \#macro eins\# ...
+
+Hat das Makro Parameter (bei der Definition mit '$'-Zeichen durchnumeriert),
+müssen beim Aufruf TEXT-Parameter eingesetzt werden (also in Anführungs-
+strichen). Beispiel:
+
+ \#*macro zwei ($1)\#
+ ... $1 ...
+ \#*macro end\#
+
+ (* Aufruf: *)
+
+ \#macro zwei ("ein einzusetzender Text")\#
+
+Anmerkung:
+Bei Makros gibt es keine generischen Anweisungen. Makros, die gleiche Namen
+haben, aber sich durch die Anzahl der Parameter unterscheiden, sind also
+nicht erlaubt.
+
+Beachten Sie ferner, daß Makro-Texte so verwendet werden, wie diese mit
+'load macros' geladen werden. Beispiel:
+
+ \#*a\#
+ \#on("underline")\#
+ \#*macro end\#
+
+ \#*b\#
+ \#off("underline")\#
+ \#*macro end\#
+
+Betätigt man in der Makro-Datei nach jeder Zeile die RETURN-Taste (Absatz),
+dann erhält man bei folgender Verwendung Fehlermeldungen von 'lineform':
+
+ ... \#a\#zu unterstreichender Text\#b\# ...
+
+weil hier Mitten im Satz Absätze erscheinen und 'lineform' bei jedem Absatz
+prüft, ob noch Modifikationen "offen" sind. In solchen Anwendungen sollte
+man also Makros ohne Absätze speichern.
+
+
+
+7. Anweisungs-Übersicht
+
+* block
+ Zweck: Blocksatz (rechter Randausgleich). Der Text einer Zeile wird durch
+ Vergrößern der Wortlücken auf die Zeilenlänge, die durch das
+ 'limit'-Kommando eingestellt ist, verlängert. Es gelten folgende
+ Bedingungen:
+ a) Leerzeichen werden nicht verbreitert bei
+ - Zeilen mit Absatzzeichen;
+ - Mehrfache Leerzeichen;
+ - führende Leerzeichen (Einrückung);
+ - ein Leerzeichen hinter dem ersten Wort einer Zeile, wenn es auf
+ die Zeichen "]", ")", ".", "-", ":" endet.
+ b) Einrückungen werden äquidistant berechnet (Anzahl Zeichen *
+ Breite eines "Standard-Blanks"). Dies gilt nur für Proportional-
+ schriften und vor einer Absatzzeile. Es gilt als Einrückung:
+ - "Spiegelstrich" (Bindestrich und Leerzeichen am Anfang der
+ Zeile);
+ - Doppelpunkt als Ende des ersten Wortes (Position < 20);
+ - Schliessende Klammer oder Punkt als Ende des ersten Wortes,
+ wenn eine Ziffer davor steht (Position < 7);
+ c) Tabellen werden auch äquidistant berechnet. Dies gilt ebenfalls
+ nur für Proportionalschriften und vor einer Absatzzeile. Es gilt
+ als Teil einer Tabelle:
+ - Position des letzten Mehrfachblank.
+
+* bottom
+ Zweck: Erzeugen von "Fußzeilen" am Ende jeder Seite in der Druckdatei für
+ Untertitel und Seitennummern. Die Textzeilen zwischen den Anwei-
+ sungen 'bottom' und 'end' werden von 'pageform' am Ende jeder Seite
+ eingesetzt.
+
+* bottom even
+ Zweck: Definition von Fußzeilen für Seiten mit geraden Seitennummern. Es
+ gilt das unter 'bottom' gesagte.
+
+* bottom odd
+ Zweck: Definition von Fußzeilen für Seiten mit ungeraden Seitennummern. Es
+ gilt das bei 'bottom' gesagte.
+
+* center
+ Zweck: Zentrieren einer Zeile (Absatzzeile).
+
+* columns (INT CONST anzahl, REAL CONST luecke)
+ Zweck: Einschalten der Spaltenformatierung.
+
+* columnsend
+ Zweck: Ausschalten der Spaltenformatierung.
+
+* count
+ Zweck: Erhöhung eines internen Zählers und Einsetzen des Wertes anstatt
+ der Anweisung in die Druckdatei.
+
+* count (TEXT CONST merkmal)
+ Zweck: Wie obiges 'count', jedoch wird der Wert des Zählers vermerkt, so
+ daß er mit 'value' wieder erfragt werden kann.
+
+* end
+ Zweck: Beendet die Defintion von 'head', 'bottom' oder Fußnotenbereichen.
+
+* foot
+ Zweck: Definieren von Fußnoten. Es werden die aktuellen Werte von 'limit',
+ 'linefeed' und 'type' für die Fußnote verwendet (vergl. 'bottom'-
+ Anweisung).
+
+* free (REAL CONST freier platz)
+ Zweck: Es werden 'freier platz' cm freigehalten.
+
+* goalpage (TEXT CONST merkmal)
+ Zweck: (Ziel-) Verweis für Seitenquerverweise in Verbindung mit der Anwei-
+ sung 'topage'. 'merkmal' muß mit dem Parameter des entsprechenden
+ 'topage' übereinstimmen.
+
+* head
+ Zweck: Definieren von Kopfzeilen, die von 'pageform' am Anfang jeder Seite
+ eingefügt werden. Es gilt das unter 'bottom' gesagte.
+
+* head even
+ Zweck: Definieren von Kopfzeilen für Seiten mit geraden Seitennummern. Es
+ gilt das unter 'bottom' gesagte.
+
+* head odd
+ Zweck: Definieren von Kopfzeilen für Seiten mit ungeraden Seitennummern.
+ Es gilt das unter 'bottom' gesagte.
+
+* ib
+ Zweck: Arbeitet wie 'ib (1)', man darf aber den Parameter weglassen.
+
+* ib (INT CONST index nummer)
+ Zweck: Indexanfang einer oder mehrerer Indexworte bis zur entsprechenden
+ 'ie'-Anweisung. Die Worte zwischen 'ib' und 'ie' werden in die
+ Indexdatei geschrieben. 'index nummer' gibt die Indexdatei an.
+
+* ib (INT CONST index nummer, TEXT CONST seitennummer zusatz)
+ Zweck: Indexanfang mit Zusatztext für die Seitennummer. Das oben gesagte
+ gilt entsprechend. 'seitennummer zusatz' wird unmittelbar hinter
+ die Seitennummer angefügt. 'seitennummer zusatz' muß in jeder 'ib'-
+ Anweisung neu gesetzt werden.
+
+* ie
+ Zweck: Arbeitet wie 'ie (1)', man darf aber den Parameter weglassen.
+
+* ie (INT CONST index nummer)
+ Zweck: Abschluß eines Index. Ein Index darf nicht über Absatz- und Seiten-
+ grenzen gehen. Ein Index über mehr als zwei Zeilen ist ebenfalls
+ aus Sicherheitsgründen (vergessene Abschlußanweisung) nicht erlaubt.
+
+* ie (INT CONST index nummer, TEXT CONST index zusatz)
+ Zweck: Es wird 'index zusatz' an die durch die Index-Anweisungen einge-
+ faßten Worte angefügt. Beispiel:
+
+ \#ib (1)\#EUMEL-System\#ie(1, ", kapitales")\# ist
+ schön.
+
+ Erscheint als 'EUMEL-System, kapitales ... 4' in der Indexdatei.
+ Diese Anweisung dient also dazu, auch Sub-Indizes zu ermöglichen.
+
+* limit (REAL CONST wert)
+ Zweck: Einstellen einer neuen Zeilenbreite in cm. Die Zeilenbreite gilt
+ solange, bis sie durch ein erneute 'limit'-Anweisung verändert wird.
+
+* linefeed (REAL CONST wert)
+ Zweck: Einstellen eines neuen Zeilenvorschubs in Abhängigkeit vom einge-
+ stellten Schrifttyp.
+
+* material (TEXT CONST mat)
+ Zweck: Angabe von installationsspezifischen Merkmalen für den Drucker.
+
+* off (TEXT CONST modification)
+ Zweck: Abschalten einer Modifikation.
+
+* on (TEXT CONST modification)
+ Zweck: Einschalten einer Modifikation. Folgende Modifikationen sind zur
+ Zeit möglich:
+ bold (Fettdruck)
+ italic (Kursivdruck)
+ underline (Unterstreichung)
+ revers (Weiß auf Schwarz)
+
+* page
+ Zweck: Anfang einer neuen Seite. 'page' muß als letztes auf einer Zeile
+ stehen.
+
+* page (INT CONST nr)
+ Zweck: Anfang einer neuen Seite mit 'nr' Seitennummer.
+
+* page length (REAL CONST cm)
+ Zweck: Einstellen der Seitenlänge in cm.
+
+* page nr (TEXT CONST seitennr zeichen, start)
+ Zweck: Einstellen eines neuen Seitennr-Zeichens und Anfangwerts bzw.
+ setzen der Seitennummer des bereits vorhandenen Seitenzeichens
+ ("%"). Neben dem vorhandenen "%"-Zeichen können zwei zusätzliche
+ (beliebige, aber von den "\#"-Zeichen unterschiedliche) Seiten-
+ zeichen definiert werden.
+
+* papersize (REAL CONST width, length)
+ Zweck: Angabe der Papiergröße des Druckers in cm.
+
+* print (INT CONST von, bis)
+ Zweck: Teilausdruck einer Datei. Der Drucker verarbeitet die Datei, bis er
+ an die Seite 'von' angelangt ist. Dann druckt er die Seiten bis
+ einschließlich 'bis'. Beachte, daß der EUMEL-Drucker die Seiten
+ immer ab 1 durchzählt (und eine eventuelle Seitennumerierung nicht
+ beachtet).
+
+* start (REAL CONST x, y)
+ Zweck: Legt den linken, oberen Eckpunkt des Schreibfeldes fest. Die
+ Angaben erfolgen in cm.
+
+* topage (TEXT CONST merkmal)
+ Zweck: Verweis auf eine Seite mit der Anweisung 'goalpage' und dem
+ gleichen 'merkmal'. Für 'topage' wird die Seitennummer von
+ 'goalpage' eingesetzt.
+
+* type (TEXT CONST schrifttyp name)
+ Zweck: Einstellen eines anderen Schrifttyps. Die verfügbaren Schriftarten
+ und deren Namen sind installationsspezifisch und deshalb hier nicht
+ beschrieben.
+
+* value
+ Zweck: Einsetzen des letzten 'count' Wertes.
+
+* value (TEXT CONST merkmal)
+ Zweck: Erfragen des mit 'count' gespeicherten Zählerwertes für 'merkmal'
+ und Einsetzen dieses Wertes durch 'pageform' in die Druckdatei.
+
+
+
+7. Kommando-Übersicht
+
+autoform
+ PROC autoform
+ Zweck: Aufruf von 'autoform' unter Verwendung des letzten eingestellten
+ Dateinamens.
+
+ PROC autoform (TEXT CONST datei)
+ Zweck: 'lineform' mit automatischer Silbentrennung. Nur die vorgenomme-
+ nen Trennungen werden auf dem Bildschirm angezeigt.
+
+ PROC autoform (FILE VAR f, TEXT CONST type name, REAL CONST width)
+ Zweck: Wie oben, jedoch auf einer Datei.
+
+index
+ PROC index (TEXT CONST eingabe datei)
+ Zweck: Erstellen von Indexdateien aus einer Druckdatei wie beschrieben.
+ Eine Indexdatei erhält den Namen der zu bearbeitenden Datei mit
+ dem Zusatz ".i" und der entsprechenden Indexnummer. Hat das
+ Programm 'index' die Druckdatei bearbeitet, werden die in die
+ Indexdatei geschriebenen Einträge alphabetisch sortiert (nach
+ Anfrage). Gleiche Einträge werden zusammengezogen: ein gleich-
+ lautender Eintrag wird entfernt, seine Seitennummer wird jedoch
+ an den bereits vorhandenen mit einem Komma aggefügt.
+
+ Die Sortierung entspricht DIN 5007:
+ - Die Sortierreihenfolge enspricht 'ABC...Z', wobei große und
+ kleine Buchstaben gleich behandelt werden.
+ - Weitere Entsprechungen:
+ ö = oe, ä = ae, ü = ue
+ Ö = Oe, Ü = Ue, Ä = Ae, Ä = ä, Ü = ü, Ö = ö, ß = ss
+ Dadurch wird z.B. 'muß' vor 'Muster' einsortiert und 'Goethe'
+ ist gleich 'Göthe'.
+ - Alle Sonderzeichen (außer " " und "-") werden ignoriert.
+ - Ein Leerzeichen und ein Bindestrich zwischen Worten werden
+ gleich behandelt. Beispiel:
+
+ 'EUMEL System' und 'EUMEL-System' sind also gleich.
+
+ Es sind z.Z. max. neun unterschiedliche Indexdateien vorgesehen.
+ Der Name einer Indexdatei ergibt sich aus dem Namen der zu bear-
+ beitenden Druckdatei, wobei '.p' durch '.i' mit der entsprechen-
+ den Ziffer ersetzt wird. Beispiel (für Indizes mit
+ 'index nummer' = 1, z.B. \#ib\# ... \#ie\#):
+
+ skript.p --> skript.i1
+
+index merge
+ PROC index merge (TEXT CONST von, hinzu)
+ Zweck: Einmischen der Indizes der Indexdatei 'von' in die Indexdatei
+ 'hinzu'. Beide Indexdateien müssen vorhanden sein. Dabei wird
+ 'von' vor dem ersten Satz von 'hinzu' eingefügt und anschließend
+ ggf. sortiert.
+
+list macros
+ PROC list macros (TEXT CONST datei)
+ Zweck: Ausgabe der "geladenen" Makros in die Datei 'datei'. 'datei' darf
+ vorher nicht existieren, wird also von 'list macros' eingerichtet.
+ Die "geladenen" Makros bleiben unberührt. Man kann die mit 'list
+ macros' in die Datei 'datei' geschriebenen Makro-Definitionen ggf.
+ verändern und erneut mit 'load macros' laden.
+ Fehlerfall:
+ * file already exists
+ Ausgabe-Datei 'datei' ist bereits vorhanden.
+
+lineform
+ PROC lineform
+ Zweck: Der zuletzt verwandte Dateiname wird benutzt. Beispiel:
+
+ edit ("test")
+ ...
+ lineform (* wird zu 'lineform ("test") *)
+
+ PROC lineform (TEXT CONST dateiname)
+ Zweck: Formatieren einer Datei zeilenweise.
+
+ PROC lineform (FILE VAR f, TEXT CONST type name, REAL CONST width)
+ Zweck: Aufruf von 'lineform' von einem Programm.
+
+load macros
+ PROC load macros (TEXT CONST datei)
+ Zweck: Lädt Makro-Definitionen in den Makro-Speicher des Textsystems. Die
+ Definitionen müssen in der Datei 'datei' enthalten sein (mit dem
+ Editor erstellen). Es können mehrere Definitionen in der Datei ent-
+ halten sein. Um den Makro-Speicher zu leeren, übergibt man eine
+ leere 'datei'.
+
+ Eine Makro-Definition besteht aus einem
+ - Makro-Kopf:
+ Muß alleine auf einer Zeile stehen. Der Makro-Kopf fängt mit
+ '\#*'-Zeichen an und wird mit '\#' beendet. Beispiel: \#*ein macro\#
+ Der Name eines Macros muß (wie alle andern Anweisungen auch)
+ mit kleinen Buchstaben geschrieben werden. Leerzeichen spielen
+ keine Rolle.
+ Eventuelle Parameter müssen in Klammern (bei mehreren durch
+ Kommata getrennt) und mit einem $-Zeichen numeriert werden.
+ Beispiel:
+ \#*macro1 ($1)\#
+ \#*macro 2 ($1, $2)\#
+
+ - Makro-Rumpf:
+ Besteht aus beliebig vielen Text-Zeilen, die Kommandos enthalten
+ können. Parameter (also das $-Zeichen mit anschließender Nummer)
+ werden bei Aufruf eines Makros ersetzt. In einem Makro-Rumpf
+ darf keine Makro-Anweisung erscheinen, die noch nicht definiert
+ wurde (sog. "Vorwärts-Referenzen").
+
+ - Makro-Ende:
+ besteht aus der Anweisung
+ \#*macro end\#
+ und muß wie der Makro-Kopf alleine auf einer Zeile stehen.
+
+ Fehlerfälle:
+ * file does not exists
+ Die Eingabe-Datei 'datei' ist nicht vorhanden.
+ * macro store overflow (number lines)
+ Es passen zur Zeit nicht mehr als 1 000 Zeilen in den Makro-Speicher.
+ * macro store overflow (number macros)
+ Es passen zur Zeit nicht mehr als 100 Makro-Defintionen in den
+ Makro-Speicher.
+
+pageform
+ PROC pageform
+ Zweck: Wie beschrieben, jedoch ohne Parameter. Die zuletzt benutzte
+ Datei wird bearbeitet. Für die Druckdatei wird dieser Dateiname,
+ an den ".p" angehängt wird, eingesetzt. Beispiel:
+
+ edit ("test")
+ ...
+ pageform (* wird zu 'pageform ("test", "test.p")'
+ ergaenzt *)
+
+ PROC pageform (TEXT CONST dateiname)
+ Zweck: Wie beschrieben, wobei der Parameter für die Druckdatei ergänzt
+ wird (an 'dateiname' wird '.p' angehängt). Beispiel:
+
+ pageform ("test")
+ (* wird zu 'pageform ("test", "test.p")' ergaenzt *)
+
+ PROC pageform (TEXT CONST dateiname, druckdatei)
+ Zweck: Wie oben.
+
+print
+ PROC print (TEXT CONST datei)
+ Zweck: Druck der Datei 'datei' unter Berücksichtigung von Anweisungen.
+
+
+
diff --git a/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil5 b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil5
new file mode 100644
index 0000000..d59b147
--- /dev/null
+++ b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil5
@@ -0,0 +1,667 @@
+ EUMEL-Benutzerhandbuch
+
+
+ TEIL 5: ELAN-Compiler
+
+
+Der ELAN-Compiler im EUMEL-System
+
+In diesem Kapitel wird die Benutzung des ELAN-Compilers im EUMEL-System be-
+schrieben. Es enthält Angaben, welche Einschränkungen bzw. Erweiterungen
+gegenüber dem Sprachstandard existieren. Eine Einführung in die Programmier-
+sprache ELAN wird hier nicht gegeben.
+
+
+
+1. Einführung
+
+Der im EUMEL-System eingesetzte ELAN-Compiler wurde von J. Liedtke und
+U. Bartling am HRZ Bielefeld in den Jahren 1975/76 erstellt und in den
+folgenden Jahren erweitert und der Sprachbeschreibung angepaßt. Der gleiche
+ELAN-Compiler wird auch auf verschiedenen Großrechnern (TR440, IBM, SIEMENS)
+eingesetzt.
+
+Den ELAN-Compiler kann man sich als aus zwei Teilen bestehend vorstellen.
+Einmal gibt es den "eigentlichen" ELAN-Compiler, der ein ELAN-Programm in
+eine Maschinensprache (im EUMEL-System der sogenannte EUMEL0-Code) übersetzt.
+Zum anderen verwaltet der ELAN-Compiler übersetzte Moduln (in ELAN Packets
+genannt).
+
+In einem Packet können Prozeduren, Datentypen und/oder Operatoren definiert
+werden. Ist ein solches Packet vorübersetzt (im EUMEL-System wird dieser
+Vorgang 'insertieren' genannt), stehen diese Objekte zur Benutzung zur Ver-
+fügung. Durch Packets kann man somit die Sprache ELAN erweitern.
+
+Weitere Informationen über die Programmiersprache ELAN finden Sie in den
+folgenden Büchern:
+
+Hommel / Jähnichen / Koster:
+Methodisches Programmieren
+W. de Gruyter, Berlin, 1983
+
+Klingen / Liedtke:
+Programmieren mit ELAN
+Teubner, Stuttgart, 1983
+
+In der Regel sind in einem EUMEL-System die Standard-Packets bereits in-
+sertiert (Ausnahmen: Datentypen #ib#VECTOR#ie# und #ib#MATRIX#ie#). Zusätz-
+lich sind weitere Packets vorübersetzt, die Kommandos zur Verfügung stellen.
+Welche weiteren Packets insertiert werden, kann jede EUMEL-Installation und
+jeder Nutzer entscheiden. Somit kann man sein System auf spezielle
+Anwendungen zuschneiden.
+
+
+
+2. Übersetzen mit dem ELAN-Compiler
+
+In diesem Abschnitt wird erklärt, wie Programme mit dem ELAN-Compiler über-
+setzt oder vorübersetzt werden können.
+
+
+
+Einfaches Übersetzen: 'run'-Kommando
+
+Mit dem 'run'-Kommando kann ein ELAN-Programm übersetzt und ausgeführt
+werden.
+
+Das 'run'-Kommando (vergl. auch die Kommandos in der Beschreibung des
+Monitors) übersetzt ein in einer Datei befindliches ELAN-Programm. Beispiel:
+
+ run ("mein programm")
+
+übersetzt das ELAN-Programm, welches in der Datei 'mein programm' enthalten
+ist. (Wie man ELAN-Programme schreibt, ist u.a. im Editor-Kapitel beschrie-
+ben).
+
+Der Fortschritt der Übersetzung wird durch laufende Nummern auf dem Bild-
+schirm des Benutzers angezeigt, die die gerade verarbeiteten Zeilennummern
+anzeigen. Da der ELAN-Compiler ein Zwei-Paß Compiler ist, werden alle
+Zeilen (mindestens) zweimal überprüft.
+
+Ist das Programm syntaktisch korrekt, d.h. hat der ELAN-Compiler keine
+Fehler gefunden, wird eine Ende-Meldung abgesetzt, die den Speicherumfang
+des übersetzten Programms enthält. Die Ende-Meldung entfällt, wenn die Task
+an kein Terminal angekoppelt ist.
+
+Nach der Ende-Meldung wird das Programm unmittelbar ausgeführt (ein Binder
+ist im EUMEL-System nicht notwendig).
+
+Merke: Das Kommando 'run' übersetzt ein in einer Datei befindliches Programm
+und führt fehlerfreie Programme aus.
+
+
+
+Korrektur von Fehlern
+
+In diesem Abschnitt wird beschrieben, wie (syntaktische bzw. semantische)
+Fehler korrigiert werden können.
+
+Entdeckt der ELAN-Compiler Fehler, so meldet er sie dem Benutzer unter An-
+Angabe der Zeilennummer. Die zwei Pässe des Compilers sind so konstruiert,
+daß sie unterschiedliche Fehler entdecken. Ist bereits im ersten Paß ein
+Fehler entdeckt worden, wird der zweite Paß nicht gestartet. Somit kann es
+vorkommen, daß man glaubt, alle Fehler beseitigt zu haben und dann werden
+wieder (andere) Fehler durch den zweiten Paß gemeldet ...
+
+Fehlermeldungen und Quelldatei werden nach Abschluß der Übersetzung durch
+den Paralleleditor angezeigt. Vergl. dazu auch die Beschreibung des Editors.
+
+Merke: Eventuelle Fehler und das zu korrigierende Programm werden durch den
+Paralleleditor angezeigt. So kann man das fehlerhafte Programm bequem ver-
+ändern.
+
+
+Nochmalige Ausführung eines Programms: 'run again'
+
+Mit 'run again' kann das zuletzt fehlerfrei übersetzte Programm nochmals
+ausgeführt werden.
+
+Ist ein Programm fehlerfrei übersetzt worden, so kann man es mit dem Komman-
+do 'run again' (beispielsweise mit anderen Eingabedaten) nochmals ausführen.
+
+Merke: Das Kommando 'run again' führt das zuletzt übersetzte Programm noch-
+mals aus.
+
+
+
+Übersetzen von Kommandos
+
+Auch Kommandos werden in der Regel vom ELAN-Compiler übersetzt.
+
+Der ELAN-Compiler wird nicht nur für Programme eingesetzt, sondern auch als
+Übersetzer für die EUMEL-Kommandosprache (in anderen Systemen "job control
+language", abgekürzt JCL genannt) und für Kommandos, die man im Editor geben
+kann. Jedes Kommando der EUMEL-Kommandosprache ist ein kleines ELAN-Programm,
+welches in der Regel aus einem Prozeduraufruf besteht. Einige häufig be-
+nutzte Kommandos werden der Effizienz halber über einen Kommando-Interpreter
+abgewickelt. Beispiel:
+
+ edit ("mein erstes Programm")
+
+Natürlich ist es möglich, mehrere Kommandos oder ein richtiges, einzeiliges
+Programm als Kommando zu verwenden. Beispiele:
+
+ put (17 * 4)
+
+ INT VAR i; FOR i FROM 1 UPTO 100 REP put ("i") PER
+
+ edit ("datei"); lineform ("datei"); print ("datei")
+
+ INT VAR i; FOR i FROM 1 UPTO 10 REP print ("d") END REP
+
+Mit vorübersetzten Prozeduren (siehe auch das Kommando 'insert') ist es
+möglich, eine eigene Kommandosprache zusammenzustellen.
+
+Merke: Der ELAN-Compiler wird auch für die Übersetzung und Ausführung von
+Kommandos benutzt.
+
+
+
+Vorübersetzen: 'insert'
+
+Das Kommando 'insert' übersetzt ein in einer Datei befindliches ELAN-Pro-
+gramm und trägt dieses in den Tabellenspeicher des Compilers ein.
+
+Mit dem Kommando 'insert' kann ein ELAN-Programm (d.h. ein Packet oder eine
+Packetfolge) in den Tabellenspeicher (eine Art "Compilerdatenbank") des
+ELAN-Compilers eingetragen werden. Die in den Packets enthaltenen Objekte
+stehen nach Abschluß der Übersetzung zur Verfügung. Beispiel:
+
+Die Datei 'mein druck' enthalte folgendes Programm:
+
+ PACKET mein druck DEFINES drucke:
+
+ PROC drucke (TEXT CONST datei):
+ edit (datei);
+ lineform (datei);
+ pageform (datei);
+ print (datei)
+ END PROC drucke;
+
+ END PACKET drucke;
+
+Mit dem Kommando
+
+ insert ("mein druck")
+
+wird das Packet 'drucke' in die Tabellen des ELAN-Compilers aufgenommen.
+Nun kann (als Kommando oder in einem Programm) der Prozeduraufruf 'drucke'
+verwandt werden.
+
+Man beachte, daß der Nutzer beim Einrichten seiner Task alle insertierten Ob-
+jekte der Vater-Task erhält. Insertiert der Benutzer in seiner Task weitere
+Packets, so sind diese nur ihm verfügbar (oder ggf. seinen Sohn-Tasks). Es
+ist somit möglich, Tasks mit unterschiedlichem Sprachumfang einzurichten.
+
+Einmal insertierte Packets können nicht mehr aus den Compilertabellen ent-
+fernt werden. Man kann also nur die Task löschen (bitte vorher alle Dateien
+archivieren oder bei der Vater-Task aufheben (siehe Kommando: 'save')).
+
+Das Kommando 'insert' arbeitet auch mit einem Thesaurus (vergl. dazu auch
+den Teil über Dateien). Beispiel:
+
+ insert (ALL myself)
+
+insertiert alle Dateien der Benutzer-Task in Reihenfolge.
+
+Merke: Das Kommando 'insert' übersetzt die in einer Datei enthaltene Packet-
+folge und trägt diese in die Tabellen des Compilers ein.
+
+
+
+Programme von einem Programm übersetzen lassen
+
+Manchmal ist es notwendig, daß ein Programm den ELAN-Compiler zur Über-
+setzung und Ausführung eines Programms aufrufen muß.
+
+Natürlich kann man auch die Kommandos 'run' oder 'insert' von einem Programm
+aus aufrufen. Leider müssen die zu übersetzenden Programme in einer Datei
+enthalten sein. Will man jedoch nur eine Anweisung übersetzen und ausführen
+lassen und nicht den "Umweg" über eine Datei gehen (wie z.B. die Kommandos
+im Monitor oder Editor), so kann man die Prozedur '#ib#do#ie#' verwenden.
+Beispiel:
+
+ ...
+ get (eingabe);
+ do (eingabe);
+ ...
+
+Findet der ELAN-Compiler bei der Übersetzung eines Textes der Prozedur 'do'
+einen Fehler, so wird dieser Fehler über 'errorstop' gemeldet (vergl. dazu
+auch das Kapitel über die Fehlerbehandlung im System-Handbuch) und die Über-
+setzung bei der ersten Fehlermeldung abgebrochen. In diesem Fall kann ein
+Nutzer den Fehler durch eine #ib#Fängerebene#ie# leicht selbst behandeln.
+
+Merke: Die Prozedur 'do' übersetzt (kleinere) ELAN-Programme von einem Pro-
+gramm aus.
+
+
+
+Kommandos zur Steuerung des ELAN-Compilers
+
+In diesem Abschnitt beschreiben wir die Kommandos für die Steuerung des
+ELAN-Compilers#ie#. Ebenso wie die Kommandos zur Übersetzung eines Programms
+müssen die Kommandos zur Steuerung des Compilers vom Monitor gegeben werden.
+
+Mit dem Kommando
+
+ prot ("datei name")
+
+wird das Listing des ELAN-Compilers eingeschaltet und in die angegebene
+Datei ausgegeben. Mit
+
+ prot off
+
+wird es wieder ausgeschaltet. 'prot off' ist voreingestellt.
+
+Normalerweise werden Zeilennummern des Quellprogramms im übersetzten Pro-
+gramm mitgeführt, so daß bei einem Fehler zusätzlich zur Fehlermeldung auch
+die Nummer der Zeile ausgegeben werden kann, in der der Fehler aufgetreten
+ist. Mit dem Kommando
+
+ check off
+
+kann die Generierung von Zeilenummern für das Objektprogramm abgeschaltet
+werden. Durch die Angabe dieses Kommandos wird weniger Code für das
+Programm erzeugt. Mit
+
+ check on
+
+wird die Generierung von Zeilennummern durch den Compiler wieder einge-
+schaltet. 'check on' ist voreingestellt. Mit der Prozedur
+
+ check
+
+die ein boolesches Resultat liefert, kann in einem Programm abgefragt werden,
+ob der 'check'-Zustand ein- oder ausgeschaltet ist. Beispiel:
+
+ IF check THEN check off FI
+
+Merke: Die Kommandos 'check on' bzw. 'check off' schalten das Einfügen von
+Zeilennummern in den erzeugten Code ein bzw. aus.
+
+
+
+3. Abweichungen gegenüber dem Sprachstandard
+
+Der im HRZ Bielefeld entwickelte ELAN-Compiler weist einige Abweichungen
+gegenüber dem Sprachstandard auf, wie er in der Sprachbeschreibung formu-
+liert ist. Es existieren einige Einschränkungen, die einen Programmierer
+jedoch nicht weiter behindern. Die Spracherweiterungen wurden meist speziell
+für das EUMEL-System geschaffen. Weitere Abweichungen gegenüber dem aktuellen
+Sprachstandard, die aber in der nächsten Sprachbeschreibung enthalten sein
+werden, sind in einem weiteren Abschnitt aufgeführt.
+
+
+
+Einschränkungen gegenüber dem Sprachstandard
+
+ * Das "row display" wurde nicht implementiert. Der Grund dafür liegt in
+ dem unverhältnismäßig hohen Aufwand, dieses Sprachmittel bei der gegen-
+ wärtigen Compiler-Struktur zu implementieren. Abhilfe: Man verwende den
+ Konstruktor. Beispiel:
+
+ ROW 5 INT VAR vektor;
+ vektor := [1, 2, 3, 4, 5]; (* nicht möglich *)
+ vektor := ROW 5 INT :(1, 2, 3, 4, 5); (* Ersatz: Konstruktor *)
+
+ * Einige alternative Darstellungen von Symbolen können nicht verwendet
+ werden. Diese sind:
+
+ "&"-Zeichen für "AND",
+ "/="-Zeichen für "<>",
+ "%"- und "//"-Zeichen für "DIV".
+
+ * Eine Typ-Definition muß einer Deklaration immer textuell vorangehen.
+ Beispiel:
+
+ TYPE QUADRAT = ... (* erlaubt *)
+ QUADRAT VAR rundes quadrat;
+ ...
+ PUNKT VAR meiner; (* verboten *)
+ TYPE PUNKT = ...
+
+ Es ist jedoch erlaubt, einen Typ in einer Typ-Definition zu verwenden,
+ der textuell erst später definiert wird. Beispiel:
+
+ TYPE PERSON = STRUCT (TEXT name, vorname, ADRESSE wohnort);
+ TYPE ADRESSE = ...
+
+ Diese Einschränkung ("defined before applied") gilt nur für Typen,
+ nicht für Datenobjekte u.ä.. Selbstverständlich ist
+
+ otto := 0;
+ INT VAR otto;
+ ...
+
+ erlaubt (aber kein besonders schöner Programmierstil)!
+
+ * Die Operatoren AND und OR können nicht redefiniert werden, sofern einer
+ ihrer Operanden vom Typ BOOL ist.
+
+
+
+Implementationsbedingte Einschränkungen
+
+ * Es sind bis zu 32 000 Zeichen in einem TEXT zugelassen. Hat ein TEXT
+ bis 13 Zeichen, so wird er vollständig auf dem Stack untergebracht.
+ TEXTe mit mehr als 13 Zeichen werden auf dem Heap gespeichert. Die
+ Benutzung des Heaps bedeutet unter Umständen eine Verlangsamung eines
+ Programms. Darum ist
+
+max text length = 32 000
+
+ * Die Anzahl der Zeichen in einem TEXT-Denoter (Angabe eines TEXTes in
+ einem Programm) ist auf 254 Zeichen beschränkt.
+
+ * INT-Werte werden in sechzehn Bit dargestellt (einschließlich Vor-
+ zeichen). Das bedeutet, daß
+
+ maxint = 32 767
+ minint = - 32 768
+
+ ist.
+
+ * REAL-Werte werden intern mit einer Mantisse von 13 Stellen abgespei-
+ chert, von denen die ersten sieben Stellen bei der Ausgabe dargestellt
+ werden. Das bedeutet, daß
+
+ maxreal = 9.999999999999e126
+
+ ist.
+
+ * Die lexikographische Reihenfolge von Zeichen entspricht dem ASCII-Code
+ (vergl. dazu die Code-Tabelle).
+
+ * Weiterhin sieht der ASCII-Code noch eine Anzahl von Steuerzeichen vor,
+ die jedoch von Herstellern leider nicht immer gleich interpretiert
+ werden. Diese Zeichen sind im EUMEL-System teilweise normiert und
+ können verwandt werden. Die verfügbaren Steuerzeichen sind ebenfalls im
+ EUMEL-Taschenbuch aufgeführt.
+
+ * Die Initialisierung von Paketen (genauer: die Initialisierung von
+ Datenobjekten, die in vorübersetzten PACKETs außerhalb von Prozeduren
+ deklariert wurden) wird nur einmal, während der Übersetzung, durchge-
+ führt. Werden mehrere Pakete hintereinander (aus einer Datei) übersetzt,
+ dürfen die Prozeduren 'run', 'run again', 'insert' und 'do', die wieder
+ den ELAN-Compiler aufrufen, nur bei der Ausführung des letzten Packets
+ verwandt werden, weil der ELAN-Compiler nicht rekursiv benutzbar ist.
+
+
+
+Erweiterungen gegenüber dem Standard
+
+ * Einem Datenobjekt, das an einen #ib#Datenraum#ie# gebunden werden soll,
+ wird bei der Deklaration das Schlüsselwort #ib#BOUND#ie# vorangestellt.
+ Damit wird dem ELAN-Compiler mitgeteilt, daß er für ein solches Objekt
+ keinen Speicherplatz reservieren muß. Die Assoziation mit einem Daten-
+ raum erfolgt bei der Deklaration mit Hilfe der Initialisierung.
+ Beispiel:
+
+ BOUND INT VAR objekt :: old ("hugo");
+ (* eine bereits errichtete Datei wird unter dem Namen "hugo" benutzt.
+ "objekt" ist jetzt an die Datei mit dem Namen "hugo" "gebunden" *)
+
+
+
+Vorweggenommene Implementation des nächsten Standards
+
+In diesem Abschnitt sind Erweiterungen/Einschränkungen des ELAN-Compilers
+hinsichtlich der aktuellen ELAN-Sprachbeschreibung aufgeführt, die in der
+nächsten Sprachbeschreibung mit aufgenommen werden.
+
+ * ASCII-Zeichen, die nicht unmittelbar dargestellt werden können, können
+ in TEXT-Denotern angegeben werden, sofern sie in Anführungszeichen
+ eingeschlossen werden. Beispiele:
+
+ ""13""
+
+ ist ein TEXT-Denoter, der nur CR (carriage return) enthält.
+
+ "Jetzt erfolgt ein Zeilenwechsel "13""10""
+
+ Hier wird nach der Ausgabe des Textes ein "Wagenrücklauf" ('CR',
+ Code = 13) und einen Zeilenvorschub ('LF', Code = 10) erzeugt.
+
+ ""1""4""
+
+ positioniert in die linke obere Ecke eines Bildschirms (Code = 1) und
+ löscht den Bildschirm (Code = 4).
+
+ * Im aktuellen Standard wurde die #ib#Reihenfolge der Auswertung von
+ Operanden#ie# nicht definiert. Nunmehr wird zusätzlich nicht garantiert,
+ daß alle Operanden ausgewertet werden, wenn dies nicht notwendig ist.
+ Beispiel:
+
+ IF f (x) > 0 AND x <> 0 THEN ... FI
+
+ Hier muß beispielsweise 'f (x)' nicht ausgewertet werden, wenn 'x = 0'
+ ist.
+
+ * Die booleschen Operatoren CAND und COR stehen zusätzlich zur Verfügung.
+ Wirkung:
+
+ a CAND b :<==> IF a THEN b ELSE FALSE FI
+
+ a COR b :<==> IF a THEN TRUE ELSE b FI
+
+ Beispiel:
+
+ IF element vorhanden
+ THEN verarbeite element
+ FI.
+
+ element vorhanden:
+ index > 0 CAND liste (index) > 0.
+
+ * Prozeduren als Parameter. Beispiel:
+
+ (* Deklaration: *)
+ PROC draw (REAL PROC (REAL CONST) funktion,
+ REAL CONST von, bis, delta)
+ (* Aufruf: *)
+ draw (REAL PROC (REAL CONST) sin, -pi, pi, 0.1)
+
+ Die obige Form von Prozedur-Parametern wird als "Langform" bezeichnet.
+ Die Langform muß verwandt werden, wenn generische aktuelle Parameter
+ benutzt werden. Eine "Kurzform" reicht aus, wenn der aktuelle Prozedur-
+ Parameter keine generischen Prozedur ist, d.h. eindeutig über den
+ Prozedurnamen (und nicht noch über die Datentypen seiner Parameter)
+ identifiziert werden kann. Die Kurzform unterscheidet sich von der
+ Langform nur beim Aufruf, bei dem eventuelle Resultate und die Daten-
+ typen der Parameter nicht mit angegeben werden müssen. Beispiel:
+
+ (* Aufruf obiger Prozedur bei nichtgenerischer aktueller Prozedur
+ 'sin' *)
+ draw (PROC sin, -pi, pi, 0.1)
+
+ * In Paketen sind auch außerhalb von Prozeduren Refinements zugelassen.
+ In solchen "Paket-Refinements" dürfen nur Paket-Objekte angesprochen
+ werden. Insbesondere ist es erlaubt, auch im letzten Paket ('main
+ packet') neben Prozeduren auch Refinements in beliebiger Reihenfolge zu
+ benutzen. Beispiel:
+
+ PROC kommando erkennung:
+ ...
+ END PROC kommando erkennung;
+
+ PROC kommando ausführung:
+ ...
+ END PROC kommando ausführung;
+
+ datei assoziieren;
+ saetze lesen und bearbeiten;
+ ende behandlung.
+
+ datei assoziieren:
+ FILE VAR f :: sequential file ...;
+ ...
+ saetze lesen und bearbeiten:
+ ...
+ ende behandlung:
+ put ("Ende der Bearbeitung").
+
+ Dies ist die Schreibweise, die wir empfehlen. Will man aber Refinements
+ auch zwischen Prozeduren deklarieren, wird es etwas komplizierter.
+ Beispiel:
+
+ PROC a:
+ END PROC a;
+ ref; (* Refinement Aufruf *)
+ PROC b:
+ END PROC b;
+ (* Achtung: Semikolon, Punkt vor dem Refinement *)
+ .ref: . ; (* Punkt, Semikolon nach dem Refinement *)
+ PROC c:
+ END PROC c
+
+ Paket-Refinements dürfen auch von Prozeduren benutzt werden, allerdings
+ sind dann auch die Sichtbarkeitsregeln zu beachten. D.h. die Paket-
+ Refinements, die in Prozeduren verwandt werden, dürfen dann auch nur
+ Paket-Objekte ansprechen. Die Aufnahme eines Refinements in das Inter-
+ face ist verboten.
+
+
+
+4. Interne Fehlermeldungen des Compilers
+
+Interne Fehlermeldungen des Compilers#ie# erfolgen, wenn der ELAN-Übersetzer
+an implementationsbedingte Einschränkungen stößt.
+
+ Interne Fehlermeldungen erfolgen in der Form:
+
+ COMPILER ERROR: <zahl>
+
+wobei <zahl> folgende Werte annehmen kann:
+
+<zahl> Bedeutung und eventuelle Abhilfe:
+
+ 101 name table overflow:
+ Die Anzahl der Namen im Programm ist zu groß oder es wurden die
+ Anführungstriche eines TEXT-Denoters vergessen. Keine Abhilfe.
+
+ 102 symbol table overflow:
+ Die Anzahl der deklarierten Objekte ist zu groß.
+ Abhilfe: Programm in Pakete unterteilen.
+
+ 103 intermediate string overflow:
+ Abhilfe: Programm in Pakete unterteilen.
+
+ 104 permanent table overflow
+ Zu viele Pakete insertiert.
+ Abhilfe: Keine (neue Task beginnen).
+
+ 106 packet address overflow:
+ Insgesamt zu viele Adressen in Paketen ( > 64K ), d.h. ein Daten-
+ objekt ist zu groß.
+ Keine Abhilfe.
+
+ 107 local data overflow:
+ Ein Datenobjekt in einer Prozedur ist zu groß ( > 32K ).
+ Abhilfe:
+ Datenobjekt in mehrere unterteilen.
+
+ 204 compiler stack overflow:
+ Keine Abhilfe.
+
+ 301 too many modules:
+ Zu viele Pakete, Prozeduren und Operatoren ( > 2048 ).
+ Keine Abhilfe.
+
+ 303 applied table overflow:
+ siehe 304
+
+ 304 too many labels:
+ In dem gerade übersetzten Modul (Prozedur, Operator oder Paket-
+ rumpf) werden vom Compiler zu viele Marken benötigt (mehr als
+ 2000). Marken werden z.B. für die Codegenerierung von Auswahl
+ (IF ...) und Wiederholung (REP ...) gebraucht. Insbesondere bei
+ SELECT-Anweisungen werden 'casemax - casemin + 2' Marken
+ benötigt, wobei 'casemax' der INT-Wert des maximalen, 'casemin'
+ der des minimalen CASE-Wertes ist. Dieser Fehler ist somit fast
+ immer auf zu viele und/oder zu weit gespannte SELECT-Anweisungen
+ zurückzuführen.
+ Abhilfe: SELECT-Anweisungen über mehrere Prozeduren verteilen oder
+ Spannweiten verringern.
+
+ 305 code overflow:
+ Der insgesamt erzeugte Code ist zu umfangreich ( > 256K ).
+ Keine Abhilfe.
+
+ 306 packet data overflow:
+ Insgesamt zu viele Datenobjekte in den Paketen ( > 128K ).
+ Keine Abhilfe.
+
+ 307 local data overflow:
+ Zu viele (lokale) Datenobjekte in einer Prozedur ( > 32K ).
+ Abhilfe: Prozedur in mehrere unterteilen, so daß die Datenobjekte
+ sich über mehrere Prozeduren verteilen.
+
+ 308 module code overflow:
+ Ein Modul (Prozedur, Operator oder Paket-Initialisierungsteil) ist
+ zu groß ( > 7.5 KB Code).
+ Abhilfe: In mehrere Prozeduren oder Pakete zerlegen.
+
+Anmerkung: Fehlermeldungen, die hier nicht aufgeführt sind, weisen in der
+Regel auf ein fehlerhaftes Arbeiten des ELAN-Compilers hin. In diesem Fall
+bitten wir um die Einsendung des Programms (Listing, Quelldatei auf Diskette
+bei umfangreichen Programmen) und entsprechender Fehlermeldung.
+
+
+
+5. Übersicht über die Compiler-Kommandos
+
+check
+ BOOL PROC check
+ Zweck: Informationsprozedur.
+
+ PROC check on
+ Zweck: Einschalten der Generierung von Zeilennummern durch den
+ ELAN-Compiler. Voreingestellt ist 'check on'.
+
+ PROC check off
+ Zweck: Ausschalten der Generierung von Zeilennummern durch den
+ ELAN-Compiler.
+
+do
+ PROC do (TEXT CONST program)
+ Zweck: Übersetzen und Ausführen von 'program' von einem Programm aus.
+
+insert
+ PROC insert
+ Zweck: Insertieren eines oder mehrerer PACKETs. Der Programmtext muß sich
+ in einer Datei befinden. Der Dateiname ist der zuletzt benutzte
+ Dateiname.
+
+ PROC insert (TEXT CONST dateiname)
+ Zweck: Wie oben. Der Programmtext wird aus der Datei mit dem Namen
+ 'dateiname' geholt.
+
+ PROC insert (THESAURUS CONST t)
+ Zweck: Insertieren aller PACKETs, die in den Dateien des Thesaurus 't'
+ enthalten sind.
+
+prot
+ BOOL PROC prot
+ Zweck: Informationsprozedur, ob 'prot' eingeschaltet ist.
+
+ PROC prot (TEXT CONST dateiname)
+ Zweck: Einschalten des Compilerlistings auf dem Bildschirm. Das Listing
+ wird gleichzeitig in die Datei 'dateiname' geschrieben.
+
+prot off
+ PROC prot off
+ Zweck: Ausschalten des Listings.
+
+run
+ PROC run
+ Zweck: Übersetzen und Ausführen eines ELAN-Programms. Der Programmtext
+ muß sich in einer Datei befinden. Der Dateiname ist der zuletzt
+ benutzte Dateiname.
+
+ PROC run (TEXT CONST dateiname)
+ Zweck: Wie oben. Der Programmtext wird aus der Datei mit dem Namen
+ 'dateiname' geholt.
+
+
+
diff --git a/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil6a b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil6a
new file mode 100644
index 0000000..1ee80ec
--- /dev/null
+++ b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil6a
@@ -0,0 +1,1590 @@
+ EUMEL-Benutzerhandbuch
+
+
+ TEIL 6: Erste Hilfe in ELAN
+
+
+Vorwort
+
+Dieser Teil des EUMEL-Handbuchs ist keine "Einführung in die Programmierung
+mit ELAN", sondern ist als Begleitmaterial für einen ELAN-Kurs gedacht.
+Zudem beschreibt das Skript nicht die vollständige Sprache; dafür ist die
+Sprachbeschreibung und das Handbuch vorgesehen. Folgende ELAN-Bücher sind
+z.Zt. erhältlich:
+
+Klingen / Liedtke:
+Programmieren mit ELAN
+Teubner, Stuttgart, 1982
+
+Jähnichen u.a.:
+Systematisches Programmieren mit ELAN
+W. de Gruyter, 1982
+
+Wir haben in dieses Skript auch einige Aufgaben mit aufgenommen, die An-
+fänger auf jeden Fall lösen sollten. Die Aufgaben dienen aber nur dazu, das
+erlernte Wissen über ELAN zu überprüfen und sind keine eigentlichen Program-
+mieraufgaben, die es im begleitenden Kurs geben sollte. Es gibt zwei Arten
+von Aufgaben:
+
+a) HSG (Hätten Sie's gewußt?): Aufgaben, die das bis dahin Gelernte über-
+ prüfen sollen.
+b) TSW (Trau', Schau', wem!): Aufgaben mit Programmen, die Fehler enthalten
+ können. Alle Programme dieses Skripts sind übrigens von der Art TSW.
+
+Es ist auch sinnvoll und notwendig, möglichst viele Programme dieses Skripts
+direkt auf dem Terminal zu probieren und zu verändern. Auf diese Weise wird
+ein Anfänger auch mit den Fehlermeldungen des ELAN-Compilers vertraut.
+
+
+
+Das erste Programm
+
+Gleich am Anfang einer Programmierlaufbahn haben Anfänger eine schwierige
+Hürde zu nehmen: das erste Programm "zum Laufen" zu bringen. Das wird einem
+Anfänger meist nicht leicht gemacht: schließlich hat er mit dem Betriebs-
+system eines Computers zu kämpfen. Ein #ib#Betriebssystem#ie# sorgt u.a. für
+die Steuerung so unterschiedlicher Peripheriegeräte wie Drucker, Lochkarten-
+leser, Magnetplatten und -bänder usw. Zusätzlich hat es dafür Sorge zu
+tragen, daß Informationen sicher gespeichert werden und nicht unbeabsichtigt
+verändert werden können. Letztendlich hat ein Betriebsystem die Aufgabe, die
+Aufträge von Benutzern ("jobs") - und das können mehrere auf einmal sein -
+sicher und effizient bearbeiten zu lassen. Um mit einem Betriebsystem
+"sprechen" zu können, ist meist eine eigene Sprache vorhanden, die Kommando-
+sprache ("job control language", abgekürzt: JCL).
+
+Eine Kommandosprache kann - auf Grund der vielfältigen Aufgaben, die mit
+ihrer Hilfe formuliert werden müssen - mehr oder weniger kompliziert sein.
+Zusätzlich sind Kommandosprachen sehr unterschiedlich: aus leicht einsichti-
+gen Gründen wollen sich Hersteller nicht auf eine Kommandosprache einigen.
+Deshalb können wir die Anweisungen in einer speziellen Kommandosprache hier
+nicht angeben; man erfragt diese am besten. Auf jeden Fall muß etwas getan
+werden, um ein Programm auf einem Rechner "zum Laufen" zu bringen.
+
+Wie bereits erwähnt, beschränken wir uns hier auf die eigentlichen Programme.
+Um den Mechanismus mit den Anweisungen an das Betriebsystem von Anfang
+an kennen zu lernen, denken wir uns ein sehr einfaches Programm aus, das wir
+bearbeiten lassen wollen.
+
+Programm 1:
+
+ put ("Hallo: mein erstes Programm")
+
+Dieses Programm muß nun dem Rechner zur Bearbeitung übergeben werden.
+Auch hier treffen wir auf Unterschiede bei den verschiedenen Rechensystemen:
+bei einigen Rechnern muß ein solches Programm (mit Anweisungen der
+Kommandosprache) auf Lochkarten übertragen werden, bei anderen dagegen
+tippt man das Programm direkt an einem Sichtgerät ("Terminal") ein. Die
+Ausgabe erfolgt dann über einen Schnelldrucker oder auch über das Sichtgerät.
+Um von Geräten bestimmter Installationen zu abstrahieren, nennen wir im
+folgenden das Eingabemedium #ib#Eingabegerät#ie# und das Gerät, auf dem die
+Resultate erscheinen, dementsprechend Ausgabegerät.
+
+Aufgabe (TSW):
+
+ Versuchen Sie, Programm 1 auf dem Rechner Ihrer Installation zu "rechnen".
+Übungsziel: Umgang mit dem Betriebsystem
+
+
+Das Ergebnis unseres ersten Programms ist nun das Erscheinen des Textes:
+'Hallo: mein erstes Programm'. Was ist hier passiert? Da ein Rechner ein
+ELAN-Programm meist nicht direkt ausführen kann, muß es in eine Form
+gebracht werden, die der Rechner "versteht". Diese Form ist wiederum eine
+(sehr andersartige und - für Menschen - nicht leicht verständliche) Sprache,
+die Maschinensprache. Man muß also ein ELAN-Programm übersetzen. Dies wird
+von einem Programm (und nicht etwa einer festverdrahteten Schaltung) vorge-
+nommen, einem Übersetzer. Eine bestimmte Art von Übersetzer heißt Compiler;
+er übersetzt ein Programm als Ganzes (im Gegensatz zu einem Interpreter, der
+nur einzelne Anweisungen übersetzt und anschließend ausführt). Darum sind
+bei ELAN-Programmen, die meist durch Compiler übersetzt ("kompiliert")
+werden, zwei Phasen zu unterscheiden:
+
+a) Übersetzungsphase:
+
+ In dieser Phase wird ein ELAN-Programm (man spricht von Quellprogramm
+ bzw. "source program") in ein äquivalentes Maschinenprogramm (Objektpro-
+ gramm) transformiert. Dabei überprüft der Übersetzer das Quellprogramm
+ auf eventuelle Fehler (Anweisungen, die nicht der ELAN-Sprachbeschreibung
+ entsprechen). Bei solchen Fehlern, die ein Compiler entdecken kann,
+ spricht man von syntaktischen Fehlern oder von Fehlern zur Übersetzungs-
+ zeit.
+
+b) Bearbeitungsphase:
+
+ In dieser Phase ("run time") wird das übersetzte (Maschinen-) Programm
+ abgearbeitet. Auch hier können Fehler auftreten (z.B. wenn auf einen Wert
+ vom Programm zugegriffen wird, der noch gar nicht berechnet wurde).
+ Solche Fehler nennt man Laufzeitfehler.
+
+Haben wir das erste Programm so geschrieben, wie oben angegeben, dürften
+keine Fehler entdeckt werden und das Programm wird (hoffentlich korrekt, d.h.
+mit den geforderten Ergebnissen) beendet. Was für ein Programm haben wir nun
+geschrieben bzw. was haben wir vom Rechner verlangt?
+
+Das Wort 'put' bezeichnet eine Prozedur. Eine Prozedur ist ein Algorithmus
+(hier mit Parametern): eine bestimmte Sammlung von Anweisungen und unter
+Umständen Daten. Eine solche Prozedur können wir in einem Programm unter
+einem Namen (nämlich 'put') ansprechen und ausführen lassen. Man spricht
+dann von dem Aufruf einer Prozedur, wenn ein Prozedurname geschrieben wird.
+Von einer Prozedur brauchen wir nur zu wissen, was die Prozedur macht, aber
+gottseidank nicht, wie sie es macht.
+
+Eine Prozedur wie 'put' ist vorgefertigt und einfach benutzbar, wobei wir
+später sehen werden, wie man solche Prozeduren selber schreiben kann. Die
+Prozedur 'put' hat einen Parameter, nämlich den in Klammern geschriebenen
+Text, der auf dem Ausgabegerät ausgegeben werden soll. Wir können eine
+solche Prozedur auch mit anderen Parametern versehen und mehrmals aufrufen:
+
+Programm 2:
+
+ put ("Programm:");
+ put (2)
+
+Mit dem zweiten Programm ist es uns gelungen, ein Programm mit zwei Anwei-
+sungen zu schreiben (dabei ist der Parameter bei dem ersten Aufruf der
+'put'-Prozedur ein Text, beim zweiten Parameter eine ganze Zahl).
+
+ELAN ist eine formatfreie Sprache, d.h. Anweisungen können so auf eine Zeile
+verteilt werden, wie es uns gefällt und zweckmäßig erscheint.
+
+Programm 3:
+
+ put ("mein"); put (3); put (".Programm")
+
+Man kann also eine oder mehrere Anweisungen auf eine Zeile schreiben oder
+eine Anweisung über mehrere Zeilen. Das setzt jedoch voraus, daß die Anwei-
+sungen voneinander getrennt werden (schließlich muß der Übersetzer erkennen
+können, wo eine Anweisung anfängt und aufhört). Das ist besonders notwendig,
+weil man in Namen in ELAN beliebig Leerzeichen zur besseren Lesbarkeit
+verwenden kann.
+
+
+Programm 4:
+
+ p u t ( "aha");
+ put ("aha")
+
+Beide Anweisungen bewirken also das Gleiche.
+
+Die Trennung von Anweisungen erfolgt in ELAN durch das Trennsymbol
+Semikolon. Es bedeutet soviel wie: "führe die nächste Anweisung aus". Aus
+diesem Grund darf hinter der letzten Anweisung eines Programms kein Semiko-
+lon geschrieben werden (es folgt ja auch keine Anweisung mehr).
+
+Der Aufruf einer Prozedur (wie z.B. 'put') verlangt von unserem Rechner im-
+mer eine Leistung. Wollen wir aber in einem Programm eine Bemerkung schrei-
+ben (z.B. um uns etwas zu merken), dann können wir einen Kommentar schrei-
+ben, der vom Übersetzer überlesen und somit keinen Einfluß auf die Aus-
+führung eines Programms hat. Ein Kommentar in ELAN wird durch die Zeichen
+(* und *) eingeschlossen und darf über mehrere Zeilen gehen. Kommentare sind
+in ELAN aber nur in wenigen Fällen notwendig, weil wir Programme durch
+andere Mittel gut lesbar machen können.
+
+
+
+Ziel der Programmierung
+
+Was wollen wir eigentlich mit dem Programmieren von Computern erreichen?
+Häufig wiederkehrende und somit oft langweilige Tätigkeiten oder solche, die
+besonders schnell erledigt werden müssen, sollen von dem "Werkzeug Computer
+erledigt werden. Gehaltsberechnungen, Unterstützung beim Schreiben von
+Texten, Katalogsysteme für Bibliotheken, Steuerung von Walzstraßen usw. sind
+typische Aufgaben für Computer.
+
+Bei der Programmierung wird also versucht, Objekte (wie z.B. Geld bei einer
+Gehaltsberechnung) und Prozesse (wie z.B. die Simulation von Wirtschaftsab-
+läufen) der realen Welt mit Hilfe von Programmen in einem Computer nachzu-
+bilden und nach bestimmten Vorstellungen so zu verändern, daß man "brauch-
+bare" Ergebnisse erlangt. In einem Programm sind Befehle an einen Rechner
+für eine solche Abbildung enthalten. Die Befehle in einem Programm werden
+Anweisungen genannt. Ein Programmierer muß also folgendes tun:
+
+1. Abbilden von Objekten und Prozessen der realen Welt in ein Programm.
+ Dabei müssen die Bedingungen der Aufgabe beachtet werden. Was das Pro-
+ gramm Programm leisten soll, wird darum in einer Spezifikation festgelegt.
+
+2. Einbringen des Programms in einen Rechner und Bearbeitung desselben. Die
+ Formulierung von Anweisungen in einem Programm erfolgt in einer bestimmten
+ Sprache, nämlich einer Programmiersprache.
+
+3. Interpretation der Ergebnisse.
+
+
+
+Das Konzept des Datentyps
+
+Befassen wir uns vorerst nur mit Objekten. Sicherlich gibt es sehr viele Ob-
+jekte in unserer Welt. Einige von ihnen haben aber gleiche Eigenschaften:
+
+- Fahrzeuge (Autos, Mofas, Dreiräder) bringen uns von Ort A nach Ort B.
+
+- Geld (Münzen, Geldscheine, Murmeln, Franc, DM) erlaubt es, etwas zu kaufen.
+
+- Schreibgeräte (Bleistift, Kugelschreiber, Schreibmaschine) sind die Werk-
+ zeuge von Leuten, die etwas zu schreiben haben.
+
+- ...
+
+Es ist also möglich, einige Objekte der realen Welt in Klassen zusammenzu-
+fassen. Eine solche Zusammenfassung kann hinsichtlich gleicher Eigenschaften
+bzw. gleicher Operationen, die für solche Objekte zugelassen sind, erfolgen.
+Eine Klasse von Objekten mit gleichen Eigenschaften wird in Programmier-
+sprachen Datentyp genannt. Dabei hat ein Datentyp immer einen Namen, der die
+Klasse von Objekten sinnvoll kennzeichnet. Als ein Datenobjekt wird ein
+Exemplar eines Datentyps (also ein spez. Objekt einer Klasse) bezeichnet.
+
+Datentypen sind in ELAN ein zentrales Konzept. Jedes der in einem ELAN-
+Programm verwandten Datenobjekte hat einen Datentyp; somit kann man Daten-
+typen auch als Eigenschaften von Datenobjekten ansehen. Für jeden Datentyp
+sind nur spezielle Operationen sinnvoll. Z.B. sind für einen Datentyp
+"UBoot" die Operationen "erstellen", "tauchen", "auftauchen", "versenken"
+und "lieber nicht verwenden" sinnvoll, aber nicht die Operation "+" wie bei
+ganzen Zahlen. Man kann nun Übersetzern die Aufgabe überlassen zu überprüfen,
+ob stets die richtige Operation auf einen Datentyp angewandt wird.
+
+Aufgabe (HSG):
+
+ Was ist ein Datentyp? Welche Funktion erfüllen Datentypen?
+Übungsziel: Datentyp-Konzept
+
+Einige Datentypen spielen bei der Programmierung eine besondere Rolle, weil
+sie häufig benötigt werden. In ELAN sind das die Datentypen für
+
+- ganze Zahlen. Dieser Datentyp wird INT (für "integer") genannt.
+
+- reelle Zahlen (REAL).
+
+- Zeichen und Zeichenfolgen (TEXT).
+
+- Wahrheitswerte (BOOL).
+
+Diese Typen werden in ELAN elementare Datentypen genannt. Für effiziente
+Rechnungen mit elementaren Datentypen gibt es in den meisten Rechnern
+spezielle Schaltungen, so daß die Hervorhebung und besondere Rolle, die
+sie in Programmiersprachen spielen, gerechtfertigt ist. Zudem hat man
+Werte-Darstellungen innerhalb von Programmen für die elementaren Datentypen
+vorgesehen, was wir im nächsten Abschnitt erklären wollen.
+
+Im weiteren Teil dieses Skripts werden wir uns zunächst auf die Behandlung
+der elementaren Datentypen beschränken. Das bedeutet für den Programmierer,
+daß er alle Objekte der realen Welt mit Hilfe der elementaren Datentypen in
+den Computer abbilden muß. Das kann manchmal sehr schwierig sein (wie bilden
+wir z.B. Personen oder UBoote mit den elementaren Datentypen ab?). Später
+werden wir dann Möglichkeiten kennenlernen, neue - problemgerechte -
+Datentypen in ELAN zu formulieren.
+
+
+
+Denoter (Werte-Repräsentationen) elementarer Datentypen
+
+Wenn wir mit Objekten elementarer Datentypen arbeiten, müssen wir die
+Möglichkeit haben, Werte in ein Programm zu schreiben. Leider kann man einen
+Wert "an sich" in einem Programm nicht direkt angeben. Schreiben wir z.B.
+4711, dann meinen wir zwar einen INT-Wert, haben aber die Ziffern 4, 7, 1 und
+1 geschrieben. Der eigentliche Wert wird in unserem Kopf oder - für unsere
+Zwecke - in einem Rechner gebildet.
+
+Die Werte-Darstellungen oder Werte-Repräsentationen, die in ELAN "Denoter"
+genannt werden, sind für jeden Datentyp unterschiedlich. Wie bereits erwähnt,
+haben alle Datenobjekte in ELAN (also auch Denoter) nur einen - vom Über­
+setzer feststellbaren - Datentyp. Aus der Form eines Denoters ist also der
+Datentyp erkennbar:
+
+- INT-Denoter:
+ Bestehen aus einer Aneinanderreihung von Ziffern. Beispiele:
+
+ 17, 007, 32767, 0
+
+ Führende Nullen spielen bei der Bildung des Wertes keine Rolle (sie werden
+ vom ELAN-Compiler überlesen). Negative INT-Denoter gibt es nicht (wie
+ negative Werte-Darstellungen in einem Programm geschrieben werden, lernen
+ wir bei den Ausdrücken).
+
+- REAL-Denoter:
+ Hier gibt es zwei Formen. Die erste besteht aus zwei INT-Denotern, die
+ durch einen Dezimalpunkt getrennt werden. Beispiele:
+
+ 0.314159, 17.28
+
+ Der Dezimalpunkt wird analog der deutschen Schreibweise als Komma
+ verwendet. Negative REAL-Denoter gibt es wiederum nicht.
+
+ Eine zweite Form wird kurioserweise als "wissenschaftliche Notation" be-
+ zeichnet. Sie findet dann Verwendung, wenn sehr große oder Zahlen, die
+ nahe bei Null liegen, dargestellt werden müssen. Beispiele:
+
+ 3.0 e5, 3.0e-5
+
+ Der (INT-) Denoter hinter dem Buchstaben e gibt an, wie viele Stellen der
+ Dezimalpunkt nach rechts (positive Werte) oder nach links zu verschieben
+ ist. Dieser Wert wird Exponent, der Teil vor dem Buchstaben e Mantisse
+ genannt.
+
+- TEXT-Denoter:
+ TEXT-Denoter werden in Anführungszeichen eingeschlossen. Beispiele:
+
+ "Das ist ein TEXT-Denoter"
+ "Jetzt ein Text-Denoter ohne ein Zeichen: ein leerer Text"
+ ""
+
+ Beachte, daß das Leerzeichen ebenfalls ein Zeichen ist. Soll ein An-
+ führungszeichen in einem TEXT erscheinen (also gerade das Zeichen, welches
+ einen TEXT-Denoter beendet), so muß es doppelt geschrieben werden:
+
+ "Ein TEXT mit dem ""-Zeichen"
+ "Ein TEXT-Denoter nur mit dem ""-Zeichen:"
+ """"
+
+ Manchmal sollen Zeichen in einem TEXT-Denoter enthalten sein, die auf dem
+ Eingabegerät nicht zur Verfügung stehen. In diesem Fall kann der Code-
+ Wert des Zeichens angegeben werden:
+
+ ""32""
+
+ bedeutet z.B. das (ASCII-) Leerzeichen. Der Code-Wert eines Zeichens er-
+ gibt sich aus einer Code-Tabelle (installationsspezifisch), in der jedem
+ Zeichen eine ganze Zahl zugeordnet ist.
+
+- BOOL-Denoter:
+ Es gibt nur zwei BOOL-Denoter: TRUE (für "wahr") und FALSE (für "falsch").
+
+Nun wird auch klar, was für Parameter wir in den obigen Programmen verwandt
+haben. Es waren natürlich TEXT- bzw. INT-Denoter.
+
+
+Aufgabe (TSW):
+
+ Welche der folgenden Denotationen ist falsch?
+
+ a) 1. e) 1 . 0 i) 007
+ b) -1 f) "" j) "Ein "Getuem" stellt sich vor"
+ c) """ g) """"
+ d) "das ist ein text" h) TRUE k) 1.0 e 37
+
+Übungsziel: Lernen von Denotationen
+
+
+
+ELAN-Datenobjekte
+
+Wie bereits erwähnt, wollen wir mit Hilfe von Programmen Datenobjekte so
+verändern, daß wir erwünschte Ergebnisse erhalten. Meist wird zu dieser Ver-
+änderung von Datenobjekten "Rechnen" gesagt, obwohl - wie wir gleich sehen
+werden - nicht nur numerische Objekte manipuliert werden. Die Veränderung
+der Datenobjekte findet zur "Laufzeit" (nicht zur Übersetzungszeit) im
+Rechner statt. Die Darstellung eines Werts in einem Rechner zur Laufzeit
+eines Programms wird #ib#Repräsentation#ie# genannt. Wenn es eindeutig ist,
+daß es sich nur um die Repräsentation im Rechner handelt, sprechen wir kurz
+von Werten.
+Da also ein Datenobjekt wechselnde Werte annehmen kann, brauchen wir eine
+Möglichkeit, es in einem Programm anzusprechen, egal welchen Wert das Objekt
+zu einem Zeitpunkt beinhaltet. Zu diesem Zweck können wir einem Datenobjekt
+einen Namen geben (wie z.B. einen Personennamen, hinter dem sich eine wirk­
+liche Person "verbirgt"). Wenn wir also den Namen des Datenobjekts in ein
+Programm schreiben, dann meinen wir (meist) den Wert des Datenobjekts, den
+es zu diesem Zeitpunkt besitzt.
+
+Nun sollen die zu behandelnden Datenobjekte ja auch neue Werte erhalten. In
+diesem Fall müssen wir die Speicherstelle finden, in die der neue Wert ge-
+bracht werden soll. Für diesen Zweck benutzen wir ebenfalls den Namen, zu-
+sätzlich zu der Angabe einer Operation, durch die das Objekt einen neuen
+Wert erhalten soll. Diese Operation (Wert "schreiben") nennen wir Zuweisung.
+Der Zuweisungs-Befehl wird ':=' geschrieben. Beispiel:
+
+ a := 5
+
+Bedeutet, daß das Datenobjekt mit dem Namen 'a' den Wert '5' erhält.
+
+Von manchen Datenobjekten wissen wir, daß wir ihnen nur einmal einen Wert
+geben wollen. Sie sollen also nicht verändert werden. Oder wir wissen, daß
+in einem Programmbereich ein Datenobjekt nicht verändert werden soll. Um ein
+unbeabsichtigtes Verändern zu verhindern, wird in ELAN dem Namen eines
+Datenobjekts ein zusätzlicher Schutz mitgegeben: das Zugriffsrecht oder
+Accessrecht. Es besteht aus der Angabe der Worte VAR (für Lesen und Ver-
+ändern) oder CONST (für ausschließliches Lesen).
+
+
+
+Die Deklaration (Vereinbarung) von Datenobjekten
+
+Wollen wir ein Datenobjekt in einem Programm verwenden, so müssen wir dem
+Übersetzer mitteilen, welchen Datentyp und welches Accessrecht das Objekt
+haben soll. Das dient u.a. dazu, nicht vereinbarte Namen (z.B. verschriebene)
+vom Übersetzer entdecken zu lassen. Weiterhin ist aus dem bei der Deklaration
+angegebenen Datentyp zu entnehmen, wieviel Speicherplatz für das Objekt zur
+Laufzeit zu reservieren ist. Beispiel:
+
+INT VAR mein datenobjekt
+
+Zuerst wird der Datentyp, dann das Accessrecht und schließlich der Name des
+Datenobjekts angegeben. Wie werden nun Namen in ELAN formuliert?
+
+Das erste Zeichen eines Namens muß immer ein kleiner Buchstabe sein. Danach
+dürfen beliebig viele kleine Buchstaben, aber auch Ziffern folgen. Zur bes-
+seren Lesbarkeit können (wie bei den obigen Prozedurnamen) Leerzeichen in
+einem Namen erscheinen, die aber nicht zum Namen zählen. Beispiele:
+
+ name1
+ n a m e 1
+ x27
+ gehalts konto
+ das ist ein langer name
+
+Verschiedene Datenobjekte mit gleichem Datentyp und Accessrecht dürfen in
+einer Deklaration angegeben werden (durch Kommata trennen). Mehrere Dekla-
+rationen werden - genauso wie Anweisungen - durch das Trennsymbol
+voneinander getrennt. Beispiele:
+
+ INT VAR mein wert, dein wert, unser wert;
+ BOOL VAR listen ende;
+ TEXT VAR zeile, wort
+
+
+
+Die Initialisierung von Datenobjekten
+
+Um mit den so vereinbarten Datenobjekten arbeiten zu können, muß man ihnen
+eine Wert geben. Hat ein Datenobjekt noch keinen Wert erhalten, so sagt man,
+sein Wert sei undefiniert. Das versehentliche Arbeiten mit undefinierten
+Werten ist eine beliebte Fehlerquelle. Deshalb wird von Programmierern
+streng darauf geachtet, diese Fehlerquelle zu vermeiden. Eine Wertgebung an
+ein Datenobjekt kann (muß aber nicht) bereits bei der Deklaration erfolgen,
+was man in ELAN Initialisierung nennt. Beispiele:
+
+ INT CONST gewuenschtes gehalt :: 12 000;
+ TEXT VAR zeile :: "";
+ REAL CONST pi :: 3.14159;
+ BOOL VAR bereits sortiert :: TRUE
+
+Allerdings: für mit CONST vereinbarte Datenobjekte ist die Initialisierung
+die einzige Möglichkeit, ihnen einen Wert zu geben.
+
+Die Initialisierung erfolgt mit Hilfe des '::'-Symbols. Anschließend folgt
+der Wert, den das Datenobjekt erhalten soll. (In den Beispielen haben wir
+nur Denoter geschrieben. Es sind aber auch allgemeinere Ausdrücke erlaubt.).
+Es ist nun möglich, mit der oben erwähnten 'put'-Prozedur auch den Wert von
+Datenobjekten ausgeben zu lassen.
+
+
+Programm 5:
+
+ INT VAR nummer :: 5;
+ TEXT CONST bemerkung :: ".Programm";
+ put (nummer);
+ put (bemerkung)
+
+Beachte dabei, daß bei der Aufführung eines Namens in diesem Fall immer der
+Wert des Datenobjekts gemeint ist. Auch die 'put'-Prozedur druckt nicht etwa
+den Namen des Datenobjekts oder die Adresse der Speicherstelle, sondern
+ebenfalls den Wert.
+
+
+Aufgabe (HSG):
+
+ Welche Aufgabe erfüllen Deklarationen? Was heißt: "Eine Variable hat
+ einen undefinierten Wert"? Was ist eine Initialisierung? Was ist ein
+ CONST-Datenobjekt? Warum müssen CONST-Datenobjekte initialisiert
+ werden?
+Übungsziel: Verständnis von Deklarationen und Accessrecht
+
+
+
+Schlüsselworte
+
+Einige Worte haben in ELAN eine feste Bedeutung und können somit nicht -
+wie etwa Namen - frei gewählt werden. Solche Worte werden bei den meisten
+ELAN-Übersetzern mit großen Buchstaben geschrieben, wie z.B. VAR, CONST,
+INT oder REAL u.a.m. Wie wir später sehen werden, besteht die Möglichkeit,
+neue Schlüsselworte einzuführen. Halten wir vorläufig fest, daß feste
+Bestandteile der Sprache (wie z.B. CONST oder VAR) und Datentypen (wie INT
+oder REAL) Schlüsselworte sind, also mit großen Buchstaben geschrieben
+werden.
+
+
+
+Ausdrücke
+
+Nun wäre es natürlich schlecht, wenn Programmierer nicht mehr machen könnten,
+als Werte ausgeben. Als erste Stufe von etwas komplexeren "Rechnungen"
+dürfen Ausdrücke gebildet werden. Ausdrücke sind eine Zusammenstellung von
+Datenobjekten (Denoter, VAR- oder CONST-Objekte) und Operatoren. Schauen wir
+uns dazu erst ein Programm an:
+
+
+Programm 6:
+
+ INT CONST wert 1 :: 1,
+ wert 2 :: 2,
+ wert 3 :: 3;
+
+ put (wert1 + wert2);
+ put (wert2 - wert1);
+ put (wert2 * wert3);
+ put (wert3 DIV wert2);
+ put (wert2 ** wert3)
+
+In diesem Programm werden drei Datenobjekte initialisiert. Anschließend
+werden jeweils die Werte von zwei Objekten addiert (Operatorzeichen: '+'),
+subtrahiert ('-'), multipliziert ('*'), dividiert (ganzzahlige Division ohne
+Rest: 'DIV') und potenziert ('**'). Dies sind Operatoren, die zwei Operanden
+haben: man nennt sie dyadische Operatoren. Die monadischen Operatoren da-
+gegen haben nur einen Operanden. Beispiel:
+
+ put ( - wert1)
+
+Operatoren in ELAN werden - wie wir an den obigen Beispielen sehen - durch
+ein oder zwei spezielle Zeichen oder durch große Buchstaben (in den Fällen,
+in denen kein "vernünftiges" Zeichen mehr zur Verfügung steht) als Schlüssel-
+wort dargestellt.
+
+Als Operanden (also die Datenobjekte, auf die ein Operator "wirken" soll)
+eines Operators darf ein VAR- oder CONST-Datenobjekt, aber auch ein Denoter
+verwendet werden. Das Resultat eines Operators (also das Ergebnis einer
+Berechnung) ist bei den obigen Ausdrücken wieder vom Datentyp INT mit dem
+Accessrecht CONST. Darum ist es erlaubt, solch einen Ausdruck wiederum als
+Operanden zu verwenden. Praktisch bedeutet dies, daß wir mehrere Operatoren
+und Datenobjekte zusammen in einem Ausdruck haben dürfen.
+
+
+Programm 7:
+
+ INT CONST wert 1 :: 1,
+ wert 2 :: 2,
+ wert 3 :: 3;
+
+ put (wert2 + 3 - wert2 * wert3);
+ put (- wert2 * wert3)
+
+Nun haben wir eine Schwierigkeit: Der Ausdruck in der ersten 'put'-Anweisung
+ist mehrdeutig, d.h. kann - je nach Reihenfolge der Auswertung - unter-
+schiedliche Ergebnisse als Resultat liefern. Beispiel:
+
+ a) (wert2 + 3 = 5) - (wert2 * wert3 = 6) = -1
+ b) ((wert2 + 3 = 5) - wert2 = 3) * 3 = 9
+
+Es kommt also auf die Reihenfolge der Auswertung von Operatoren an. Diese
+kann man durch die Angabe von Klammern steuern. Beispiel:
+
+ (a + b) * (a + b)
+
+Es wird jeweils erst 'a + b' ausgewertet und dann erst die Multiplikation
+durchgeführt. In ELAN ist es erlaubt, beliebig viel Klammernpaare zu ver-
+wenden (Regel: die innerste Klammer wird zuerst ausgeführt). Es ist sogar
+zulässig, Klammern zu verwenden, wo keine notwendig sind, denn überflüssige
+Klammernpaare werden überlesen. Beispiel:
+
+ ((a - b)) * 3 * ((c + d) * (c - d))
+
+Somit können wir beliebig komplizierte Ausdrücke formulieren. (Was man aber
+vermeiden sollte, weil sie leicht zu Fehlern führen. Stattdessen kann man
+einen komplizierten Ausdrücke in mehrere (einfachere) zerlegen.)
+
+Um solche Ausdrücke einfacher zu behandeln und sie so ähnlich schreiben zu
+können, wie man es in der Mathematik gewohnt ist, wird in Programmiersprachen
+die Reihenfolge der Auswertung von Operatoren festgelegt. In ELAN wurden
+neun Ebenen, Prioritäten genannt, festgelegt:
+
+
+Priorität Operatoren
+
+ 9 alle monadischen Operatoren
+ 8 **
+ 7 *, /, DIV, MOD
+ 6 +, -
+ 5 =, <>, <, <=, >, >=
+ 4 AND
+ 3 OR
+ 2 alle übrigen, nicht in dieser Tabelle aufgeführten
+ dyadischen Operatoren
+ 1 :=
+
+
+(Die bis jetzt noch nicht erwähnten Operatoren in der Tabelle werden wir in
+den weiteren Abschnitten besprechen.)
+
+Operatoren mit der höchsten Priorität werden zuerst ausgeführt, dann die mit
+der nächst höheren Priorität usw. Operatoren mit gleicher Priorität werden
+von links nach rechts ausgeführt. Dadurch ergibt sich die gewohnte Abarbei-
+tungsfolge wie beim Rechnen. Beispiel:
+
+ -2 + 3 * 2 ** 3
+
+ a) -2
+ b) 2 ** 3
+ c) 3 * (2 ** 3)
+ d) ((-2)) + (3 * (2 ** 3))
+
+Wie bereits erwähnt, ist es immer erlaubt, Klammern zu setzen. Ist man sich
+also über die genaue Abarbeitungsfolge nicht im Klaren, so kann man Klammern
+verwenden.
+
+
+Aufgabe (HSG):
+
+ Welche INT-Werte ergeben sich?
+
+ a) 14 DIV 4 e) -14 DIV -4
+ b) + 14 DIV 4 f) 2 * 3 DIV 2 ** 2 * 4
+ c) -14 DIV 4 g) 2 ** 3 ** 4
+ d) 14 DIV -4 h) 3 + 4 * 2 + 3
+
+Übungsziel: Arithmetische Ausdrücke
+
+
+Aufgabe (HSG):
+
+ Bilden Sie für folgende mathematische Formeln entsprechende ELAN-
+ Ausdrücke:
+
+ a b a+b
+ a) - c d) a g) - ---
+ b c
+
+
+ a+b b a c
+ b) --- e) -a h) - * -
+ c+d b d
+
+
+ a+b -b c
+ c) --- e f) a i) (a*b)
+ c+d
+
+Übungsziel: Arithmetische Ausdrücke formulieren
+
+
+
+Generische Operatoren und Prozeduren
+
+Bis jetzt wurden nur Ausdrücke mit INT-Operanden verwendet. Wie sieht es
+jetzt mit REALs aus?
+
+
+Programm 8:
+
+ put (1.0 + 2.0);
+ put (2.0 - 1.0);
+ put (2.0 * 3.0);
+ put (3.0 / 2.0);
+ put (2.0 ** 3.0)
+
+Man beachte die Unterschiede zum Programm 7: Wir müssen nun REAL-Denoter
+verwenden (mit INT-Denotern zu arbeiten wäre ein Fehler). Der Divisions-
+Operator hat sich nun von 'DIV' zu '/' gewandelt. Die Ergebnisse sind nun
+nicht INT-, sondern REAL-Werte. Für die Reihenfolge der Auswertung der
+Operatoren sowie die Verwendung von Klammern gilt das für INT-Ausdrücke
+gesagte.
+
+Wir haben den '+'-Operator in zwei verschiedenen Formen gesehen: in Programm
+7 mit Operanden vom Datentyp INT, ein INT-Resultat liefernd, und in Programm
+8 das gleiche mit REALs. Es liegen also zwei verschiedene Operatoren vor,
+die aber den gleichen Namen (Zeichen: '+') haben.
+
+In ELAN ist es somit möglich, unterschiedlichen Operatoren (aber auch Proze-
+duren) gleiche Namen zu geben. Solche Operatoren werden generische Opera-
+toren genannt. Ein ELAN-Compiler wählt den richtigen Operator aufgrund der
+Datentypen der Operanden aus. Oft werden die verfügbaren Operatoren wie folgt
+dokumentiert:
+
+ INT OP + (INT CONST links, rechts)
+
+Diese Form nennt man einen "Operator-Kopf". Sie wird in ELAN-Programmen bei
+der Definition von Operatoren benötigt. Dabei steht OP für "OPERATOR". Die
+Angabe des Datentyps davor gibt den Datentyp des Resultats des Operators an.
+Zwischen 'OP' und der öffnenden Klammer steht der Name des Operators (hier:
+'+'). In den Klammern werden die Datentypen und das Accessrecht der
+Operanden angegeben. CONST bedeutet hier: der Operand darf vom Operator
+nicht verändert werden, während bei VAR (was normalerweise ja nicht sein
+sollte!) ein Operand bei der Abarbeitung eines Operators verändert werden
+kann.
+
+Damit wir solche Definitionen besser beherrschen, geben wir noch weitere
+Beispiele an:
+
+ INT OP - (INT CONST operand)
+ REAL OP / (INT CONST l, r)
+
+Bei dem ersten Operator handelt es sich um den monadischen Operator '-' für
+INT-Operanden (z.B.: 'INT VAR a :: 1; put (-a)'), während es sich bei dem
+zweiten Operator um eine Divisions-Operator handelt, der jedoch ein REAL-
+Resultat liefert (z.B.: 'put (3 / 2)' liefert 1.5). Der MOD-Operator liefert
+den Rest einer Division:
+
+ INT OP MOD (INT CONST l, r)
+ REAL OP MOD (REAL CONST l, r)
+
+Die Beschreibung von generischen Prozeduren verläuft analog. Beispiele:
+
+ PROC put (INT CONST wert)
+ PROC put (REAL CONST wert)
+
+Hier wird das Wort 'OP' durch 'PROC' (für 'PROCEDURE') ersetzt. Die Angaben
+in Klammern bezeichnen nun nicht Operanden, sondern Parameter.
+
+Über die verfügbaren Operatoren und Prozeduren für INT- und REAL-Datenob-
+jekte kann man sich im ELAN-Handbuch oder im EUMEL-Benutzerhandbuch infor-
+mieren. Einige - aber nicht alle - der Operatoren und Prozeduren (auch für
+andere Datentypen) werden wir erklären, wenn wir sie in Programmen benötigen.
+
+
+
+Die Zuweisung
+
+Ein spezieller Operator ist die Zuweisung (Zeichen: ':='). Dieser Operator
+hat immer die geringste Priorität, wird also immer als letzter eines Aus-
+drucks ausgeführt. Die Zuweisung wird verwendet, um einer Variablen einen
+neuen Wert zu geben. Beispiel:
+
+ a := b
+
+Hier wird der Wert von 'b' der Variablen 'a' zugewiesen. Der vorher vor-
+handene Wert von 'a' geht dabei verloren. Man sagt auch, der Wert wird über-
+schrieben. Auf der rechten Seite (also als rechter Operand) des ':='
+Operators darf auch ein Ausdruck stehen. Beispiel:
+
+ a := b + c
+
+Hier wird das Resultat von 'b + c' an die Variable 'a' zugewiesen. Man be-
+achte dabei die Prioritäten der Operatoren '+' (Priorität 6) und ':=' (Pri-
+orität 1): die Addition wird vor der Zuweisung ausgeführt. Die Auswertung
+von Zuweisungen mit Ausdrücken muß immer so verlaufen, da die Zuweisung
+stets die niedrigste Priorität aller Operatoren hat.
+
+Schauen wir uns zum besseren Verständnis die Definitionen des (natürlich
+auch generischen) Operators ':=' an:
+
+ OP := (INT VAR ziel, INT CONST quelle)
+ OP := (REAL VAR ziel, REAL CONST quelle)
+ OP := (TEXT VAR ziel, TEXT CONST quelle)
+ OP := (BOOL VAR ziel, BOOL CONST quelle)
+
+Der Operator ':=' liefert also kein Resultat (man sagt auch, er liefert
+keinen Wert) und verlangt als linken Operanden ein VAR-Datenobjekt (an den
+der Wert der rechten Seite zugewiesen werden soll). Der Wert des linken
+Operanden wird also verändert. Für den rechten Operanden ist durch CONST
+sichergestellt, daß er nur gelesen wird.
+
+Oft kommt es vor, daß ein Objekt auf der linken und rechten Seite des Zuwei-
+sungsoperators erscheint, z.B. wenn ein Wert erhöht werden soll. Beispiele:
+
+ a := a + 1;
+ a := a + 17
+
+Hier wird der "alte", aktuelle Wert von 'a' genommen, um '1' erhöht und dem
+Objekt 'a' zugewiesen. Man beachte, daß hier in einer Anweisung ein Datenob-
+jekt unterschiedliche Werte zu unterschiedlichen Zeitpunkten haben kann.
+
+In solchen Fällen darf man den Operator INCR verwenden:
+
+ a INCR 1;
+ a INCR 17
+
+Analoges gilt für den Operator DECR, bei dem ein Wert von einer Variable
+subtrahiert wird. Also:
+
+ OP INCR (INT VAR ziel, INT CONST dazu)
+ OP INCR (REAL VAR ziel, REAL CONST dazu)
+
+ OP DECR (INT VAR ziel, INT CONST abzug)
+ OP DECR (REAL VAR ziel, REAL CONST abzug)
+
+Schauen wir uns folgendes Programm an, bei dem zwei Werte vertauscht werden:
+
+
+Programm 9:
+
+ INT VAR a, b, x;
+
+ get (a);
+ get (b);
+ x := a;
+ a := b;
+ b := x;
+ put (a);
+ put (b)
+
+Wie wir an diesem Beispiel sehen, existieren nicht nur 'put'-Prozeduren,
+sondern auch 'get'-Prozeduren, die einen Wert vom Eingabemedium einlesen.
+Es gibt folgende 'get'- Prozeduren (die 'put'-Prozeduren führen wir der
+Vollständigkeit halber auch mit auf):
+
+ PROC get (INT VAR wert)
+ PROC get (REAL VAR wert)
+ PROC get (TEXT VAR wert)
+
+ PROC put (INT CONST wert)
+ PROC put (REAL CONST wert)
+ PROC put (TEXT CONST wert)
+
+
+Aufgabe (HSG):
+
+ Was versteht man unter Generizität?
+ Übungsziel: Generizitäts-Begriff
+
+
+
+Refinements
+
+Bevor wir die Operationen für TEXTe und BOOLs besprechen, wollen wir eine
+weitere wichtige Eigenschaft von ELAN diskutieren, nämlich die Namensgebung.
+Namen für Datenobjekte haben wir bereits kennengelernt. In ELAN ist es eben-
+falls möglich, Namen für Ausdrücke oder eine bzw. mehrere Anweisungen zu
+vergeben.
+
+
+Programm 10:
+
+ INT VAR a, b, x;
+ einlesen von a und b;
+ vertauschen von a und b;
+ vertauschte werte ausgeben.
+
+ einlesen von a und b:
+ get (a);
+ get (b).
+
+ vertauschen von a und b:
+ x := a;
+ a := b;
+ b := x.
+
+ vertauschte werte ausgeben:
+ put (a);
+ put (b).
+
+Dies ist das gleiche Programm wie das 9. Beispielprogramm. Für den Namen
+'einlesen von a und b' werden die Anweisungen 'get (a); get (b)' vom
+ELAN-Übersetzer eingesetzt. Man kann also die ersten vier Zeilen des
+Programms als eigentliches Programm ansehen, wobei die Namen durch die
+betreffenden Anweisungen ersetzt werden. Eine solche Konstruktion wird in
+ELAN Refinement genannt. Was wird dadurch erreicht?
+
+Durch die sinnvolle Verwendung von Refinements wird ein Programm im Programm
+und nicht in einer separaten Beschreibung dokumentiert. Weiterhin kann ein
+Programm "von oben nach unten" ("top down") entwickelt werden: wir haben das
+obige - zugegeben einfache - Beispielprogramm in drei Teile zerlegt und
+diese durch Namen beschrieben. Bei der Beschreibung von Aktionen durch Namen
+sagen wir, was wir machen wollen und nicht wie, denn wir brauchen uns auf
+dieser Stufe der Programmentwicklung um die Realisierung der Refinements
+(noch) keine Sorgen zu machen. Das erfolgt erst, wenn wir genauer definieren
+müssen, wie das Refinement programmiert werden muß. Dabei können wir
+wiederum Refinements verwenden usw., bis wir auf eine Ebene "herunterge-
+stiegen" sind, bei dem eine (jetzt: Teil-) Problemlösung sehr einfach ist
+und wir sie direkt hinschreiben können. Wir beschäftigen uns also an jedem
+Punkt der Problemlösung nur mit einem Teilaspekt des gesamten Problems.
+Zudem sieht man - wenn die Refinements einigermaßen vernünftig verwendet
+werden - dem Programm an, wie die Problemlösung entstanden ist.
+
+Die Verwendung von Refinements hat also eine Anzahl von Vorteilen. Schauen
+wir uns deshalb an, wie die Refinements formal verwandt werden müssen. Das
+"Hauptprogramm" wird durch einen Punkt abgeschlossen, falls ein Refinement
+folgt. Ein Refinement besteht aus der Nennung des Refinement-Namens, der
+von einem Doppelpunkt gefolgt sein muß. In einem Refinement kann eine
+Anweisung oder mehrere - durch Semikolon getrennt - stehen. Das Refinement
+wird durch einen Punkt abgeschlossen.
+
+Refinements können auch dort verwendet werden, wo ein Wert erwartet wird,
+z.B. in einem Ausdruck oder einer 'put'-Anweisung. In diesem Fall muß das
+Refinement natürlich einen Wert liefern. Wie macht man das? Eine Möglichkeit
+ist, daß im Refinement ein Ausdruck geschrieben wird, der einen Wert als
+Resultat liefert.
+
+
+Programm 11:
+
+ INT VAR a :: 1, b :: 2, c :: 3;
+ put (resultat).
+
+ resultat:
+ (a * b + c) ** 3.
+
+Eine Zuweisung liefert - wie bereits erwähnt - kein Resultat. Es ist auch
+erlaubt, ein Refinement mit mehreren Anweisungen zu schreiben, das einen Wert
+liefert. Allgemeine Regel: die letzte Anweisung eines Refinements bestimmt,
+ob ein Refinement einen Wert liefert - und wenn ja, von welchen Datentyp.
+
+
+
+BOOLesche Operationen
+
+Für BOOLesche Datenobjekte gibt es einige Operatoren:
+
+ BOOL OP AND (BOOL CONST links, rechts)
+ BOOL OP OR (BOOL CONST links, rechts)
+ BOOL OP NOT (BOOL CONST operand)
+
+Der Operator AND liefert als Resultat die logische "und"-Verknüpfung (nur
+wenn beide Operanden den Wert TRUE haben ist das Resultat TRUE, sonst FALSE),
+OR ist das logische "oder" (nur wenn beide Operanden FALSE liefern, ist das
+Resultat FALSE, sonst TRUE) und die logische Negation NOT (als Resultat wird
+das "Gegenteil" geliefert).
+
+Ebenfalls wichtig sind die Vergleichs-Operatoren, die zwar keine BOOLeschen
+Operanden erwarten, aber ein BOOLesches Resultat liefern:
+
+ BOOL OP = (INT CONST links, rechts)
+ BOOL OP <> (INT CONST links, rechts)
+ BOOL OP < (INT CONST links, rechts)
+ BOOL OP <= (INT CONST links, rechts)
+ BOOL OP > (INT CONST links, rechts)
+ BOOL OP >= (INT CONST links, rechts)
+
+Diese Operatoren: = (gleich), <> (ungleich), < (kleiner), <= (kleiner
+gleich), > (größer), >= (größer gleich) gibt es auch noch für Operanden vom
+Datentyp REAL und TEXT. Da die Vergleichs-Operatoren ein BOOLesches Resultat
+liefern, kann man sie in BOOLeschen Ausdrücken verwenden. Zu beachten ist
+dabei die Priorität der Operatoren: die Vergleiche werden immer vor den
+Operatoren AND bzw. OR ausgeführt.
+
+
+Programm 12:
+
+ BOOL CONST kaufen;
+ kaufen := will ich AND NOT zu teuer.
+
+ will ich:
+ TEXT VAR produktname;
+ get (produktname);
+ produktname = "muesli" OR produktname = "vollkornbrot".
+
+ zu teuer:
+ INT VAR preis;
+ get (preis);
+ preis > 20.
+
+
+
+Aufgabe (HSG):
+
+ Welche BOOL-Werte ergeben sich?
+
+ a) TRUE AND FALSE e) TRUE AND TRUE OR TRUE
+ b) TRUE OR FALSE f) 10 < 3 AND 17 > 4
+ c) TRUE AND NOT FALSE g) 17 + 4 = 21 OR TRUE
+ d) NOT TRUE AND FALSE h) TRUE AND FALSE OR TRUE
+
+ Übungsziel: Boolesche Ausdrücke
+
+
+
+Abfragen
+
+BOOLesche Ausdrücke werden in einer speziellen Anweisung verwandt, der
+Abfrage:
+
+
+Programm 13:
+
+ INT VAR a, b;
+ get (a); get (b);
+ IF a > b
+ THEN vertausche a und b
+ END IF;
+ put (a); put (b).
+
+ vertausche a und b:
+ INT CONST x :: a;
+ a := b;
+ b := x.
+
+Das Refinement im THEN-Teil der bedingten Anweisung wird nur durchgeführt,
+wenn der BOOLesche Ausdruck ('a > b') den Wert TRUE liefert. Liefert er den
+Wert FALSE, wird die Anweisung, die der bedingten Anweisung folgt (nach END
+IF), ausgeführt. Programm 13 kann etwas anders geschrieben werden:
+
+
+Programm 14:
+
+ INT VAR a, b;
+ get (a); get (b);
+ IF a > b
+ THEN put (a);
+ put (b)
+ ELSE put (b);
+ put (a)
+ END IF.
+
+Der THEN-Teil wird wiederum ausgeführt, wenn die BOOLesche Bedingung
+erfüllt ist. Liefert sie dagegen FALSE, wird der ELSE-Teil ausgeführt.
+
+Die bedingte Anweisung gibt uns also die Möglichkeit, abhängig von einer
+Bedingung eine oder mehrere Anweisungen ausführen zu lassen. Dabei können
+im THEN- bzw. ELSE-Teil wiederum bedingte Anweisungen enthalten sein usw.
+Solche geschachtelten bedingten Anweisungen sollte man jedoch vermeiden,
+weil sie leicht zu Fehlern führen können (statt dessen durch Refinements
+realisieren). Man beachte auch die Einrückungen, die man machen sollte, um
+die "Zweige" besonders kenntlich zu machen.
+
+
+Aufgabe (HSG):
+
+ a) In welcher Reihenfolge werden Operatoren ausgewertet?
+ b) Reihenfolge der Auswertung von: a + b + c
+ c) INT VAR a, b, c;
+ ...
+ IF NOT a = 0 AND b = 0 THEN...
+ ergibt einen syntaktischen Fehler. Welchen?
+ d) Wie wird der BOOLesche Ausdruck ausgewertet?
+ INT VAR a :: 0, b :: 4;
+ ...
+ IF a = 0 AND b DIV a > 0
+ e) Warum ist
+ BOOL VAR ende :: TRUE;
+ ...
+ IF ende = TRUE
+ THEN...
+ Unsinn?
+
+ Übungsziel: Reihenfolge der Auswertung von Ausdrücken
+
+Bei Abfrageketten kann das ELIF-Konstrukt eingesetzt werden. (ELIF ist eine
+Zusammenziehung der Worte ELSE und IF). Anstatt
+
+ ...
+ IF bedingung1
+ THEN aktion1
+ ELSE IF bedingung2
+ THEN aktion2
+ ELSE aktion3
+ END IF
+ END IF;
+ ...
+
+kann man besser
+
+ ...
+ IF bedingung1
+ THEN aktion1
+ ELIF bedingung2
+ THEN aktion2
+ ELSE aktion3 END IF;
+ ...
+
+schreiben.
+
+Die bedingte Anweisung kann auch einen Wert liefern. In diesem Fall muß der
+ELSE-Teil vorhanden sein und jeder Zweig den gleichen Datentyp liefern
+(jeweils die letzte Anweisung muß einen Wert liefern).
+
+
+Aufgabe (HSG):
+
+ Was berechnen folgende (Teil-) Programme?
+
+ a) INT VAR a;
+ get (a);
+ put (wert).
+
+ wert:
+ IF a < 0
+ THEN -a
+ ELSE a
+ END IF.
+
+ b) INT VAR brutto, netto;
+ get (brutto);
+ berechne gehalt;
+ put ("mein gehalt:");
+ put (netto).
+
+ berechne gehalt:
+ IF jahresverdienst > 30 000 (* zu wenig? *)
+ THEN sonderabgabe
+ END IF;
+ netto := brutto - brutto DIV 100 * 20.
+
+ jahresverdienst:
+ brutto * 12.
+
+ sonderabgabe:
+ brutto := brutto - brutto DIV 100 * 30
+
+ c) INT VAR x;
+ ...
+ put (signum).
+
+ signum:
+ IF x > 0
+ THEN 1
+ ELSE kleiner gleich
+ END IF.
+
+ kleiner gleich:
+ IF x = 0
+ THEN 0
+ ELSE -1
+ END IF.
+
+
+
+TEXTe
+
+TEXT-Denoter haben wir bereits kennengelernt. Im folgenden Programm stellen
+wir die Wirkung einiger TEXT-Operationen vor.
+
+
+Programm 15:
+
+ TEXT VAR a, b, c;
+ a := "ELAN";
+ b := "-Programm";
+ c := a + b;
+ put (c)
+
+Der Operator
+
+ TEXT OP + (TEXT CONST links, rechts)
+
+liefert als Ergebnis einen TEXT, bei dem an den linken der rechte Operand
+angefügt wurde (Fachausdruck: "Konkatenation"). Weitere Operatoren:
+
+ TEXT OP CAT (TEXT VAR ziel, TEXT CONST dazu)
+ TEXT OP * (INT CONST i, TEXT CONST a)
+ TEXT OP SUB (TEXT CONST t, INT CONST pos)
+
+Der Operator CAT fügt an einen TEXT einen zweiten an ('a CAT b' wirkt wie
+'a := a + b'). Mit dem '*'-Operator kann man einen TEXT vervielfältigen
+(Beispiel: 17 * "--"), während man mit SUB ein Zeichen aus einem TEXT her-
+ausholen kann (Beispiel: "ELAN" SUB 3 liefert "A").
+
+Die meisten TEXT-Operationen sind als Prozeduren realisiert, weil mehr als
+zwei Operanden benötigt werden. Die Wirkung einiger Operationen geben wir in
+kurzen Kommentaren an:
+
+ TEXT PROC subtext (TEXT CONST t, INT CONST von)
+ (* rechter Teiltext von 't' von der Position 'von' bis Ende *)
+
+ TEXT PROC subtext (TEXT CONST t, INT CONST von, bis)
+ (* Teiltext von 't' von der Position 'von' bis 'bis' *)
+
+ PROC change (TEXT VAR t, TEXT CONST old, new)
+ (* Ersetzung von 'old' in 'new' im TEXT 't' *)
+
+ INT PROC length (TEXT CONST t)
+ (* Anzahl Zeichen von 't' *)
+
+ INT PROC pos (TEXT CONST t, muster)
+ (* Die Position des ersten Auftretens von 'muster' in 't' *)
+
+Die Vergleichs-Operatoren für TEXTe arbeiten bei dem Vergleich nach der
+alphabetischen Reihenfolge ('"a" < "b"' liefert TRUE). Dabei definiert ELAN
+nur die Reihenfolge innerhalb der kleinen und großen Buchstaben und Ziffern.
+Das Leerzeichen ("#ib#blank#ie#") ist jedoch stets das "kleinste" Zeichen.
+Wie diese "Zeichenblöcke" und die restlichen Zeichen angeordnet sind, wurde
+nicht spezifiziert. Ob '"a" < "Z"' TRUE oder FALSE liefert, wurde also nicht
+festgelegt und ist somit rechnerspezifisch. Anmerkung: Im EUMEL-Betriebs-
+system wird der ASCII-Zeichencode, DIN 66 003 mit Erweiterungen verwandt.
+Die folgenden Vergleiche sind alle TRUE:
+
+ "otto" = "otto"
+ "a" < "z"
+ "Adam" < "Eva"
+ "hallo" < "hallu"
+ "hallo" < "hallo "
+ length ("ha") = 2
+ subtext ("ELAN-Programmierung", 14) = "ierung"
+
+
+Aufgabe (HSG):
+
+ Gib die Realisierung von folgenden vorgegebenen Prozeduren und Opera-
+ toren an:
+ a) TEXT PROC subtext (TEXT CONST t, INT CONST von) durch
+ TEXT PROC subtext (TEXT CONST t, INT CONST von, bis)
+ b) OP CAT (TEXT VAR a, TEXT CONST b) durch ':=' und '+'
+ c) TEXT OP SUB (TEXT CONST t, INT CONST p) durch 'subtext'
+
+ Übungsziel: Lernen einiger vorgegebener TEXT-Operationen
+
+
+
+Die Wiederholungs-Anweisung
+
+Wiederholungs-Anweisungen ermöglichen es uns, Anweisungen wiederholt - meist
+in Abhängigkeit von einer Bedingung - ausführen zu lassen. Darum wird die
+Wiederholungs-Anweisung oft auch #ib#Schleife#ie# genannt, die in ihr ent-
+haltenen Anweisungen #ib#Schleifenrumpf#ie#. Die Schleife von ELAN baut auf
+einem Basis-Konstrukt auf:
+
+ REP
+ anweisungen
+ END REP
+
+Diese Anweisungsfolge realisiert eine sogenannte "Endlosschleife", weil nicht
+spezifiziert wird, wann die Schleife beendet werden soll.
+
+Bei der abweisenden Schleife wird die Abbruchbedingung an den Anfang der
+Schleife geschrieben:
+
+ WHILE boolesche bedingung REP
+ anweisungen
+ END REP
+
+Bei jedem erneuten Durchlauf durch die Schleife wird überprüft, ob der
+BOOLesche Ausdruck den Wert TRUE liefert. Ist das nicht der Fall, wird mit
+der nächsten, auf die Schleife folgenden Anweisung mit der Bearbeitung fort-
+gefahren. Die Schleife wird abweisende Schleife genannt, weil der Schleifen-
+rumpf nicht ausgeführt wird, wenn die Bedingung vor Eintritt in die Schleife
+bereits FALSE liefert.
+
+Anders verhält es bei der nicht abweisenden Schleife:
+
+ REP
+ anweisungen
+ UNTIL boolesche Bedingung END REP
+
+Hier wird der Schleifenrumpf auf jeden Fall einmal bearbeitet. Am Ende des
+Rumpfes wird die BOOLesche Bedingung abgefragt. Liefert diese den Wert FALSE,
+wird die Schleife erneut abgearbeitet. Liefert die Bedingung den Wert TRUE,
+wird die Schleife abgebrochen und mit der ersten Anweisung hinter der
+Schleife in der Bearbeitung fortgefahren.
+
+Bei beiden Arten der Wiederholungs-Anweisung ist es wichtig, daß Elemente
+der BOOLeschen Bedingung in der Schleife verändert werden, damit das
+Programm terminieren kann, d.h. die Schleife abgebrochen wird.
+
+Eine Endlos-Schleife wird bei der Zählschleife meist nicht vorkommen:
+
+ FOR i FROM anfangswert UPTO endwert REP
+ anweisungen
+ END REP
+
+Zählschleifen werden eingesetzt, wenn die genaue Anzahl der Schleifendurch-
+läufe bekannt ist. Hier wird eine Laufvariable verwendet (in unserem Bei-
+spiel 'i': sie muß mit INT VAR deklariert werden), die die INT-Werte von
+'anfangswert' bis 'endwert' in Schritten von '1' durchläuft. Diese Schleife
+zählt "aufwärts". Wird anstatt UPTO das Schlüsselwort DOWNTO verwendet, wird
+mit Schritten von -1 "abwärts" gezählt. Beispiel:
+
+ FOR i FROM endwert DOWNTO anfangswert REP
+ ...
+
+Für ein Beispielprogramm stellen wir uns die Aufgabe, aus TEXTen das Auf-
+treten des Buchstabens "e" herauszufinden. Die TEXTe sollen vom Eingabe-
+medium solange eingelesen werden, bis wir den TEXT "00" eingeben.
+
+
+Programm 16:
+
+ INT VAR anzahl e :: 0;
+ TEXT VAR wort;
+ REP
+ get (wort);
+ zaehle e im wort
+ UNTIL wort = "00" END REP;
+ put (anzahl e).
+
+ zaehle e im wort:
+ INT VAR i;
+ FOR i FROM 1 UPTO length (wort) REP
+ IF das i te zeichen ist e
+ THEN anzahl e INCR 1
+ END IF
+ END REP.
+
+ das i te zeichen ist e:
+ (wort SUB i) = "e".
+
+
+Aufgabe (HSG):
+
+ Die Klammern in dem letzten Refinement sind notwendig. Warum?
+
+Bevor wir ein Programm einem Rechner zur Bearbeitung übergeben, sollten wir
+uns davon überzeugen, daß das Programm wirklich das leistet, was es soll.
+Eine der wichtigsten Bedingungen ist die Terminierung eines Programms, d.h.
+das Programm darf nicht in eine Endlosschleife geraten. Unser Beispielpro-
+gramm terminiert, wenn beide Schleifen terminieren: die obere Schleife
+terminiert durch das Endekriterium, während die zweite Schleife automatisch
+durch die Zählschleife begrenzt wird. Das Programm wird also auf jeden Fall
+beendet (kann in keine Endlosschleife geraten), falls das Endekriterium ein-
+gegeben wird.
+Interessant sind dabei immer "Grenzfälle", wie z.B. die Eingabe eines
+"leeren Textes", sehr lange TEXTe usw.
+
+
+Aufgabe (HSG):
+
+ Welche Fehler befinden sich in den folgenden Programmteilen?
+ a) INT VAR i;
+ FOR i FROM 1 UPTO i REP
+ tue irgendwas
+ END REP
+
+ b) BOOL CONST noch werte :: TRUE;
+ INT VAR i;
+ WHILE noch werte REP
+ get (i);
+ ...
+ IF i = O
+ THEN noch werte := FALSE
+ END IF
+ END REP
+
+ c) INT VAR anz berechnungen :: 1;
+ REP
+ lies eingabe wert;
+ berechnung;
+ drucke ausgabewert
+ UNTIL anz berechnungen > 10 END REP.
+
+ d) INT VAR anz berechnungen;
+ WHILE anz berechnungen <= 10 REP
+ lies eingabewert;
+ berechnung;
+ drucke ausgabewert;
+ anz berechnungen INCR 1
+ END REP.
+
+ e) INT VAR n := 1, summe;
+ summe der ersten 100 zahlen.
+
+ summe der ersten 100 zahlen:
+ WHILE n < 100 REP
+ summe := summe + n;
+ n INCR 1
+ END REP.
+ (* Achtung: 2 Fehler! (Vorwarnen ist feige) *)
+
+ f) INT VAR n := 1;
+ REP
+ INT VAR summe := 0;
+ summe := summe + n;
+ n INCR 1
+ UNTIL n = 100 END REP
+ (* Achtung: 2 Fehler! *)
+
+ Übungsziel: Arbeiten mit Schleifen
+
+
+Das Programm 16 können wir etwas besser formulieren. Dazu wollen wir uns
+aber eine etwas andere Aufgabe stellen: wie viele Leerzeichen sind in einem
+Text? Zur Lösung dieser Aufgabe sollten wir den Text nicht wortweise ein-
+lesen, sondern zeilenweise. Dazu verwenden wir die Prozedur
+
+ PROC get (TEXT VAR t, INT CONST max length)
+
+die einen TEXT 't' mit maximal 'max length' Zeichen einliest. Auf dem
+EUMEL-System gibt es dafür auch die Prozedur 'getline'.
+
+
+Programm 17:
+
+ INT VAR anzahl blanks :: 0;
+ REP
+ lies zeile ein;
+ zaehle blanks
+ UNTIL zeile hat endekriterium END REP.
+
+ lies zeile ein:
+ TEXT VAR zeile;
+ get (zeile, 80).
+
+ zaehle blanks:
+ INT VAR von :: 1;
+ WHILE zeile hat ab von ein blank REP
+ anzahl blanks INCR 1;
+ von auf blank position setzen
+ END REP.
+
+ zeile hat ab von ein blank:
+ pos (zeile, " ", von) > 0.
+
+ von auf blank position setzen:
+ von := pos (zeile, " ", von).
+
+ zeile hat endekriterium:
+ pos (zeile, "00") > 0.
+
+
+Aufgabe (TSW):
+
+ Das Programm 17 enthält (mindestens) zwei Fehler. Finden Sie diese bitte
+ heraus.
+
+ Übungsziel: Finden von Programmierfehlern.
+
+
+Aufgabe (HSG):
+
+ a) Welche Werte liefern folgende Ausdrücke für die Textvariable
+ TEXT VAR t :: "Das ist mein Text"
+ a1) pos (t, "ist")
+ a2) pos (t, "ist", 5)
+ a3) length (t)
+ a4) subtext (t, 14)
+ a5) subtext (t, 14, 17)
+
+ b) Welche Werte liefern folgende Ausdrücke für die Textkonstanten
+ TEXT CONST text :: "ELAN-Programm",
+ alphabet :: "abcde...xyz"
+ b1) 3 * text
+ b2) length ("mein" + text + 3 * "ha")
+ b3) 3 * "ha" < text
+ b4) pos (text, alphabet SUB 1)
+ b5) pos (text, subtext (alphabet, 7, 7))
+
+ c) Schreibe in anderer Form:
+ c1) subtext (text, 7, 7)
+ c2) change (text, "alt", "neu")
+ c3) INT VAR laenge :: length (text);
+ IF subtext (text, laenge, laenge) =...
+ c4) IF NOT (text = "aha")
+ THEN aktion 1
+ ELSE aktion 2
+ END IF
+
+ Übungsziel: TEXT-Ausdrücke und Prozeduren
+
+
+
+Die Repräsentation von Datentypen
+
+Wie bereits erwähnt, sind Datentypen Klassen von Objekten der realen Umwelt.
+Die Objekte eines Datentyps müssen in den Speicher eines Rechners abgebildet
+werden. Die Darstellung eines Objekts im Rechner wird Repräsentation genannt.
+Aus organisatorischen Gründen versucht man, immer feste, gleich große Ein-
+heiten für die Objekte eines Datentyps zu verwenden. Durch die Begrenzung auf
+feste Speicherplatzeinheiten ist der Wertebereich beschränkt. Diese Grenzen
+hat man beim Programmieren zu beachten.
+
+Beim Datentyp BOOL spielt die Repräsentation nur insoweit eine Rolle, daß
+man die zwei möglichen Werte mehr oder weniger speicheraufwendig realisieren
+kann. Eine Einschränkung des Wertebereichs gibt es nicht.
+
+Bei INTs ist jedoch eine Einschränkung des Wertebereichs gegeben. Für die
+Repräsentation von INTs sind Einheiten von 16, 32 Bit u.a.m. gebräuchlich.
+Es existiert die Möglichkeit, den größten INT-Wert mit Hilfe von
+
+ maxint
+
+zu erfragen. Z.B. ist 'maxint' für EUMEL-Systeme z.Zt. 32 767. Der kleinste
+INT-Wert ist oft nicht ' - maxint' (im EUMEL-System kann er unter 'minint'
+angesprochen werden). Übersteigt ein Wert 'maxint', gibt es eine Fehler-
+meldung 'overflow', im andern Fall 'underflow'.
+
+REALs sind noch schwieriger. Durch die endliche Darstellung der Mantisse
+treten "Lücken" zwischen zwei benachbarten REALs auf. Deshalb ist bei Ver-
+wendung von REALs immer mit Repräsentationsfehlern zu rechnen. Dieses Thema
+der "Rundungsfehler" wollen wir hier jedoch nicht weiter vertiefen. Auf
+jeden Fall gibt es aber auch einen größten REAL-Wert
+
+ maxreal
+
+Bei TEXTen gibt es zwei Repräsentations-Schwierigkeiten. Einerseits werden
+TEXTe durch "irgendeinen" Code im Rechner repräsentiert, der z.B. bei Ver-
+gleichen verwendet wird. ELAN-Compiler auf Rechenanlagen mit unterschied-
+lichen Zeichencodes können daher unterschiedliche Ergebnisse liefern.
+Andererseits ist in ELAN nicht definiert, wie viele Zeichen maximal in einen
+TEXT passen, was ebenfalls vom Rechner bzw. von einem ELAN-Compiler abhängt.
+Auf dem EUMEL-System kann die maximale Anzahl Zeichen eines TEXTs durch
+'maxtext length' erfragt werden. Sie ist z.Z. '32 000'.
+
+
+
+Ein- und Ausgabe
+
+Wie Datenobjekte - auf einfache Weise - auf einem Ausgabemedium ausgegeben
+werden können, haben wir bereits geschildert (Prozedur 'put'). Die Ausgabe
+erfolgt solange auf einer Zeile, bis ein auszugebender Wert nicht mehr auf
+eine Zeile paßt. In diesem Fall wird die Ausgabe in die nächste Zeile pla-
+ziert. Zwischen den einzelnen Werten auf einer Zeile wird jeweils ein Blank
+Zwischenraum gelassen, um die Ausgaben voneinander zu trennen. Mit folgenden
+Prozeduren kann man die Ausgabe flexibel gestalten:
+
+ PROC line (* bewirkt einen Zeilenvorschub *)
+
+ PROC line (INT CONST anzahl) (* bewirkt 'anzahl' Zeilenvorschübe *)
+
+ PROC page (* bewirkt einen Seitenvorschub auf
+ einem Drucker oder löscht den Bild-
+ schirm und positioniert in die linke
+ obere Ecke *)
+
+ PROC putline (TEXT CONST zeile) (* gibt 'zeile' auf dem Bildschirm aus
+ und positioniert auf die nächste
+ neue Zeile *)
+
+ PROC cursor (INT CONST reihe, spalte) (* Positioniert die Schreibmarke
+ auf dem Bildschirm in die an-
+ gegebene Position *)
+
+Die Prozedur 'get' holt Eingaben vom Eingabemedium. Ein Element der Eingabe
+wird dabei durch ein Blank vom nächsten getrennt. Einige weitere Eingabe-
+Prozeduren:
+
+ PROC get (TEXT VAR t, TEXT CONST delimiter) (* die nächste Eingabe wird
+ nicht von einem Blank
+ begrenzt, sondern durch
+ 'delimiter' *)
+
+ TEXT PROC get (* dient zum Initialisieren *)
+
+ PROC inchar (TEXT VAR zeichen) (* wartet solange, bis ein Zeichen vom
+ Bildschirm eingegeben wird *)
+
+ TEXT PROC incharety (* Versucht ein Zeichen vom Bildschirm
+ zu lesen. Ist kein Zeichen vor-
+ handen, wird "" geliefert *)
+
+ PROC editget (TEXT VAR line) (* Bei der Eingabe kann 'line' editiert
+ werden *)
+
+ PROC get cursor (INT VAR zeile, spalte) (* Informationsprozedur, wo die
+ Schreibmarke aktuell steht *)
+
+
+
+Konvertierungen
+
+Manchmal ist es notwendig, eine Datentyp-Wandlung für ein Objekt vorzunehmen.
+Die Wandlungen von einem INT- bzw. einen REAL-Wert in einen TEXT und umge-
+kehrt sind relativ unkritisch:
+
+ TEXT PROC text (INT CONST value)
+ TEXT PROC text (REAL CONST value)
+ INT PROC int (TEXT CONST number)
+ REAL PROC real (TEXT CONST number)
+
+Aber bei der folgenden Prozedur 'int' gehen im allgemeinen Fall Informationen
+verloren (es wird abgeschnitten):
+
+ INT PROC int (REAL CONST value)
+ REAL PROC real (INT CONST value)
+
+Zusätzlich steht eine Informationsprozedur 'last conversion ok' zur Ver-
+fügung, die den Wert TRUE liefert, falls die letzte Konversion fehlerfrei
+war:
+
+ BOOL PROC last conversion ok
+
+Solche Abfragen sind notwendig, weil die Konversionsroutinen bei falschen
+Parameterwerten (z.B. 'int (maxreal)') nicht mit einer Fehlermeldung ab-
+brechen. Als Beispiel zeigen wir ein Programm zum Einlesen von Werten, von
+denen man nicht weiß, ob sie INT oder REAL sind. Darum kann auch nicht die
+'get'-Prozedur für INT oder REAL verwandt werden:
+
+
+Programm 18:
+
+ TEXT VAR eingabe element;
+ REP
+ get (eingabe element);
+ wert nach intwert oder realwert bringen;
+ berechnung
+ UNTIL ende ENDREP.
+
+ wert nach intwert oder realwert bringen:
+ IF pos (eingabe element, ".") > 0
+ THEN REAL VAR realwert :: real (eingabe element)
+ ELSE INT VAR intwert :: int (eingabe element)
+ END IF;
+ IF NOT last conversion ok
+ THEN put ("Fehler bei Konvertierung:" + eingabe element);
+ line
+ END IF.
+
+ berechnung:
+ ...
+
+
diff --git a/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil6b b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil6b
new file mode 100644
index 0000000..7fdaf39
--- /dev/null
+++ b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil6b
@@ -0,0 +1,1425 @@
+ EUMEL-Benutzerhandbuch
+
+
+ TEIL 6: Erste Hilfe in ELAN
+
+Prozeduren
+
+Prozeduren werden verwendet, wenn
+
+- Anweisungen und Datenobjekte unter einem Namen zusammengefaßt werden
+ sollen ("Abstraktion").
+
+- gleiche Anweisungen von mehreren Stellen eines Programms verwandt werden
+ sollen (Codereduktion) u.U. mit verschieden Datenobjekten (Parameter);
+
+- wenn Datenobjekte nur kurzfristig benötigt werden (dynamische Speicherver-
+ waltung) und diese nicht von dem gesamten Programm angesprochen werden
+ sollen (lokale, globale Datenobjekte);
+
+Im folgenden Programm stellen wir ein Fragment vor, in dem zwei Werte ver-
+tauscht werden. In der einen (linken) Lösung wird ein Refinement, in der
+anderen eine Prozedur verwandt.
+
+Programm 19:
+
+ ... PROC vertausche a und b:
+ IF a > b INT CONST x :: a;
+ THEN vertausche a und b a := b;
+ END IF; b := x
+ ... END PROC vertausche a und b;
+ vertausche a und b; ...
+ ... IF a > b
+ THEN vertausche a und b
+ vertausche a und b: END IF;
+ INT CONST x :: a; ...
+ a := b; vertausche a und b;
+ b := x. ...
+
+Beim ersten Hinsehen leisten beide Programme das Gleiche. Es gibt jedoch
+drei wichtige Unterschiede:
+
+1) Das Refinement 'vertausche a und b' wird zweimal (vom ELAN-Compiler)
+ eingesetzt, d.h. der Code ist zweimal vorhanden. Die Prozedur dagegen ist
+ vom Code nur einmal vorhanden, wird aber zweimal - durch das Aufführen
+ des Prozedurnamens - aufgerufen.
+
+2) Die Variable 'x' ist in der linken Programmversion während des gesamten
+ Ablauf des Programms vorhanden. Solche Datenobjekte nennt man statische
+ Datenobjekte oder auch (aus Gründen, die erst etwas später offensichtlich
+ werden) Paket-Objekte. Das Datenobjekt 'x' der rechten Version dagegen
+ ist nur während der Bearbeitung der Prozedur vorhanden. Solche Daten-
+ objekte, die nur kurzfristig Speicher belegen, werden dynamische Daten-
+ objekte genannt.
+
+ Prozeduren sind also ein Mittel, um die Speicherbelegung zu beeinflussen,
+ was besonders bei großen Datenobjekten notwendig ist.
+
+3) 'x' kann in der linken Programmversion - obwohl sie in einem Refinement
+ deklariert wurde - von jeder Stelle des Programms angesprochen werden.
+ Solche Datenobjekte werden globale Datenobjekte genannt. Das Datenobjekt
+ 'x' der Prozedur dagegen kann nur innerhalb der Prozedur angesprochen
+ werden, sie ist also ein lokales Datenobjekt hinsichtlich der Prozedur.
+ Innerhalb der Prozedur dürfen globale Datenobjekte (also Objekte, die
+ außerhalb von Prozeduren deklariert wurden) angesprochen werden.
+
+ Eine Prozedur in ELAN bildet im Gegensatz zu Refinements einen eigenen
+ Gültigkeitsbereich hinsichtlich Datenobjekten und Refinements, die inner-
+ halb der Prozedur deklariert werden. Prozeduren sind somit ein Mittel, um
+ die in ihr deklarierten Datenobjekte hinsichtlich der Ansprechbarkeit
+ nach Außen "abzuschotten".
+
+Prozeduren wie die in Programm 19 werden mit dem Schlüsselwort PROC, dem
+Namen der Prozedur und einem Doppelpunkt eingeleitet. Dies nennt man den
+Prozedurkopf. Der Prozedurkopf entspricht den Definitionen, die wir bereits
+in vorigen Abschnitten dieses Skripts gegeben haben. Nach dem Prozedurkopf
+folgt der Prozedurrumpf, der Datenobjekt-Deklarationen, Anweisungen und
+Refinements enthalten kann. Abgeschlossen wird die Prozedur durch END PROC
+und dem Prozedurnamen.
+
+
+Aufgabe (HSG):
+
+ a) Erkläre den Unterschied zwischen einer Prozedur und einem Refinement.
+ b) Was sind globale bzw. lokale Datenobjekte?
+Übungsziel: Begriffe, die mit Prozeduren zusammenhängen
+
+
+Aufgabe (TSW):
+
+ Gegeben sei folgendes Programmfragment:
+ INT VAR a, b;
+ ... (*1*)
+ PROC x:
+ INT VAR x1;
+ ... (*2*)
+ END PROC x;
+ TEXT VAR t;
+ PROC y:
+ REAL VAR y1
+ ... (*3*)
+ END PROC y;
+ ... (*4*)
+
+ 1.) Welche Objekte (einschließlich Prozeduren) sind an den Punkten
+ (*1*) :
+ (*2*) :
+ (*3*) :
+ (*4*) :
+ ansprechbar?
+
+ 2.) Welche Datenobjekte sind in der Prozedur 'y'
+ global:
+ lokal:
+Übungsziel: Globale und lokale Objekte
+
+
+Prozeduren mit Parametern erlauben es, gleiche Anweisungen mit unterschied-
+lichen Datenobjekten auszuführen:
+
+
+Programm 20:
+
+ PROC vertausche (INT VAR a, b):
+ INT VAR x :: a;
+ a := b;
+ b := x
+ END PROC vertausche;
+
+ INT VAR eins :: 1,
+ zwei :: 2,
+ drei :: 3;
+ vertausche (eins, zwei);
+ vertausche (zwei, drei);
+ vertausche (eins, zwei);
+ put (eins); put (zwei); put (drei)
+
+Die Datenobjekte 'a' und 'b' der Prozedur 'vertausche' werden formale Para-
+meter genannt. Sie stehen als Platzhalter für die bei einem Prozeduraufruf
+einzusetzenden aktuellen Parameter (in unserem Beispiel die Datenobjekte
+'eins', 'zwei' und 'drei').
+
+
+Aufgabe (HSG):
+
+ Welche Werte werden in dem Programm 20 ausgedruckt?
+Übungsziel: Arbeiten mit Prozeduren und Parameter-Mechanismus.
+
+
+Parameter werden im Prozedurkopf nach dem Prozedurnamen in Klammern mit
+Datentyp und Accessrecht angegeben. Dabei bedeutet CONST, daß auf den
+Parameter nur lesend zugegriffen wird, während auf einen VAR-Parameter auch
+z.B. eine Zuweisung angewandt werden kann. CONST-Parameter sind also
+Eingabe-Parameter, während VAR-Parameter Ein-/Ausgabe-Parameter realisieren.
+
+Bei den aktuellen Parametern ist folgendes zu beachten:
+
+a) Wird ein VAR-Parameter in der Definition der Prozedur vorgeschrieben (wie
+ z.B. im Programm 20), darf kein Ausdruck als aktueller Parameter "überge-
+ ben" werden, weil an einen Ausdruck nichts zugewiesen werden kann.
+ Gegenbeispiel:
+
+ vertausche ( eins * zwei, drei)
+
+ Ausdrücke haben - wie bereits erwähnt - das Accessrecht CONST.
+
+b) Wird ein CONST-Parameter verlangt, dann darf in diesem Fall ein Ausdruck
+ als aktueller Parameter geschrieben werden. Aber auch ein VAR-Datenobjekt
+ darf angegeben werden. In diesem Fall wird eine Wandlung des Accessrechts
+ (CONSTing) vorgenommen: der aktuelle Parameter erhält sozusagen für die
+ Zeit der Abarbeitung der Prozedur das Accessrecht CONST.
+
+Es ist auch möglich, Prozeduren als Parameter zu definieren, worauf wir aber
+hier nicht eingehen wollen.
+
+Eine Werte liefernde Prozedur erhält man, wenn der Prozedurrumpf einen Wert
+liefert, d.h. die letzte ausführbare Anweisung des Prozedurrumpfes muß einen
+Wert liefern (analog Werte liefernde Refinements) und der zu liefernde
+Datentyp vor den Prozedurkopf geschrieben wird.
+
+
+Programm 21:
+
+ INT PROC max (INT CONST a, b):
+ IF a > b
+ THEN a
+ ELSE b
+ END IF
+ END PROC max;
+
+ put (max (3, 4))
+
+(In unserem Beispiel liefert die IF-Anweisung einen Wert. Das erfolgt da-
+durch, daß beide Zweige der Anweisung einen Wert liefern.)
+
+
+
+Neudefinierte Operatoren
+
+Neue, zusätzliche Operatoren können in ELAN wie Prozeduren definiert werden.
+Es ist nur notwendig, bei der Definition das Wort PROC gegen OP zu vertau-
+schen. Es sind aber auch nur 1 oder 2 Parameter bei Operatoren erlaubt.
+
+
+Programm 22a:
+
+ TEXT OP * (INT CONST mal, TEXT CONST t):
+ INT VAR zaehler :: mal;
+ TEXT VAR ergebnis :: "";
+ WHILE zaehler > 0 REP
+ ergebnis := ergebnis + t;
+ zaehler := zaehler - 1
+ END REP;
+ ergebnis
+ END OP *;
+
+Dieser Operator vervielfältigt TEXTe ( 2 * "ha" liefert "haha"). Der Name
+des Operators ist '*'. Man kann als Operatornamen die vorhandenen, bereits
+benutzten Sonderzeichen verwenden. In diesem Fall bekommt der neudefinierte
+Operator die gleiche Priorität wie der bereits vorhandene oder ein Schlüssel-
+wort.
+
+Der "Aufruf" eines Operators unterscheidet sich von einer Prozedur durch die
+infix-Schreibweise. Im übrigen gilt das für Prozeduren Gesagte.
+
+
+
+Optimierungen
+
+Optimierungen werden vorgenommen, wenn man mit den Laufzeiten bzw. Speicher-
+bedarf eines Programms nicht zufrieden ist. Kleinere, lokale Optimierungen
+sind meist nicht sinnvoll und notwendig und bringen mehr Fehler, als Ver-
+besserungen:
+
+
+Programm 22b:
+
+ TEXT OP * (INT CONST mal, TEXT CONST t):
+ INT VAR i;
+ TEXT VAR ergebnis :: "";
+ FOR i FROM 1 UPTO mal REP
+ ergebnis CAT t
+ END REP;
+ ergebnis
+ END OP *;
+
+Wir haben hier die WHILE-Schleife durch eine Zählschleife und 'ergebnis :=
+ergebnis + t' durch 'ergebnis CAT t' ersetzt. Dies ist nur eine minimale
+Optimierung (wenn sie überhaupt etwas einbringt). Leider sind solche
+"Optimierungen" sehr häufig anzutreffen. Besser ist es, eine Lösung zu
+finden, die algorithmisch oder von den Datenstrukturen her prinzipiell
+besser ist. Wir haben dies für das Programm 22 getan. Lösungsidee: jeweilige
+Verdopplung eines Zwischentextes ("Russische Multiplikation").
+
+
+Programm 22c:
+
+ TEXT OP * (INT CONST mal, TEXT CONST t):
+ INT VAR zaehler :: mal;
+ TEXT VAR einer :: "",
+ dopplung :: t;
+ IF fehlerhafter aufruf
+ THEN LEAVE * WITH ""
+ ELSE verdopplung
+ END IF;
+ dopplung + einer.
+
+ fehlerhafter aufruf:
+ zaehler < 1.
+
+ verdopplung:
+ WHILE zaehler > 1 REP
+ IF zaehler ist ungerade
+ THEN einer CAT t
+ END IF;
+ dopplung CAT dopplung;
+ zaehler := zaehler DIV 2
+ END REP.
+
+ zaehler ist ungerade:
+ zaehler MOD 2 = 1.
+
+ END OP *;
+
+
+In diesem Programm wurde eine Anweisung verwendet (LEAVE), die wir im
+folgenden Abschnitt erklären wollen.
+
+
+
+Das LEAVE-Konstrukt
+
+Das LEAVE-Konstrukt wird verwendet, um eine benannte Anweisung (Refinement,
+Prozedur oder Operator) vorzeitig zu verlassen. Es ist auch möglich, mehr-
+fach geschachtelte Refinements zu verlassen. Durch eine (optionale)
+WITH-Angabe kann auch ein wertelieferndes Refinement verlassen werden.
+
+
+
+Reihungen
+
+Wir haben bis jetzt bereits zusammengesetzte algorithmische Objekte kennen-
+gelernt, die man unter einem Namen als Ganzes ansprechen kann (Prozeduren).
+Die gleiche Möglichkeit gibt es auch bei Datenobjekten, wobei wir gleich-
+artige oder ungleichartige Objekte zu einem Objekt zusammenfassen können.
+Zuerst zu der Zusammenfassung gleichartiger Datenobjekte, die in ELAN eine
+Reihung (ROW) genannt wird. Die einzelnen Objekte einer Reihung werden
+Elemente genannt. Beispiel (Deklaration einer Reihung von 10 INT-Elementen):
+
+ ROW 10 INT VAR feld
+
+Die Angabe hinter dem Schlüsselwort ROW muß ein INT-Denoter sein (oder
+durch ein LET definierter Name). Dabei ist ROW 10 INT ein (neuer, von den
+elementaren unterschiedlicher) Datentyp, für den keine Operationen definiert
+sind, außer der Zuweisung. Das Accessrecht (VAR in unserem Beispiel) und der
+Name ('feld') gilt - wie bei den elementaren Datentypen - für diesen neuen
+Datentyp, also für alle 10 Elemente.
+
+Warum gibt es keine Operationen außer der Zuweisung? Das wird uns sehr
+schnell einsichtig, wenn wir uns vorstellen, daß es ja sehr viele Datentypen
+(zusätzlich zu den elementaren) gibt, weil Reihungen von jedem Datentyp
+gebildet werden können:
+
+ ROW 1 INT ROW 1 REAL
+ ROW 2 INT ROW 2 REAL
+ : :
+ ROW maxint INT ROW maxint REAL
+
+ ROW 1 TEXT ROW 1 BOOL
+ ROW 2 TEXT ROW 2 BOOL
+ : :
+ ROW maxint TEXT ROW maxint BOOL
+
+Für die elementaren INT-, REAL-, BOOL- und TEXT-Datentypen sind
+unterschiedliche Operationen definiert. Man müßte nun für jeden dieser
+zusammengesetzten Datentypen z.B. auch 'get'- und 'put'-Prozeduren
+schreiben, was allein vom Schreibaufwand sehr aufwendig wäre. Das ist der
+Grund dafür, daß es keine vorgegebene Operationen auf zusammengesetzte
+Datentypen gibt.
+
+Zugegebenermaßen könnte man mit solchen Datentypen, die nur über eine Opera-
+tion verfügen (Zuweisung), nicht sehr viel anfangen, wenn es nicht eine wei-
+tere vorgegebene Operation gäbe, die #ib#Subskription#ie#. Sie erlaubt es,
+auf die Elemente einer Reihung zuzugreifen und den Datentyp der Elemente
+"aufzudecken". Beispiel:
+
+ feld [3]
+
+bezieht sich auf das dritte Element der Reihung 'feld' und hat den Datentyp
+INT. Für INT-Objekte haben wir aber einige Operationen, mit denen wir
+arbeiten können. Beispiele:
+
+ feld [3] := 7;
+ feld [4] := feld [3] + 4;
+ ...
+
+Eine Subskription "schält" also vom Datentyp ein ROW ab und liefert ein
+Element der Reihung. Die Angabe der Nummer des Elements in der Reihung nennt
+man Subskript (in unserem Fall '3'). Der Subskript wird in ELAN in eckigen
+Klammern angegeben, um eine bessere Unterscheidung zu den runden Klammern in
+Ausdrücken zu erreichen. Ein subskribiertes ROW-Datenobjekt kann also über-
+all da verwendet werden, wo ein entsprechender Datentyp benötigt wird (Aus-
+nahme: Schleifenvariable). Als Beispiel zeigen wir zwei Prozeduren, die eine
+Reihung einlesen bzw. ausgeben:
+
+
+Programm 23:
+
+ PROC get (ROW 10 INT VAR feld):
+ INT VAR i;
+ FOR i FROM 1 UPTO 10 REP
+ put (i); put ("tes Element bitte:");
+ get (feld [i]);
+ line
+ END REP
+ END PROC get;
+
+ PROC put (ROW 10 INT CONST feld):
+ INT VAR i;
+ FOR i FROM 1 UPTO 10 REP
+ put (i); put ("tes Element ist:");
+ put (feld [i]);
+ line
+ END REP
+ END PROC put
+
+
+Wie bereits erwähnt, ist es erlaubt, Reihungen überall dort zu verwenden, wo
+auch die elementaren Datentypen verwandt werden können, also auch als
+Parameter. Zudem haben wir die generischen Eigenschaften von Prozeduren in
+ELAN bei der Benennung der Prozeduren benutzt.
+
+Diese beiden Prozeduren benutzen wir gleich im nächsten Programm, welches
+10 Werte einliest und die Summe berechnet:
+
+
+Programm 24:
+
+ ROW 10 INT VAR werte;
+ lies werte ein;
+ summiere sie;
+ drucke die summe und einzelwerte.
+
+ lies werte ein:
+ get (werte).
+
+ summiere sie:
+ INT VAR summe :: 0, i;
+ FOR i FROM 1 UPTO 10 REP
+ summe INCR werte [i]
+ END REP.
+
+ drucke die summe und einzelwerte:
+ put (werte);
+ line;
+ put ("Summe:"); put (summe).
+
+
+Aufgabe (HSG):
+
+ Wie kann man vermeiden, daß 'summe > maxint' ("overflow"-Bedingung)
+ wird?
+
+
+Oft benötigt man die Werte einer Reihung sortiert. Das Programm 25 zeigt
+einen (sehr dummen und ineffizienten) Sortieralgorithmus:
+
+
+Programm 25:
+
+ ROW 10 INT VAR wert;
+ lies die werte ein;
+ sortiere in eine zweite liste;
+ drucke die zweite liste.
+
+ lies die werte ein:
+ get (wert).
+
+ sortiere in eine zweite liste:
+ INT VAR i;
+ FOR i FROM 1 UPTO 10 REP
+ suche kleinstes element aus der werte liste;
+ bringe dieses in die zweite liste;
+ entferne es aus der werte liste
+ END REP.
+
+ suche kleinstes element aus der werte liste:
+ INT VAR kleinstes element :: maxint, position kleinstes element :: 0, k;
+ FOR k FROM 1 UPTO 10 REP
+ IF wert [k] < kleinstes element
+ THEN kleinstes element := wert [k];
+ position kleinstes element := k
+ END IF
+ END REP.
+
+ bringe dieses in die zweite liste:
+ ROW 10 INT VAR liste2;
+ liste2 [i] := kleinstes element.
+
+ entferne es aus der werte liste:
+ wert [position kleinstes element] := maxint.
+
+ drucke die zweite liste:
+ put (liste2).
+
+Anmerkung: Bei diesem einfachen Sortieralgorithmus (der übrigens "lineare
+Auswahl" heißt), wurde der Wert 'maxint' als zulässiger Wert ausgeschlossen.
+Der Algorithmus ist ziemlich der schlechteste, den wir uns ausdenken können.
+Einmal braucht er den doppelten Speicherplatz für die zu sortierende Liste,
+andererseits sind für N Werte N*N Durchläufe durch die Liste notwendig (man
+sagt, der Algorithmus ist von der Ordnung N Quadrat).
+
+Da es möglich ist, von jedem Datentyp eine Reihung zu bilden, kann man
+natürlich auch von einer Reihung eine Reihung bilden:
+
+ ROW 5 ROW 10 INT VAR matrix
+
+Für eine "doppelte" Reihung gilt das für "einfache" Reihungen gesagte.
+Wiederum existieren keine Operationen für dieses Datenobjekt (außer der
+Zuweisung), jedoch ist es durch Subskription möglich, auf die Elemente zuzu-
+greifen:
+
+ matrix [3]
+
+liefert ein Datenobjekt mit dem Datentyp ROW 10 INT, für den wir bereits in
+Programm 23 die Prozeduren 'get' und 'put' geschrieben haben, die wir
+verwenden können:
+
+ get (matrix [4])
+
+Subskribieren wir jedoch 'matrix' nochmals, so erhalten wir ein INT:
+
+ matrix [2] [8]
+
+(jede Subskription "schält" von Außen ein ROW vom Datentyp ab).
+
+
+Aufgabe (HSG):
+
+ a) Geben Sie Datentyp, Accessrecht und Name der folgenden Datenobjekte
+ an:
+ ROW 17 INT CONST alpha;
+ ROW 3 ROW 4 TEXT VAR matrix;
+ ...
+ beta [3] := 7;
+ gamma [4] := gamma [5]
+
+ b) Was führt zu Fehlern? Wenn ja, warum?
+ ROW 17 INT VAR alpha;
+ ROW 3 ROW 4 TEXT VAR beta, gamma;
+ ROW 4 ROW 3 TEXT CONST delta;
+ INT VAR x :: 7;
+ ROW x BOOL VAR y;
+ get (alpha);
+ get (beta [7]);
+ FOR x FROM 1 UPTO 3 REP
+ get (beta [x])
+ END REP;
+ beta := delta;
+ delta [1] [2] := "mist";
+ beta := gamma;
+ beta [3] := gamma [3];
+ get (beta [1] [1]);
+ gamma [1] [5] := beta [1] [1] + "ELAN"
+ x := alpha [3];
+ x := 20;
+ alpha [x] := alpha [3] + 7
+Übungsziel: Umgang mit Reihungen
+
+
+
+Strukturen
+
+Strukturen sind Datenverbunde wie Reihungen, aber die Komponenten können
+ungleichartige Datentypen haben. Die Komponenten von Strukturen heißen
+Felder (bei Reihungen: Elemente) und der Zugriff auf ein Feld Selektion
+(Reihungen: Subskription). Eine Struktur ist - genauso wie bei Reihungen -
+ein eigener Datentyp, der in einer Deklaration angegeben werden muß.
+Beispiel:
+
+ STRUCT (TEXT name, INT alter) VAR ich
+
+Wiederum existieren keine Operationen auf Strukturen außer der Zuweisung und
+der Selektion, die es erlaubt, Komponenten aus einer Struktur herauszulösen:
+
+ ich . name
+ ich . alter
+
+Die erste Selektion liefert einen TEXT-, die zweite ein INT-Datenobjekt. Mit
+diesen (selektierten) Datenobjekten kann - wie gewohnt - gearbeitet werden
+(Ausnahme: nicht als Schleifenvariable).
+
+Zum Datentyp einer Struktur gehören auch die Feldnamen:
+
+ STRUCT (TEXT produkt name, INT artikel nr) VAR erzeugnis
+
+ist ein anderer Datentyp als im ersten Beispiel dieses Abschnitts. Für
+Strukturen - genauso wie bei Reihungen - kann man sich neue Operationen
+definieren. Im folgenden Programm definieren wir für eine Struktur, die
+Personen beschreibt, die Operationen 'put', 'get' und den dyadischen
+Operator HEIRATET. Anschließend werden drei Paare verHEIRATET.
+
+
+Programm 26a:
+
+ PROC get (STRUCT (TEXT name, vorname, INT alter) VAR p):
+ put ("bitte Nachname:"); get ( p.name);
+ put ("bitte Vorname:"); get ( p.vorname);
+ put ("bitte Alter:"); get ( p.alter);
+ line
+ END PROC get;
+
+ PROC put (STRUCT (TEXT name, vorname, INT alter) CONST p):
+ put (p.vorname); put (p.name);
+ put ("ist");
+ put (p.alter);
+ put ("Jahre alt");
+ line
+ END PROC put;
+
+ OP HEIRATET
+ (STRUCT (TEXT name, vorname, INT alter) VAR w,
+ STRUCT (TEXT name, vorname, INT alter) CONST m):
+ w.name := m.name
+ END OP HEIRATET;
+
+ ROW 3 STRUCT (TEXT name, vorname, INT alter) VAR frau, mann;
+
+ personendaten einlesen;
+ heiraten lassen;
+ paardaten ausgeben.
+
+ personendaten einlesen:
+ INT VAR i;
+ FOR i FROM 1 UPTO 3 REP
+ get (frau [i]);
+ get (mann [i])
+ END REP.
+
+ heiraten lassen:
+ FOR i FROM 1 UPTO 3 REP
+ frau [i] HEIRATET mann [i]
+ END REP.
+
+ paardaten ausgeben:
+ FOR i FROM 1 UPTO 3 REP
+ put (frau [i]);
+ put ("hat geheiratet:"); line;
+ put (mann [i]); line
+ END REP.
+
+Reihungen und Strukturen dürfen miteinander kombiniert werden, d.h. es darf
+eine Reihung in einer Struktur erscheinen oder es darf eine Reihung von einer
+Struktur vorgenommen werden. Selektion und Subskription sind in diesen Fällen
+in der Reihenfolge vorzunehmen, wie die Datentypen aufgebaut wurden (von
+außen nach innen).
+
+
+Aufgabe (HSG):
+
+ In ELAN heissen
+ a1) Datenverbunde gleichartiger Komponenten:
+ a2) Datenverbunde ungleichartiger Komponenten:
+ b1) die Komponenten eines ROWs:
+ b2) die Komponenten eines STRUCTs:
+ c1) die Zugriffe auf die Komponenten eines ROWs:
+ c2) die Zugriffe auf die Komponenten eines STRUCTs:
+Übungsziel: Begriffe von ROWs und STRUCTs kennenlernen
+
+
+
+LET-Konstrukt
+
+Wie wir in Programm 26 gesehen haben, ist die Verwendung von Strukturen
+oder auch Reihungen manchmal schreibaufwendig. Mit dem LET-Konstrukt darf
+man Datentypen (und Denotern) einen Namen geben. Dieser Name steht als
+Abkürzung und verringert so die Schreibarbeit. Zusätzlich wird durch die
+Namensgebung die Lesbarkeit des Programms erhöht. Beispiel:
+
+
+Programm 26b:
+
+ LET PERSON = STRUCT (TEXT name, vorname, INT alter);
+
+ PROC get (PERSON VAR p):
+ put ("bitte Nachname:"); get ( p.name);
+ put ("bitte Vorname:"); get ( p.vorname);
+ put ("bitte Alter:"); get ( p.alter);
+ line
+ END PROC get;
+
+ PROC put (PERSON CONST p):
+ put (p.vorname); put (p.name); put ("ist");
+ put (p.alter); put ("Jahre alt"); line
+ END PROC put;
+
+ OP HEIRATET (PERSON VAR f, PERSON CONST m):
+ f.name := m.name
+ END OP HEIRATET;
+
+ ROW 3 PERSON VAR mann, frau;
+ ...
+
+Überall wo der abzukürzende Datentyp verwandt werden kann, kann PERSON
+benutzt werden. Wohlgemerkt: PERSON ist kein neuer Datentyp, sondern nur ein
+Name, der für STRUCT (....) steht. Der Zugriff auf die Komponenten des
+abgekürzten Datentyps bleibt erhalten (was bei abstrakten Datentypen, die wir
+etwas später erklären, nicht mehr der Fall ist).
+
+Neben der Funktion der Abkürzung von Datentypen kann das LET-Konstrukt
+auch für die Namensgebung für die Denoter verwandt werden. Beispiele:
+
+ LET pi = 3.14159;
+ LET blank = " ";
+ LET anzahl = 27
+
+Der Einsatz von LET-Namen für INT-Denoter macht es möglich, Programme
+leicht zu ändern:
+
+
+Programm 26c:
+
+ LET anzahl paare = 3;
+ ROW anzahl paare PERSON VAR frau, mann;
+
+ personendaten einlesen;
+ heiraten lassen;
+ paardaten ausgeben.
+
+ personendaten einlesen:
+ INT VAR i;
+ FOR i FROM 1 UPTO anzahl paare REP
+ get (frau [i]);
+ get (mann [i])
+ END REP.
+ ...
+
+Ebenso wie die Abkürzung von Datentypen (LET PERSON = STRUCT (...)) wird
+im obigen Beispiel für den Namen 'anzahl paare' bei jedem Auftreten der
+Denoter '3' vom ELAN-Compiler eingesetzt. Um nun (z.B.) 27 Paare "heiraten"
+zu lassen, brauchen wir nur die LET-Anweisung in '27' zu verändern...
+(Scheidungen erfordern etwas mehr Aufwand).
+
+
+Aufgabe (HSG):
+
+ Was ist falsch?
+ LET anz = 5,
+ max = 5*5,
+ MAT = ROW anz ROW anz TEXT;
+
+ PROC get (MAT CONST m):
+ FOR i FROM 1 UPTO max REP
+ get (m [i])
+ END REP
+ END PROC get;
+
+ MAT VAR x,y;
+ get (x);
+ x := y + 1
+
+
+Aufgabe (HSG):
+
+ Schreibe ein Programm, das mit den Deklarationen
+ LET anz = 5,
+ VEC = ROW anz INT,
+ MAT = ROW anz VEC;
+ folgende Prozeduren realisiert:
+ PROC get (VEC VAR v)
+ PROC get (MAT VAR m)
+ PROC put (VEC CONST v)
+ PROC put (MAT CONST m)
+ INT PROC reihensumme (VEC CONST v)
+Übungsziel: Reihungen als Parameter
+
+
+
+Denoter für Datenverbunde: Konstruktoren
+
+Denoter für die elementaren Datentypen haben wir kennengelernt. Oft ergibt
+sich auch die Notwendigkeit (z.B. bei Initialisierungen), Datenverbunde in
+einem Programm Werte zu geben. Das kann durch normale Zuweisungen erfolgen.
+Beispiel:
+
+ LET PERSON = STRUCT (TEXT name, vorname, INT alter);
+
+ PERSON VAR mann;
+
+ mann.name := "meier";
+ mann.vorname := "egon";
+ mann.alter := 27
+
+Aber man möchte auch Denoter für Datenverbunde z.B. in Ausdrücken verwenden,
+was durch die Konstruktoren ermöglicht wird. Beispiel:
+
+ LET PERSON = STRUCT (TEXT name, vorname, INT alter);
+
+ PERSON VAR mann, frau;
+
+ frau := PERSON : ( "niemeyer", "einfalt", 65);
+ frau HEIRATET PERSON : ( "meier", "egon", 27)
+
+Ein Konstruktor ist also ein Mechanismus, um ein Datenobjekt eines Datenver-
+bundes in einem Programm zu notieren. Ein Konstruktor besteht aus der Angabe
+des Datentyps (der auch durch einen LET-Namen abgekürzt sein darf), einem
+Doppelpunkt und den in Klammern eingefaßten Komponenten (hier Denoter).
+Besteht eine der Komponenten wiederum aus einem Datenverbund, muß inner-
+halb des Konstruktors wiederum ein Konstruktor eingesetzt werden usw. Kon-
+struktoren sind natürlich für Reihungen auch möglich:
+
+ ROW 7 INT VAR feld;
+ feld := ROW 7 INT : ( 1, 2, 3, 4, 5, 6, 7);
+
+
+Aufgabe (HSG):
+
+ Geben Sie Datentyp, Accessrecht und Name der folgenden Datenobjekte an:
+ STRUCT (INT alter, TEXT name) VAR mensch;
+ STRUCT (INT jahrgang, ROW 2 TEXT lage) CONST wein;
+ ROW 100 STRUCT (PERSON p, NUMMER n) VAR betriebsangehoeriger;
+ STRUCT (INT anz terminals, STRUCT (TEXT systemname, INT version) art)
+ CONST betriebsystem;
+ mensch := ...;
+ betriebsangehoeriger [2] := ...;
+ betriebsangehoeriger [2]. n := NUMMER: (...);
+ betriebsystem.art.systemname := "EUMEL";
+ wein.lage := ROW 2 TEXT: ("Loire", "Frankreich");
+ wein.lage [1] := "Kroever Nacktarsch";
+Übungsziel: Umgang mit Strukturen.
+
+
+
+Rekursive Prozeduren und Operatoren
+
+Alle Prozeduren und Operatoren dürfen in ELAN rekursiv sein.
+
+
+Programm 27:
+
+ INT PROC fakultaet (INT CONST n):
+ IF n > 0
+ THEN fakultaet (n-1) * n
+ ELSE 1
+ END IF
+ END PROC fakultaet
+
+Dieses Beispiel ist aber (leider) kein gutes Beispiel für eine Rekursion,
+denn das Programm kann leicht in eine iterative Version umgewandelt werden:
+
+
+Programm 28:
+
+ INT PROC fakultaet (INT CONST n):
+ INT VAR prod :: 1, i;
+ FOR i FROM 2 UPTO n REP
+ prod := prod * i
+ END REP;
+ prod
+ END PROC fakultaet
+
+Die Umwandlung von einem rekursiven Programm in ein iteratives ist übrigens
+immer möglich, jedoch oft nicht so einfach wie in diesem Fall. Beispiel
+(Ackermann-Funktion):
+
+
+Programm 29:
+
+ INT PROC acker (INT CONST m, n):
+ IF m = 0
+ THEN n + 1
+ ELIF n = 0
+ THEN acker (m-1, 0)
+ ELSE acker (m - 1, acker (m, n - 1))
+ ENDIF
+ END PROC acker
+
+
+Aufgabe (HSG):
+
+ a) Beschreibe die Unterschiede zwischen Iteration und Rekursion. Worauf
+ muß man bei Rekursionen achten?
+ b) Wie groß ist der Wert von 'acker (2, 2)'? Hilfreicher Tip: stelle
+ dabei eine Tabelle auf!
+ c) Zudem enthält die Programmierung der Ackermann-Funktion (mindestens)
+ einen Fehler. Welchen?
+Übungsziel: Umgang mit Rekursion
+
+
+Das eigentliche Einsatzgebiet von rekursiven Algorithmen liegt aber bei den
+'backtrack'-Verfahren. Diese werden eingesetzt, wenn eine exakte algorithmi-
+sche Lösung nicht bekannt ist oder nicht gefunden werden kann und man ver-
+schiedene Versuche machen muß, um zu einem Ziel (oder Lösung) zu gelangen.
+
+Als Beispielprogramm zeigen wir das Spiel "Maus sucht Käse". In einem Laby-
+rinth (realisiert durch eine Reihung von einer Reihung), das mit Hindernis-
+sen bestückt ist, wurde ein Käse versteckt. Eine sehr dumme Maus sucht
+systematisch die umliegenden Felder (in allen vier Himmelsrichtungen) nach
+dem Käse ab. Ist sie auf einem neuen Feld und ist das Feld frei, sucht sie
+erneut. Felder, auf denen sie bereits war, werden von ihr markiert. Da die
+Maus sehr kurzsichtig ist und nicht richtig riechen kann, bemerkt sie den
+Käse erst, wenn sie sozusagen mit allen vier Pfoten in ihm gelandet ist
+(analog bei Hindernissen, die nicht überklettert werden können). Damit die
+Maus nicht aus dem Labyrinth entfliehen kann, wird der Rand als Hindernis
+angesehen.
+
+
+(Teil-) Programm 30:
+
+ PROC suche weg (INT CONST x, y):
+ IF labyrinth [x] [y] = kaese
+ THEN kaese gefunden
+ ELIF labyrinth [x] [y] = frei
+ THEN suche weiter
+ END IF.
+
+ suche weiter:
+ labyrinth [x] [y] := markiert;
+ INT VAR richtung;
+ FOR richtung FROM osten UPTO sueden REP
+ versuche diese richtung
+ END REP;
+ labyrinth [x] [y] := frei.
+
+ versuche diese richtung:
+ IF richtung = osten
+ THEN suche weg (x + 1, y)
+ ELIF richtung = norden
+ THEN suche weg (x, y + 1)
+ ...
+
+
+
+Dateien
+
+Dateien werden benötigt, wenn
+
+- Daten über die Abarbeitungszeit eines Programms aufbewahrt werden sollen;
+- der Zeitpunkt oder Ort der Datenerfassung nicht mit dem Zeitpunkt oder Ort
+ der Datenverarbeitung übereinstimmt;
+- die gesamte Datenmenge nicht auf einmal in den Zentralspeicher eines
+ Rechners paßt;
+- die Anzahl und/oder Art der Daten nicht von vornherein bekannt sind.
+
+Eine Datei ("file") ist eine Zusammenfassung von Daten, die auf Massenspei-
+chern aufbewahrt wird. Dateien sind in bestimmten Informationsmengen, den
+Sätzen ("records") organisiert.
+
+In ELAN gibt es zwei Arten von Dateien:
+
+a) FILE: sequentielle Dateien. Die Sätze können nur sequentiell gelesen bzw.
+ geschrieben werden. Eine Positionierung ist nur zum nächsten Satz möglich.
+b) DIRFILE: indexsequentielle Dateien. Die Positionierung erfolgt direkt mit
+ Hilfe eines Schlüssels ("key") oder Index, kann aber auch sequentiell
+ vorgenommen werden.
+
+ Wichtig:
+ DIRFILEs sind auf dem EUMEL-System nicht implementiert! Deswegen wird
+ auf diesen Dateityp hier nicht weiter eingegangen.
+
+Dateien werden normalerweise von dem #ib#Betriebsystem#ie# eines Rechners
+aufbewahrt und verwaltet. Somit ist eine Verbindung von einem ELAN-Programm,
+in dem eine Datei unter einem Namen - wie jedes andere Datenobjekt auch -
+angesprochen werden soll, und dem Betriebsystem notwendig. Dies erfolgt durch
+sogenannte Assoziierungsprozeduren. Beispiele:
+
+ FILE VAR meine datei :: sequential file (output, "xyz");
+ FILE CONST eine andere datei :: sequential file (input, "abc")
+
+Die Assoziierungsprozedur heißt 'sequential file' für FILEs. Der erste
+Parameter einer Assoziierungsprozedur gibt immer die sogenannte Betriebs-
+richtung ("TRANSPUTDIRECTION") an. Es gibt folgende Betriebsrichtungen:
+
+ input nur Lesen der Datei
+ output nur Schreiben der Datei
+
+ Anmerkung:
+ Im EUMEL-System gibt es noch die Betriebsrichtung 'modify', die es er-
+ laubt, beliebig zu positionieren, Sätze zu löschen und/oder einzufügen
+ usw. Dafür gibt es keine DIRFILEs. Siehe dazu auch das Kapitel über
+ Dateien in diesem Benutzerhandbuch.
+
+Der zweite Parameter einer Assoziierungsprozedur gibt an, unter welchem
+Namen die Datei in dem Betriebsystem bekannt ist. Mit Hilfe dieses Namens
+wird die Datei an das Datenobjekt gekoppelt, das bei der FILE-Deklaration im
+Programm erzeugt wurde.
+
+Welche Operationen sind nun für Dateien zugelassen? Wir beschreiben die
+wichtigsten für die beiden Dateiarten und Betriebsrichtungen getrennt:
+
+a) FILE mit 'input' (nur lesen):
+
+ PROC getline (FILE CONST f, TEXT VAR zeile)
+ PROC get (FILE CONST f, TEXT VAR t)
+ PROC get (FILE CONST f, REAL VAR r)
+ PROC get (FILE CONST f, INT VAR i)
+ BOOL PROC eof (FILE CONST f)
+ (* Abfrageprozedur auf das Ende eines FILEs (letzter Satz) *)
+
+ Als Beispiel zeigen wir ein Programm, welches eine Datei liest und auf
+ dem Ausgabemedium ausgibt.
+
+
+ Programm 31:
+
+ FILE CONST f :: sequential file (input, "datei1");
+ TEXT VAR satz;
+ WHILE NOT eof (f) REP
+ getline (f, satz);
+ put (satz); line
+ END REP.
+
+b) FILE mit 'output' (nur schreiben):
+
+ PROC putline (FILE VAR f, TEXT CONST zeile)
+ PROC put (FILE VAR f, TEXT CONST t)
+ PROC put (FILE VAR f, REAL CONST r)
+ PROC put (FILE VAR f, INT CONST i)
+ PROC line (FILE VAR f, INT CONST zeilenzahl)
+
+
+Aufgabe (HSG):
+
+ a) Das Arbeiten mit Dateien ist manchmal notwendig, weil ...
+ b) Wenn man mit Dateien in ELAN arbeitet, sind Assoziierungsprozeduren
+ notwendig.
+ b1) Wie heißen diese?
+ b2) Was gibt man in diesen an?
+ c) Welche Betriebsrichtungen gibt es bei FILES und was bewirken sie?
+Übungsziel: Datei-Begriffe
+
+
+Aufgabe (TSW):
+
+ Welche Fehler befinden sich in den folgenden Programmfragmenten?
+ a) FILE VAR f :: sequential file (input, "MIST");
+ TEXT VAR zeile;
+ REP
+ getline (f, zeile);
+ ...
+ UNTIL eof (f) END REP
+
+ b) FILE VAR f :: sequential file (output, "NOCHMAL");
+ TEXT VAR zeile;
+ REP
+ getline (f, zeile);
+ put (zeile)
+ UNTIL eof (f) END REP
+
+ c) FILE VAR f :: sequential file (input, "VERDAMMT"),
+ g :: sequential file (input, "DAEMLICH");
+ TEXT VAR zeile;
+ kopiere g in f.
+
+ kopiere g in f:
+ FOR i FROM 1 UPTO 100 REP
+ getline (g, zeile);
+ putline (f, zeile)
+ UNTIL eof (g) END REP.
+Übungsziel: Arbeiten mit Dateien
+
+
+
+Programmstruktur 1
+
+Bis jetzt haben wir noch nicht vollständig erklärt, wie ein ELAN-Programm
+formal als Ganzes aufgebaut sein muß, d.h. wie und in welcher Reihenfolge
+die Anweisungen, Refinements, Prozeduren und Deklarationen geschrieben
+werden müssen.
+
+Ein ELAN-Programm kann aus mehreren Moduln (Bausteinen) aufgebaut sein,
+die in ELAN PACKETs genannt werden. Das letzte PACKET wird "main packet"
+genannt, weil in diesem das eigentliche Benutzerprogramm (Hauptprogramm)
+enthalten ist. In diesem Abschnitt wollen wir uns nur mit dem Aufbau eines
+solchen PACKETs beschäftigen. Wir werden dabei nicht alle Möglichkeiten
+besprechen, sondern nur die wichtigsten Anwendungen beschreiben, mit einer
+Empfehlung, in welcher Reihenfolge die Elemente geschrieben werden sollten.
+
+Ein "main packet" kann aus folgenden Elementen bestehen:
+
+a) Deklarationen und Anweisungen. Diese müssen nicht in einer bestimmten
+ Reihenfolge im Programm erscheinen, sondern es ist möglich, erst in dem
+ Augenblick zu deklarieren, wenn z.B. eine neue Variable benötigt wird. Es
+ ist jedoch gute Programmierpraxis, die meisten Deklarationen an den
+ Anfang eines Programms (außer z.B. Datenobjekte, die nur lokal oder
+ kurzfristig benötigt werden, wie Hilfsvariablen oder Laufvariablen) zu
+ plazieren.
+
+ <Deklarationen> ;
+ <Anweisungen>
+
+b) Deklarationen, Refinements und Anweisungen. In diesem Fall ist es notwen-
+ dig, die Refinements hintereinander zu plazieren. Refinement-Aufrufe
+ und/oder Anweisungen sollten textuell vorher erscheinen. Die Refinements
+ werden durch einen Punkt von den Aufrufen getrennt:
+
+ <Deklarationen> ;
+ <Refinement-Aufrufe und/oder Anweisungen> .
+ <Refinements>
+
+ Innerhalb der Refinements sind Anweisungen und/oder Deklarationen möglich.
+
+c) Deklarationen, Prozeduren und Anweisungen. Werden Prozeduren vereinbart,
+ sollte man sie nach den Deklarationen plazieren. Danach sollten die
+ Anweisungen folgen:
+
+ <Deklarationen> ;
+ <Prozeduren> ;
+ <Anweisungen>
+
+ Mehrere (parallele) Prozeduren werden durch ";" voneinander getrennt. In
+ diesem Fall sind die Datenobjekte aus den Deklarationen außerhalb von
+ Prozeduren statisch, d.h. während der gesamten Laufzeit des Programm
+ vorhanden. Solche Datenobjekte werden auch PACKET-Daten genannt.Im
+ Gegensatz dazu sind die Datenobjekte aus Deklarationen in Prozeduren
+ dynamische Datenobjekte, die nur während der Bearbeitungszeit der
+ Prozedur existieren. Innerhalb einer Prozedur dürfen wiederum Refinements
+ verwendet werden. Ein Prozedur-Rumpf hat also den formalen Aufbau wie
+ unter a) oder b) geschildert.
+
+ Die Refinements und Datenobjekte, die innerhalb einer Prozedur deklariert
+ wurden, sind lokal zu dieser Prozedur, d.h. können von außerhalb nicht
+ angesprochen werden.
+
+d) Deklarationen, Prozeduren, Anweisungen und PACKET-Refinements.
+ Zusätzlich zu der Möglichkeit c) ist es erlaubt, neben den Anweisungen
+ außerhalb einer Prozedur auch Refinements zu verwenden:
+
+ <Deklarationen> ;
+ <Prozeduren> ;
+ <Anweisungen> .
+ <Refinements>
+
+ Diese Refinements können nun in Anweisungen außerhalb der Prozeduren
+ benutzt werden oder auch durch die Prozeduren (im letzteren Fall spricht
+ man analog zu globalen PACKET-Daten auch von PACKET-Refinements oder
+ globalen Refinements). In PACKET-Refinements dürfen natürlich keine
+ Datenobjekte verwandt werden, die lokal zu einer Prozedur sind.
+
+
+
+Moduln (PACKETs)
+
+PACKETs sind in ELAN eine Zusammenfassung von Datenobjekten, Prozeduren/
+Operatoren und Datentypen. Man kann sich ein PACKET als ein 'main packet'
+mit Zusätzen vorstellen. PACKETs können separat übersetzt werden, so
+daß der "Zusammenbau" eines umfangreichen Programms aus mehreren PACKETs
+möglich ist.
+
+Elemente eines PACKETs (Prozeduren/Operatoren, Datentypen) können außerhalb
+des PACKETs nur angesprochen werden, wenn sie in der Schnittstelle des
+PACKETs, die auch "interface" genannt wird, aufgeführt wird. Mit anderen
+Worten: es können alle Elemente eines PACKETs von außen nicht angesprochen
+werden, sofern sie nicht über die Schnittstelle "nach außen gereicht" wird.
+Damit wird gewährleistet, daß mehrere Programmierer an einem gemeinsamen
+Projekt arbeiten können und daß eine gemeinsame Benutzung (oder Störung) von
+Programmteilen nur über die in den Schnittstellen von PACKETs aufgeführten
+Objekte erfolgen kann.
+
+Im Gegensatz zu einer Prozedur kann ein PACKET nicht aufgerufen werden (nur
+die Elemente der Schnittstelle können benutzt werden). Beispiel:
+
+
+Programm 32:
+
+ PACKET fuer eine prozedur DEFINES swap:
+
+ PROC swap (INT VAR a, b):
+ INT CONST x :: a;
+ b := a;
+ a := x
+ END PROC swap
+
+ END PACKET fuer eine prozedur
+
+Dies ist ein PACKET, das eine Tausch-Prozedur für INT-Datenobjekte bereit-
+stellt. Das PACKET kann übersetzt werden und dem ELAN-Compiler bekannt
+gemacht werden (EUMEL: "insertieren"). Ist das geschehen, kann man 'swap'
+wie alle anderen Prozeduren (z.B. 'put', 'get') in einem Programm verwenden.
+Tatsächlich werden die meisten Prozeduren und Operatoren (aber auch einige
+Datentypen), die in ELAN zur Verfügung stehen, nicht durch den ELAN-Compiler
+realisiert, sondern durch solche PACKETs. Um solche Objekte einigermaßen
+zu standardisieren, wurde in der ELAN-Sprachbeschreibung festgelegt, welche
+Datentypen, Prozeduren und Operatoren in jedem ELAN-System vorhanden
+sein müssen. Solche PACKETs werden Standard-Pakete genannt. Jeder Installa-
+tion - aber auch jedem Benutzer - steht es jedoch frei, zu den Standard-
+Paketen zusätzliche PACKETs mit in den Compiler aufzunehmen und damit den
+ELAN-Sprachumfang zu erweitern.
+
+Ein ELAN-PACKET beginnt mit dem PACKET-Schlüsselwort. Danach folgt der Name
+des PACKETs (der am Ende des PACKETs hinter END PACKET wieder erscheinen
+muß), gefolgt von der DEFINES-Liste. In dieser Schnittstelle werden die Ob-
+jekte angegeben, die nachfolgenden PACKETs zur Verfügung gestellt werden
+sollen.
+
+In der Schnittstelle werden Prozeduren/Operatoren nur mit ihrem Namen ange-
+geben. Weiterhin können Datentypen und mit CONST vereinbarte Datenobjekte
+in der Schnittstelle aufgeführt werden, aber keine VAR-Datenobjekte, weil
+diese sonst über PACKET-Grenzen hinweg verändert werden könnten.
+
+Im obigen Programm 32 haben wir ein PACKET in der Funktion als spracher-
+weiterndes Instrument gezeigt. Im folgenden Beispiel zeigen wir ein Programm,
+in dem das PACKET-Konzept verwandt wird, um Datenobjekte vor unbefugten
+Zugriff zu schützen.
+
+
+Programm 33:
+
+ PACKET stack handling DEFINES push, pop, init stack:
+
+ LET max = 1000;
+ ROW max INT VAR stack;
+ INT VAR stack pointer;
+
+ PROC init stack:
+ stack pointer := 0
+ END PROC init stack;
+
+ PROC push (INT CONST dazu wert):
+ stack pointer INCR 1;
+ IF stack pointer > max
+ THEN errorstop ("stack overflow")
+ ELSE stack [stack pointer] := dazu wert
+ END IF
+ END PROC push;
+
+ PROC pop (INT VAR von wert):
+ IF stack pointer = 0
+ THEN errorstop ("stack empty")
+ ELSE von wert := stack [stack pointer];
+ stack pointer DECR 1
+ END IF
+ END PROC pop
+
+ END PACKET stack handling;
+
+Nun kann man den Stack über die Prozeduren 'init stack', 'push' und 'pop'
+benutzen (in einem 'main packet').
+
+
+Programm 34:
+
+ init stack;
+ werte einlesen und pushen;
+ werte poppen und ausgeben.
+
+ werte einlesen und pushen:
+ INT VAR anzahl :: 0, wert;
+ REP
+ get (wert);
+ push (wert);
+ anzahl INCR 1
+ UNTIL ende kriterium END REP.
+
+ werte poppen und ausgeben:
+ INT VAR i;
+ FOR i FROM 1 UPTO anzahl REP
+ pop (wert);
+ put (wert)
+ END REP.
+
+Die Datenobjekte 'stack' und 'stack pointer' haben nur Gültigkeit innerhalb
+des PACKETs 'stack handling'. Anweisungen wie z.B.
+
+ put (stack [3]);
+ stack [27] := 5
+
+außerhalb des PACKETs 'stack handling' sind also verboten und werden vom
+ELAN-Compiler entdeckt.
+
+Ein PACKET bietet also auch einen gewissen Schutz vor fehlerhafter Verwen-
+dung von Programmen und Datenobjekten. Wichtig ist weiterhin, daß die Reali-
+sierung des Stacks ohne weiteres geändert werden kann, ohne daß Benutzer-
+programme im 'main packet' geändert werden müssen, sofern die Schnittstelle
+nicht verändert wird. Beispielsweise kann man sich entschließen, den Stack
+nicht durch eine Reihung, sondern durch eine gekettete Liste zu realisieren.
+Davon bleibt ein Benutzerprogramm unberührt.
+
+Die letzte Funktion von PACKETs ist die Realisierung von abstrakten Daten-
+typen. Dazu müssen wir uns aber zuvor die Möglichkeiten anschauen, neue
+Datentypen zu definieren.
+
+
+
+Die Definition neuer Datentypen
+
+Im Gegensatz zur LET-Vereinbarung, bei der lediglich ein neuer Name für
+einen bereits vorhandenen Datentyp eingeführt wurde und bei der somit auch
+keine neuen Operationen definiert werden müssen (weil die Operationen für
+den abzukürzenden Datentyp verwandt werden können), wird durch eine TYPE-
+Vereinbarung ein gänzlich neuer Datentyp eingeführt. Im Gegensatz zu
+Strukturen und Reihungen stehen für solche Datentypen noch nicht einmal die
+Zuweisung zur Verfügung. Beispiel:
+
+ TYPE PERSON = STRUCT (TEXT name, vorname, INT alter)
+
+Ein solcher Datentyp kann wie auch alle anderen Datentypen verwandt werden
+(Deklarationen, Parameter, Werte liefernde Prozeduren, als Komponenten in
+Reihungen und Strukturen usw.).
+
+Der neudefinierte Datentyp wird abstrakter Datentyp genannt. Er kann mit
+Hilfe eines PACKETs (vergl. nächsten Abschnitt) anderen Programmteilen zur
+Verfügung gestellt werden. Die rechte Seite der TYPE-Vereinbarung wird
+"konkreter Typ", "Realisierung des Datentyps" oder Feinstruktur genannt.
+
+Um neue Operatoren und/oder Prozeduren für einen abstrakten Datentyp zu
+schreiben, ist es möglich, auf die Komponenten des Datentyps (also auf die
+Feinstruktur) mit Hilfe des Konkretisierers zuzugreifen. Der Konkretisierer
+arbeitet ähnlich wie die Subskription oder Selektion: er ermöglicht eine
+typmäßige Umbetrachtung vom abstrakten Typ zum Datentyp der Feinstruktur.
+Beispiel:
+
+ TYPE MONAT = INT;
+
+ PROC put (MONAT CONST m):
+ put ( CONCR (m))
+ END PROC put;
+
+Der Konkretisierer ist bei Feinstrukturen notwendig, die von elementarem
+Datentyp sind. Besteht dagegen die Feinstruktur aus Reihungen oder Struk-
+turen, dann wird durch eine Selektion oder Subskription eine implizite Kon-
+kretisierung vorgenommen. Beispiel:
+
+ TYPE LISTE = ROW 100 INT;
+
+ LISTE VAR personal nummer;
+ ...
+ personal nummer [3] := ...
+ (* das gleiche wie *)
+ CONCR (personal nummer) [3] := ...
+
+Denoter für neudefinierte Datentypen werden mit Hilfe des Konstruktors
+gebildet:
+
+ TYPE GEHALT = INT;
+
+ GEHALT VAR meins :: GEHALT : (1 000 000);
+
+Besteht die Feinstruktur aus einem Datenverbund, muß der Konstruktor u.U.
+mehrfach geschachtelt angewandt werden:
+
+ TYPE KOMPLEX = ROW 2 REAL;
+
+ KOMPLEX CONST x :: KOMPLEX : ( ROW 2 REAL : ( 1.0, 2.0));
+
+
+
+Abstrakte Datentypen
+
+Auf die Feinstruktur über den Konkretisierer eines neudefinierten Datentyps
+darf nur in dem PACKET zugegriffen werden, in dem der Datentyp definiert
+wurde. Der Konstruktor kann ebenfalls nur in dem typdefinierenden PACKET
+verwandt werden.
+
+Wird der Datentyp über die Schnittstelle des PACKETs anderen Programmteilen
+zur Benutzung zur Verfügung gestellt, so müssen Operatoren und/oder Proze-
+duren für den Datentyp ebenfalls "herausgereicht" werden. Da dann der neude-
+finierte Datentyp genauso wie alle anderen Datentypen verwandt werden kann,
+aber die Komponenten nicht zugänglich sind, spricht man von abstrakten
+Datentypen.
+
+Welche Operationen sollten für einen abstrakten Datentyp zur Verfügung
+stehen? Obwohl das vom Einzelfall abhängt, werden meistens folgende
+Operationen und Prozeduren definiert:
+
+- 'get'- und 'put'-Prozeduren.
+- Zuweisung (auch für die Initialisierung notwendig).
+- Denotierungs-Prozedur (weil kein Konstruktor für den abstrakten Datentyp
+ außerhalb des definierenden PACKETs zur Verfügung steht)
+
+
+Programm 35:
+
+ PACKET widerstaende DEFINES WIDERSTAND, REIHE, PARALLEL, :=, get, put:
+
+ TYPE WIDERSTAND = INT;
+
+ OP := (WIDERSTAND VAR l, WIDERSTAND CONST r):
+ CONCR (l) := CONCR (r)
+ END OP :=;
+
+ PROC get (WIDERSTAND VAR w):
+ INT VAR i;
+ get (i);
+ w := WIDERSTAND : (i)
+ END PROC get;
+
+ PROC put (WIDERSTAND CONST w):
+ put (CONCR (w))
+ END PROC put;
+
+ WIDERSTAND OP REIHE (WIDERSTAND CONST l, r):
+ WIDERSTAND : ( CONCR (l) + CONCR (r))
+ END OP REIHE;
+
+ WIDERSTAND OP PARALLEL (WIDERSTAND CONST l, r):
+ WIDERSTAND :
+ ((CONCR (l) * CONCR (r)) DIV (CONCR (l) + CONCR (r)))
+ END OP PARALLEL
+
+ END PACKET widerstaende
+
+Dieses Programm realisiert den Datentyp WIDERSTAND und mit den Operationen
+eine Fachsprache, mit dem man nun leicht WIDERSTANDs-Netzwerke berechnen
+kann, wie z.B. folgendes:
+
+
+ +--- R4 ---+
+ | |
+ +--- R1 ---+ +--- R5 ---+
+ | | | |
+ ---+ +--- R3 ---+ +---
+ | | | |
+ +--- R2 ---+ +--- R6 ---+
+ | |
+ +--- R7 ---+
+
+Zur Berechnung des Gesamtwiderstandes kann nun folgendes Programm
+geschrieben werden:
+
+ ROW 7 WIDERSTAND VAR r;
+ widerstaende einlesen;
+ gesamtwiderstand berechnen;
+ ergebnis ausgeben.
+
+ widerstaende einlesen:
+ INT VAR i;
+ FOR i FROM 1 UPTO 7 REP
+ put ("bitte widerstand R"); put (i); put (":");
+ get (r [i]);
+ END REP.
+
+ gesamtwiderstand berechnen:
+ WIDERSTAND CONST rgesamt :: (r [1] PARALLEL r [2]) REIHE
+ r [3] REIHE (r [4] PARALLEL r [5] PARALLEL r [6]
+ PARALLEL r [7]).
+
+ ergebnis ausgeben:
+ line;
+ put (rgesamt).
+
+
+Aufgabe (HSG):
+
+ Was ist ein Modul? Was ist ein Interface? Was ist der Unterschied
+ zwischen einem PACKET und einer Prozedur?
+ Die Realisierung von WIDERSTAND durch INTs ist nicht in allen Fällen
+ befriedigend. Warum? (Beachte besonders die Realisierung des OP
+ PARALLEL).
+ Wenn man bei der Typ-Vereinbarung von WIDERSTAND INT gegen REAL
+ austauschen würde, wo müßte man noch Änderungen vornehmen? Sind
+ insbesondere Änderungen im Benutzer-Programm (hier im 'main packet')
+ notwendig?
+Übungsziel: PACKET-Begriff
+
+
+
+Programmstruktur 2
+
+Nun können wir auch erklären, wie ein ELAN-Programm mit mehreren PACKETs
+aussieht. Ein Programm besteht aus einer Folge von PACKETs, dem ein 'main
+packet' folgt. Es ist auch möglich, PACKETs vorübersetzen zu lassen, so daß
+es für einen Nutzer so aussieht, als ob er nur ein 'main packet' übersetzen
+läßt. Tatsächlich sind zumindest die Standard-Packets vorübersetzt vorhanden.
+
+
diff --git a/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil7 b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil7
new file mode 100644
index 0000000..1aadc5f
--- /dev/null
+++ b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil7
@@ -0,0 +1,2469 @@
+ EUMEL-Benutzerhandbuch
+
+ TEIL 7: Dateien, Datei-Verwaltung und Datenräume
+
+1. Übersicht
+
+Dateien dienen zur Aufnahme von Informationen, die auch über die Bearbei-
+tungszeit eines Programms erhalten bleiben (können). Dateien werden als
+Objekte in einer Task gehalten. Sie bleiben solange erhalten, bis sie expli-
+zit gelöscht ('forget'-Kommando) oder die Task beendet wird ('end'-Kommando).
+
+Dateien kann man an andere Tasks schicken ('save'-Kommando) oder von anderen
+Tasks holen ('fetch'-Kommando). Mit diesen (hier vorgestellten) Kommandos
+ist der Transport von Dateien jedoch nur in direkter Linie des Task-Baums
+möglich, also an einen "Vater" oder einen "Sohn". Damit ist automatisch eine
+Datei-Hierarchie im EUMEL-System realisiert.
+
+Alle Datei-Arten des EUMEL-Systems basieren auf Datenräumen. Ein Datenraum
+ist ein Speicherplatz, der 1 MByte Daten speichern kann und vom EUMEL-System
+verwaltet wird. Datenräume können gelöscht, kopiert usw. werden. Mit Hilfe
+Mit Hilfe von Datenräumen werden alle Datei-Arten des EUMEL-Systems reali-
+siert, indem einem Datenraum eine Struktur (Datentyp) aufgeprägt wird. Da-
+durch wird es Benutzern des EUMEL-Systems ermöglicht, auf einfache Weise
+neben den bereits vorhandenen Datei-Arten (FILEs für die Speicherung von
+Texten, PICFILEs für die Speicherung von Bildinformationen, u.a.m.)
+spezielle Dateien zu konstruieren.
+
+Die wichtigste Datei-Art, mit der ein Benutzer in Berührung kommt, ist die
+sequentielle Datei, genannt FILE. Ein FILE kann nur TEXTe aufnehmen und hat
+z.Zt. ein Fassungsvermögen von 4000 Zeilen (Sätze). Insgesamt darf ein FILE
+1 MByte aufnehmen. Eine Datei-Zeile (Satz) kann bis zu 32 000 Zeichen auf-
+nehmen.
+
+FILEs können in einer von drei Betriebsrichtungen bearbeitet werden:
+- "input": nur Lesen.
+- "output": nur Schreiben.
+- "modify": Lesen/Schreiben und zusätzlich beliebiges Positionieren, Ein-
+ fügen und Löschen von Sätzen.
+
+'input'-Dateien sind also Eingabedateien, 'output'- sind Ausgabedateien und
+'modify'-Dateien kann man verändern. Insbesondere die 'modify'-Dateien eig-
+nen sich, um andere Datei-Arten leicht zu realisieren (z.B. indexsequentiel-
+le Dateien).
+
+Eine Datei kann auf einen bestimmten Zeilenbereich eingeschränkt werden. Ein
+solches Segment kann selbst wie eine Datei von einem Programm behandelt
+werden.
+
+
+
+2. Datei-Kommandos
+
+Dateien werden in der Regel in einer Benutzer-Task gehalten. Die Kommandos
+für die Behandlung von Dateien in einer Benutzer-Task werden hier vorge-
+stellt. Dann wird erklärt, wie Dateien zu einer übergeordneten Task ge-
+schickt oder geholt werden können.
+
+
+
+Datei-Kommandos für Benutzer-Tasks
+
+Im Monitor-Dialog kann man Dateien kopieren, löschen und einen anderen Namen
+geben.
+
+Mit dem Kommando
+
+ edit ("dateiname")
+
+wird eine Text-Datei im Monitor-Dialog (implizit) eingerichtet, wenn es sich
+um einen noch nicht vorhandenen 'dateiname' handelt (vergl. auch die Editor-
+Beschreibung).
+
+Welche Dateien in der Benutzer-Task vorhanden sind, kann mit dem Kommando
+
+ list
+
+erfragt werden. 'list' zeigt auf dem Bildschirm die Dateinamen der Benutzer-
+Task. Vor jedem Namen steht ein Datum, welches anzeigt, an welchem Tag die
+Datei zuletzt von einem Programm bearbeitet wurde. Ein 'a' hinter dem Datum
+kennzeichnet Dateien, die nach einer Archivierung nicht bearbeitet wurden.
+
+Ein Duplizieren einer Datei kann mit
+
+ copy ("alte datei", "neue datei")
+
+erreicht werden, wobei eine Kopie von 'alter datei' angelegt wird, die den
+Namen 'neue datei' erhält. Man beachte, daß es sich um eine logische (und
+vorerst um keine physikalische) Kopie handelt. Erst bei Schreibzugriffen
+werden Seiten " entshared" ("copy-on-write"). Ein Umbenennen einer Datei
+kann mit
+
+ rename ("alter datei name", "neuer datei name")
+
+erfolgen. Mit
+
+ forget ("dateiname")
+
+kann eine Datei gelöscht werden.
+
+Wurde in einer Datei editiert, kann durch Löschen oder Einfügen von Zeilen
+der interne Verwaltungsaufwand hoch werden, so daß Positionierungen nicht
+mehr effizient vor sich gehen. Mit dem Kommando
+
+ reorganize ("dateiname")
+
+wird die Datei so organisiert, als wenn sie neu erstellt wäre (gilt nur für
+Text-Dateien). Sie braucht dann in der Regel auch etwas weniger Speicher-
+platz.
+
+
+Merke: Das Kommando 'rename' gibt einer Datei einen anderen Namen, 'copy'
+dupliziert eine Datei. Mit 'list' kann man sich anzeigen lassen, welche
+Dateien in der Task vorhanden sind.
+
+
+
+Datei-Kommandos für Vater-Tasks
+
+Man kann Dateien von einer Vater-Task holen oder an eine Vater-Task schicken,
+um sie dort längerfristig zu speichern. Auch wenn die Benutzer-Task gelöscht
+wird, bleiben alle Dateien, die bei einer Vater-Task gespeichert (also
+"gerettet") sind, erhalten. Andere Sohn-Tasks können sich Dateien bei einer
+Vater-Task abholen.
+
+Auf Dateien einer Benutzer-Task können andere Nutzer aus anderen Tasks in
+der Regel nicht zugreifen. Manchmal ist es jedoch notwendig, daß mehrere
+Nutzer Dateien gemeinsam benutzen oder eine Datei eine Task "überleben" soll.
+In solchen Fällen muß man Dateien bei einem Vater aufbewahren.
+
+Mit der Prozedur
+
+ global manager
+
+kann die Benutzer-Task zu einem Datei-Manager gemacht werden. Erst nach
+Aufruf dieser Prozedur können Söhne dieser Task eingerichtet werden.
+
+Von einer Benutzer-Task kann eine Datei mit
+
+ save ("Buch 1")
+
+der direkten Vater-Task übergeben werden, wobei 'buch 1' in der Benutzer-
+Task erhalten bleibt. 'save' wirkt also wie ein Transport einer Kopie der
+angegebenen Datei in die Vater-Task. Achtung: ist eine Datei 'Buch 1' in der
+Vater-Task bereits vorhanden, wird diese ohne Warnung überschrieben.
+
+Analog zu der 'forget'-Prozedur für Dateien einer Benutzer-Task können
+Dateien einer unmittelbaren Vater-Task mit
+
+ erase ("datei name")
+
+gelöscht werden. Soll eine Datei von einer Vater-Task in eine Benutzer-Task
+geholt werden, so benutzt man die Prozedur
+
+ fetch ("datei")
+
+Nach Aufruf dieser Prozedur wird eine Kopie der angegebenen Datei in der
+Benutzer-Task angelegt. Ist bereits eine Datei 'datei' in der Benutzer-Task
+vorhanden, so erfolgt eine Fehlermeldung.
+
+Mit 'save', 'fetch' und 'erase' ist es möglich, daß zwei oder mehr Benutzer
+eine Datei alternierend bearbeiten. In diesem Fall müssen sich die Benutzer
+als Söhne einer gemeinsamen Vater-Task einrichten und die Datei mit 'fetch'
+jeweils in die Benutzer-Task holen. Um zu verhindern, daß ein anderer Be-
+nutzer zur gleichen Zeit mit der Datei arbeitet, wird sie jeweils mit 'erase'
+bei der Vater-Task gelöscht. Nach Beendigung der Arbeiten muß die Datei dann
+wieder mit 'save' in die Vater-Task transportiert werden. Dann steht sie
+wieder anderen Benutzern zur Verarbeitung zur Verfügung. Beispiel:
+
+ fetch ("datei"); erase ("datei"); (* Datei vom Vater holen und dort
+ loeschen *)
+ edit ("datei"); (* Datei bearbeiten *)
+ save ("datei"); (* Datei zur Vater-Task bringen *)
+ forget ("datei") (* Datei in Benutzer-Task
+ loeschen *)
+
+Mit den Prozeduren
+
+ save all
+ fetch all
+
+kann man alle Dateien einer Benutzer-Task in die direkte Vater-Task schicken
+oder von dort holen.
+
+Merke:
+ * * * * * * * * * *
+ * *
+ * <-+ * Vater-Task
+ * | | *
+ * * * | * * | * * *
+ | |
+ fetch save
+ | |
+ * * * | * * | * * *
+ * | | *
+ * ->edit| * Benutzer-Task
+ * *
+ * * * * * * * * * *
+
+
+
+Ansprechen von anderen Tasks
+
+Sollen Dateien in andere als die direkte Vater-Task transportiert oder von
+anderen Tasks geholt werden, muß man den internen Task-Bezeichner angeben.
+
+Es gibt einige Prozeduren, mit denen man den internen Task-Bezeichner einer
+Task bekommt. Solch eine Prozedur ist
+
+ father
+
+Prozeduren, mit denen man Dateien transportieren kann, liegen auch in einer
+Version vor, bei denen man den internen Task-Bezeichner angeben kann.
+Beispiel:
+
+ save ("datei", father) (* wie: save ("datei") *)
+ erase ("datei", father) (* wie: erase ("datei") *)
+ fetch ("datei", father) (* wie: fetch ("datei") *)
+
+Weitere Prozeduren, die einen internen Task-Bezeichner liefern, sind:
+
+ myself
+ printer
+ public
+ archive
+
+Anmerkung: Zur Prozedur 'archive' siehe auch das nächste Kapitel; zu 'print'
+siehe auch SPOOLER. Dadurch kann man Dateien auch zu anderen als der
+Vater-Task transportieren, holen oder löschen. Beispiele:
+
+ erase ("datei", public) (* Loescht 'datei' in Task 'PUBLIC' *)
+ fetch ("datei", public) (* Holt 'datei' aus der Task "PUBLIC" *)
+ save ("datei", public) (* Kopiert 'datei' in die Task 'PUBLIC' *)
+ save ("datei", printer) (* Uebergibt 'datei' dem Spooler und
+ druckt die Datei *)
+ list (father) (* Listet Dateien der Vater-Task *)
+
+Bei komplizierten "Verwandschafts-Verhältnisse" von Tasks ist es einfacher,
+eine Task mit Hilfe des Task-Namens anzusprechen. Das erfolgt mit Hilfe der
+Prozedur 'task'. Beispiel:
+
+ save ("datei", task ("hugo"))
+
+'task' liefert den internen Task-Bezeichner von 'hugo'. Die Umkehr-Prozedur
+zu 'task' ist 'name':
+
+ put (name (myself))
+
+schreibt den Namen der Task, in der man sich gerade befindet, auf den Bild-
+schirm.
+
+Durch die Prozedur 'father', die einen internen Task-Bezeichner als
+Parameter erwartet, kann man an die Vater-Task einer Task gelangen.
+Beispiel:
+
+ save ("datei", father (father))
+
+Hier wird die Datei 'datei' an die Vater-Task der Vater-Task geschickt (also
+zur "Großvater-Task").
+
+Mit dem Operator /
+
+kann man aus einem Tasknamen den internen Tasknamen erhalten. '/' kann über-
+all dort eingesetzt werden, wo ein interner Taskname verlangt wird. Beispiel:
+
+ task status (/"meine task")
+
+
+Merke: Mit den internen Task-Bezeichner kann man mit anderen Tasks als der
+Vater-Task kommunizieren.
+
+
+
+Kommandos für mehrere Dateien
+
+Durch die vom EUMEL-System bereitgestellten Task-Variablen und Datei-Ver-
+zeichnisse (Thesaurus, Plural: Thesauren) ist es möglich, mehrere Dateien
+mit einem Kommando zu behandeln.
+
+Sollen alle Dateien einer Task zu einer anderen transportiert werden (mit
+'save') oder alle Dateien geholt werden, kann man 'save all' und 'fetch all'
+auch mit einem internen Task-Bezeichner versehen. Beispiele:
+
+ save all (public)
+ fetch all (public)
+
+Damit werden alle Dateien der Benutzer-Task zu der Task 'PUBLIC' geschickt
+oder von dort geholt.
+
+Die internen Tasknamen wie z.B. 'myself', 'father', 'public' usw. werden
+auch bei dem Einsatz eines Thesaurus benutzt. Was ist ein "Thesaurus"?
+
+Das EUMEL-System hält sich die Dateinamen einer Task des Taskbaums in einer
+internen Liste. Die Namens-Liste wird Thesaurus (laut Duden: ein
+"systematisch geordnetes Verzeichnis") genannt.
+
+Der Operator ALL liefert den Thesaurus einer Task. Beispiel:
+
+ ALL father
+ ALL myself
+
+liefert jeweils den Thesaurus der Vater- oder der eigenen Task. Solche
+Thesauren kann man als Parameter der meisten der oben erwähnten Kommandos
+verwenden:
+
+ save (ALL myself) (* kopiert alle Dateien in die Vater-Task;
+ arbeitet wie 'save all' *)
+ forget (ALL myself) (* loescht alle Dateien der Benutzer-Task *)
+ fetch (ALL father) (* holt alle Dateien der Vater-Task;
+ arbeitet wie 'fetch all' *)
+
+Der Operator SOME dagegen bietet einen Thesaurus vorher zum Editieren an,
+um Dateinamen zu streichen (HOP RUBOUT). Beispiele:
+
+ fetch (SOME father) (* holt die nicht gestrichenen Dateien *)
+ save (SOME myself) (* kopiert die nicht gestrichenen Dateien *)
+ forget (SOME myself) (* loescht die nicht gestrichenen Dateien *)
+
+Es ist auch möglich, aus den Thesauren mehrerer Tasks einen neuen Thesaurus
+zu bilden:
+
+ - (* Differenzmenge *)
+ / (* Schnittmenge *)
+ + (* Vereinigungsmenge *)
+
+Beispiel:
+
+ fetch (ALL father - ALL myself)
+
+holt alle Dateien der Vater-Task, die nicht bereits in der Benutzer-Task
+sind.
+
+
+Merke: Mit den Operatoren 'ALL' und 'SOME' kann man mehrere Dateien mit
+einem Kommando behandeln.
+
+
+
+Datei-Schutz durch Paßworte und Verschlüsselung
+
+Dateien können vor unbefugtem Zugriff mit Hilfe von Paßworten und/oder der
+Verschlüsselung der Informationen geschützt werden.
+
+
+
+Paßworte
+
+Paßworte für Dateien dienen zur Verhinderung von unbefugtem Zugriff auf
+Dateien, die bei einer Vater-Task gespeichert werden. (Die Dateien der
+Benutzer-Task können durch ein Task-Paßwort geschützt werden). Dabei sollte
+man bedenken, daß Paßworte bekannt werden können.
+
+Der Paßwort-Schutz ist im EUMEL-System etwas sicherer als in anderen
+Betriebssystemen, weil Paßworte nur selten angegeben werden müssen und
+daher nicht so leicht bekannt werden können (z.B. durch "über die Schulter
+schauen"). Die Kommandozeile wird zudem bei der Angabe eines Paßworts nach
+dem Betätigen der RETURN-Taste gelöscht.
+
+Paßworte werden nur im Verkehr mit Vater-Tasks eingesetzt. Lokale Benutzer-
+Dateien brauchen nicht gesondert gesichert zu werden, da man ein Paßwort
+auf die Benutzer-Task legen kann oder die zu sichernden Dateien aus dem
+System nehmen kann. Ein Paßwort kann mit der Prozedur
+
+ enter password ("schreibpasswort / lesepasswort")
+
+angegeben oder ein bereits eingestelltes Paßwort kann mit dieser Prozedur
+überschrieben werden. Voreingestellt ist kein Paßwort. Nachdem ein Benutzer
+die 'enter password'-Prozedur angegeben hat, wird jeder Datei-Verkehr mit
+einer Vater-Task mit Hilfe dieses Paßworts überprüft. Unzulässige Zugriffe
+durch Benutzer anderer Tasks auf Dateien einer Vater-Task werden abgewiesen.
+
+Ein Paßwort hat eine eigene Syntax. Es besteht aus zwei Teilen, die leer
+sein können und die durch ein "/"-Zeichen voneinander getrennt sind. Der
+erste Teil ist das Schreib-Paßwort, der zweite das Lese-Paßwort. Wird kein
+Lese-Paßwort angegeben, gilt das Schreib-Paßwort auch für das Lesen. Ist
+also kein "/"-Zeichen im Paßwort-String vorhanden, so wird das Schreib-
+Paßwort sozusagen gedoppelt. Beispiele:
+
+ enter password ("") (* kein Paßwort *)
+ enter password ("hugo") (* 'hugo' gilt fuer das Schreiben und
+ Lesen *)
+ enter password ("egon/meier") (* 'egon' fuers Schreiben, 'meier' fuers
+ Lesen *)
+
+Zusätzlich kann das "-"-Zeichen in dem Teil des Paßworts angegeben werden,
+für den ein Zugriff nicht erlaubt sein soll. Beispiel:
+
+ enter password ("-/nurlesen") (* Schreibzugriff nicht erlaubt,
+ Lese-Passwort ist 'nurlesen' *)
+
+Das Lese-Paßwort gilt für die Prozedur
+
+ fetch
+
+während das Schreib-Paßwort für die Prozeduren
+
+ save
+ erase
+
+gilt. Sofern die betreffende Datei durch ein Paßwort geschützt ist, ist
+folgendes zu beachten:
+
+a) fetch:
+ Will ein Benutzer mit der Prozedur 'fetch' eine Datei in seine Benutzer-
+ Task holen, so wird sein aktuell eingestelltes Paßwort (nur Lese-Teil)
+ und das Paßwort der Datei überprüft. Stimmen diese nicht überein, so wird
+ der 'fetch'-Zugriff auf eine Datei der Vater-Task abgewiesen.
+
+b) save:
+ Bei einem Transport in eine Vater-Task mit Hilfe der Prozedur 'save' sind
+ zwei Fälle zu unterscheiden:
+
+ - Datei ist in der Vater-Task noch nicht vorhanden: Diese Datei wird
+ in der Vater-Task mit dem aktuellen Paßwort des Benutzers einge-
+ tragen.
+
+ - Datei ist in der Vater-Task bereits vorhanden und soll durch die
+ neue Datei ersetzt werden: Es wird überprüft, ob das aktuelle
+ Schreib-Paßwort des Benutzers mit dem der gleichnamigen Datei in der
+ Vater-Task übereinstimmt. Ist dies nicht der Fall, wird die Datei
+ nicht in der Vater-Task eingetragen.
+
+c) erase:
+ Soll eine Datei der Vater-Task gelöscht werden, wird überprüft, ob das
+ aktuelle Schreib-Paßwort mit dem der zu löschenden Datei in der Vater-
+ Task übereinstimmt. Ist dies nicht der Fall, wird die Lösch-Operation
+ abgewiesen.
+
+
+Merke: Dateien können bei der Sicherung in einer Vater-Task vor unbefugtem
+Zugriff durch Paßworte geschützt werden.
+
+
+
+Dateien verschlüsseln
+
+Zusätzlich zu einem Paßwort kann man eine Datei vor unbefugtem Zugriff
+schützen, indem sie verschlüsselt wird.
+
+Mit den Prozeduren
+
+ crypt
+ decrypt
+
+kann eine Datei ver- oder entschlüsselt werden (Datenschutz für einzelne
+Dateien). Dabei ist es möglich, eine Datei mehrfach zu verschlüsseln (man
+muß die Verschlüsselung dann allerdings auch mehrfach rückgängig machen).
+Beispiel:
+
+ crypt ("datei", "schluessel")
+
+verschlüsselt 'datei' mit 'schluessel'. Die Entschlüsselung erfolgt, indem
+man die Prozedur 'decrypt' auf 'datei' anwendet und den gleichen Schlüssel
+zur Entschlüsselung benutzt. Beispiel:
+
+ decrypt ("datei", "schluessel")
+
+Den Text des Schlüssels (hier: 'schluessel') sollte man sich also unbedingt
+merken, sonst kann die Datei nicht mehr entschluesselt werden.
+
+Merke: Dateien werden durch 'crypt' und 'decrypt' ver- und entschlüsselt.
+
+
+
+3. Das Archiv
+
+Dateien werden im EUMEL-System auf Systemträgern gespeichert. Mit dem Archiv
+können Dateien vom System auf externe Speichermedien (normalerweise
+Disketten) gebracht und von diesen ins System geholt werden.
+
+Das EUMEL-Archiv hat folgende Aufgaben:
+
+a) Das Archiv wird als Sicherheitsbereich benutzt, indem man von wichtigen
+ Dateien Kopien anlegt und diese außerhalb des EUMEL-Systems speichert.
+
+b) Man kann das Archiv-System aber auch benutzen, um Dateien, die nur selten
+ oder in größeren Zeitabständen benötigt werden, zu kopieren ("archi-
+ vieren") und im EUMEL-System zu löschen. Falls diese Dateien wieder
+ gebraucht werden, können sie wieder in das EUMEL-System geholt werden.
+ Damit wird erreicht, daß im EUMEL-System nur die wirklich notwendigen
+ Dateien stehen.
+
+c) Sollen Dateien von einer EUMEL-Installation auf eine andere übertragen
+ werden, so kann man ebenfalls Archive verwenden.
+
+d) Bei Versionswechsel des EUMEL-Systems sind Archive die einzige Möglich-
+ keit, Dateien in die neue Systemversion einzuspielen. Dabei wird garan-
+ tiert, daß zumindest Archive der letzten Version gelesen werden können.
+
+Merke: Durch das Archiv können Dateien außerhalb des Systems gesichert
+werden.
+
+
+
+Das Archiv reservieren
+
+Soll archiviert werden, muß man das dem Archiv-System mitteilen, damit nicht
+ein anderer Benutzer zur gleichen Zeit auf das Archiv zugreift. Dieser
+Vorgang wird "reservieren" genannt.
+
+Archiv-Disketten haben aus Sicherheitsgründen einen Namen. Dieser Name muß
+bei der Anmeldung einer Archivierung angegeben werden. Die Anmeldung einer
+Archivierung und gleichzeitige Reservierung erfolgt mit
+
+ archive ("name")
+
+Der Archiv-Name wird bei folgenden Archiv-Operationen zur Überprüfung mit
+dem eingelegten Archiv verwandt.
+
+Wichtig: Eine Diskette sollte erst nach dem 'archive'-Kommando in das
+Laufwerk geschoben werden, d.h. erst dann, wenn das Archiv-System reserviert
+ist. Sonst kann es geschehen, daß ein anderer Benutzer auf dieser Diskette
+archiviert.
+
+Archivierungen erfolgen durch die schon beschriebenen Transportkommandos
+'save' und 'fetch'. Dabei wird als Zieltask 'archive' angegeben. Beispiel:
+
+ save ("mein buch", archive)
+ fetch ("kapitel 1", archive)
+ save all (archive)
+ fetch all (archive)
+
+Das Archiv bleibt für den Nutzer solange reserviert, wie er Archivierungs-
+operationen vollzieht. Dann sollte er das Archiv wieder für andere Benutzer
+mit der Prozedur
+
+ release (archive)
+
+freigeben.
+
+Leitet ein Nutzer innerhalb von fünf Minuten nach der letzten Archiv-
+Operation keine neue ein und meldet sich ein anderer Nutzer mit 'archive'
+bei dem Archiv-System an, so wird dem ersten Nutzer die Archiv-Berechtigung
+entzogen, um Blockaden zu verhindern. Wenn der erste Nutzer eine erneute
+Archiv-Operation versucht, erhält er eine Fehlermeldung. Dadurch kann ein
+Nutzer das Archiv längere Zeit (ohne 'release') benutzen, ohne den Betrieb
+zu stören, da andere Nutzer bei Bedarf jederzeit eingeschoben werden.
+
+Wichtig: Muß die Archiv-Floppy gewechselt werden (weil etwa von einer
+Diskette eine Datei gelesen wurde und diese auf eine andere geschrieben
+werden soll), muß erneut das 'archive'-Kommando gegeben werden. Dies ist
+notwendig, um das Verzeichnis aller auf der Diskette befindlichen Dateien
+der neuen Diskette zu lesen.
+
+Merke: Mit 'archive' wird die Archiv-Verwaltung für einen Nutzer reserviert, mit 'release' wieder freigegeben. Mit 'archive' wird
+gleichzeitig ein Archiv-Name eingestellt, der bei Archiv-Operationen mit dem
+auf der Diskette gespeicherten Archiv-Namen verglichen wird.
+
+
+
+Archiv löschen und einen Namen geben
+
+Bevor ein Archiv-Diskette benutzt werden kann, muß sie den mit 'archive'
+eingestellten Namen bekommen.
+
+Bei der Erstbenutzung eines Archivs muß dieses mit einem Namen versehen
+werden. Als Archiv-Name wird der mit 'archive' eingestellte Name verwandt.
+Dies erfolgt mit der Prozedur
+
+ clear (archive)
+
+Gleichzeitig werden alle Dateien, die sich eventuell vorher auf dem Archiv-
+Träger befanden, gelöscht. Somit wird 'clear' auch für das Löschen von
+Archiven verwendet.
+
+
+Merke: Mit 'clear' wird die Archiv-Diskette gelöscht und gleichzeitig der
+mit 'archive' eingestellte Name gegeben.
+
+
+
+Einfache Archiv-Operationen
+
+In diesem Abschnitt werden einfache Archiv-Operationen beschrieben.
+
+Mit den Prozeduren
+
+ save ("datei", archive)
+ fetch ("datei", archive)
+ erase ("datei", archive)
+
+kann jeweils eine Datei auf die Archiv-Diskette ('save') und von dem Archiv
+in das EUMEL-System kopiert ('fetch') oder auf dem Archiv gelöscht ('erase')
+werden. Dabei bedeutet 'datei' die zu kopierende Datei und 'archive' der
+interne Task-Name für die Archiv-Verwaltung. Bei den ersten zwei Kommandos
+ist zu beachten, daß die Datei, die auf das Archiv geschrieben (bei 'save')
+oder die in die Benutzer-Task geholt werden soll (bei 'fetch'), immer
+kopiert wird. Dateien bleiben also im "Ursprung" immer erhalten.
+
+Ist eine Datei gleichen Namens bereits auf der Archiv-Diskette (bei 'save')
+oder in der Benutzer-Task (bei 'fetch') vorhanden, wird von der Archiv-Ver-
+waltung angefragt, ob diese Datei überschrieben werden darf. Es kann somit
+nicht zu einem unbeabsichtigten Löschen von Dateien kommen.
+
+Mit dem Kommando
+
+ list (archive)
+
+erhält man (wie bei dem "normalen" 'list'-Kommando) ein Namens-Verzeichnis
+aller Dateien, die sich auf der eingelegten Archiv-Diskette befinden.
+
+
+Merke: Nachdem ein Archiv mit 'archive' reserviert wurde, kann mit 'save'
+eine Datei auf das Archiv geschrieben und mit 'fetch' eine Datei von dem
+Archiv in die Benutzer-Task kopiert werden.
+
+
+
+Archiv-Operationen für mehrere Dateien
+
+Hier wird beschrieben, wie man mehrere Dateien auf einmal auf ein Archiv
+schreibt oder von einem Archiv liest.
+
+Mit den Kommandos
+
+ save all (archive)
+ fetch all (archive)
+
+werden alle Dateien der Benutzer-Task auf das Archiv geschrieben bzw. von
+dort geholt.
+
+Zusätzlich ist es möglich, die Operatoren 'ALL' und 'SOME' auf ein Archiv
+anzuwenden. Wie bereits geschildert, liefern diese Operatoren einen
+Thesaurus der angegebenen Task: 'ALL' liefert alle Dateinamen, während man
+bei 'SOME' eine Auswahl treffen kann. Damit ist es möglich, alle oder einige
+Dateien der Benutzer-Task auf eine Archiv-Diskette zu kopieren oder von der
+Archiv-Diskette in die Benutzer-Task zu holen:
+
+ fetch (SOME archive, archive) (* zeigt die Namen der Dateien der
+ Archiv-Diskette. Die nicht ge-
+ strichenen Dateien werden in die
+ Benutzer-Task geholt *)
+ save (SOME myself, archive) (* zeigt die Namen der Dateien der
+ Benutzer-Task. Die nicht ge-
+ strichenen Dateien werden auf die
+ Archiv-Diskette kopiert *)
+ save (ALL archive, archive) (* sichert alle Dateien der Benutzer-
+ Task, die sich schon auf dem Archiv
+ befinden (alte Version). Das
+ Kommando ist für Sicherungs-
+ Disketten gedacht, bei dem man immer
+ die gleichen Dateien auf dem Archiv
+ haben will *)
+
+Durch die Thesaurus-Operatoren '-' (Differenzmenge), '/' (Schnittmenge) und
+'+' (Vereinigungsmenge) kann man kompliziertere Wirkungen erzielen.
+Beispiele:
+
+ save (ALL myself - ALL archive, archive) (* Schreibt alle Dateien der
+ Benutzer-Task auf das Archiv,
+ die nicht bereits auf dem
+ Archiv stehen *)
+ save (ALL myself - ALL father - ALL archive, archive)
+ (* Schreibt alle Dateien der
+ Benutzer-Task auf das Archiv,
+ mit Ausnahme der Dateien, die
+ längerfristig in der Vater-
+ Task gespeichert sind und die
+ nicht bereits auf dem Archiv
+ stehen *)
+ fetch (ALL archive - ALL myself) (* Holt alle Dateien vom Archiv,
+ die sich nicht bereits in der
+ Benutzer-Task befinden *)
+
+Werden mehrere Dateien mittels eines Thesaurus bearbeitet, kann man nach
+einer Unterbrechung der Bearbeitung (d.h. Fehlermeldung) die Operation wieder
+aufsetzen. Dazu liefert das Kommando
+
+ remainder
+
+den "Rest"-Thesaurus. Er enthält alle nicht bearbeiteten Dateinamen.
+Beispiel:
+
+ save (SOME myself, archive) (* Unterbrechung, z.B. durch einen vom
+ Programm erzeugten 'errorstop' oder SV
+ und 'halt' *)
+ save (remainder, archive) (* bearbeitet die restlichen Dateien *)
+
+
+Merke: Mit 'save all' bzw. 'fetch all' kann man alle Dateien einer Benutzer-
+Task archivieren bzw. alle Dateien eines Archivs in die Benutzer-Task holen.
+Mit den Operatoren SOME und ALL sind weitere Operationen möglich.
+
+
+
+Fehlermeldungen des Archivs
+
+Bei Archiv-Operationen kann es zu Fehlersituationen kommen.
+
+Versucht man eine Datei vom Archiv zu lesen, kann es vorkommen, daß das
+Archiv-System
+
+ Lese-Fehler (Archiv)
+
+meldet und den Lese-Vorgang abbricht. Dies kann auftreten, wenn die Floppy
+beschädigt oder aus anderen Gründen nicht lesbar ist (z.B. nicht justierte
+Disketten-Geräte). In einem solchen Fall vermerkt das Archiv-System intern,
+daß die Datei nicht korrekt gelesen werden kann. Das sieht man z.B. beim
+'list (archive)'. Dort ist der betreffende Datei-Name mit dem Zusatz 'mit
+Lese-Fehler' gekennzeichnet. Um diese Datei trotzdem zu lesen, muß man sie
+im Datei-Namen mit dem Zusatz 'mit Lese-Fehler' versehen. Beispiel:
+
+ fetch ("dateiname mit Lese-Fehler")
+
+Die Datei wird in diesem Fall trotz Lese-Fehler (Informationsverlust!) vom
+Archiv gelesen.
+
+Um solche Fälle möglichst zu vermeiden, sieht das EUMEL-System die
+Möglichkeit vor, Archive bzw. Archiv-Dateien nach beschreiben zu prüfen. Das
+erfolgt mit dem Kommando
+
+ check ("dateiname", archive) (* oder *)
+ check (ALL archive, archive) (* fuer alle Archiv-Dateien *)
+
+Durch dieses Kommando werden eventuelle Lese-Fehler gemeldet.
+
+Weitere Fehlermeldungen des Archivs:
+
+* Lesen unmöglich (Archiv) Archiv-Floppy nicht eingelegt oder die Tür
+ des Laufwerks ist nicht geschlossen.
+
+* Schreiben unmöglich (Archiv) Floppy ist schreibgeschützt.
+
+* Archiv nicht angemeldet Archiv wurde nicht angemeldet
+ ('archive ("name")' geben).
+
+* Lese-Fehler (Archiv) Siehe obige Beschreibung.
+
+* Schreibfehler (Archiv) Die Floppy kann nicht (mehr) beschrieben
+ werden. Andere Floppy verwenden.
+
+* Speicherengpass Im System ist nicht mehr genügend Platz, um
+ eine Datei vom Archiv zu laden.
+ Ggf. Dateien löschen.
+
+* RERUN beim Archiv-Zugriff Das System wurde bei einer Archiv-Operation
+ durch Ausschalten bzw. Reset unterbrochen.
+
+* ... gibt es nicht Die Datei ... gibt es nicht auf dem Archiv.
+
+* Archiv heißt ... Die eingelegte Floppy hat einen anderen als
+ den eingestellten Archiv-Namen.
+
+* Archiv wird von Task ... benutzt Das Archiv wurde von einem anderen
+ Benutzer reserviert.
+
+* ... kann nicht geschrieben werden (Archive voll) Das Archiv ist voll.
+ Neue Archiv-Floppy
+ benutzen.
+
+* Archiv inkonsistent Die eingelegte Floppy hat nicht die Struk-
+ tur einer Archiv-Floppy ('clear (archive)'
+ vergessen).
+
+* save/erase wegen Lese-Fehler verboten Bei Archiven mit Lese-Fehler sind
+ Schreiboperationen verboten, weil
+ ein Erfolg nicht garantiert
+ werden kann.
+
+
+
+4. FILEs in Programmen
+
+Die bisher geschilderten Kommandos gelten für alle Datei-Arten. In diesem
+Kapitel wird der Standard Datei-Typ FILE beschrieben. Eine Datei von Daten-
+typ FILE ist eine sequentielle Datei, die das Lesen und Schreiben von Daten
+in strikter Aufeinanderfolge von Sätzen erlaubt (Betriebsrichtungen 'input'
+und 'output'). Die Betriebsrichtung 'modify' erlaubt das gleichzeitige Lesen
+und Schreiben sowie beliebiges Positionieren.
+
+
+
+Deklaration, Assoziierung und Betriebsrichtungen
+
+Für ELAN-Programme gibt es standardmäßig den Datentyp FILE. FILEs müssen
+deklariert werden. Die Kopplung einer FILE VAR im Programm mit einer Datei
+erfolgt durch eine Assoziierungsprozedur. Bei der Assoziierung muß man an-
+geben, wie die Datei bearbeitet werden soll.
+
+Dateien müssen in einem ELAN-Programm - wie alle anderen Objekte auch -
+deklariert werden. Beispiel:
+
+ FILE VAR f :: ...
+
+Mit der Deklaration wird dem ELAN-Compiler der Name der Datei-Variablen
+bekannt gemacht. Dabei ist zu beachten, daß im EUMEL-System alle FILEs mit
+VAR deklariert werden müssen, denn jede Lese/Schreib-Operation verändert
+einen FILE. FILE CONST Objekte sind also nicht erlaubt. Ähnlich wie bei
+anderen Datenobjekten werden FILEs initialisiert. In der Regel erfolgt dies
+mit einer Assoziierungsprozedur. Beispiele:
+
+ FILE VAR meine datei :: sequential file (output, "daten")
+ ...
+ (* oder: *)
+ TEXT VAR datei name;
+ put ("Dateiname bitte:"); get (datei name);
+ FILE VAR f :: sequential file (input, datei name);
+
+Die Assoziierungsprozedur 'sequential file' hat die Aufgabe, eine in einem
+Programm deklarierte FILE VAR mit einer bereits vorhandenen oder noch einzu-
+richtenden Datei (abhängig von der Betriebsrichtung, siehe unten) des
+EUMEL-Systems zu koppeln. Den Dateinamen gibt man als zweiten Parameter
+an. Dadurch können ELAN-Programme geschrieben werden, die Dateien
+bearbeiten, deren Namen man beim Erstellen des Programms noch nicht kennt.
+
+Der erste Parameter gibt die sog. Betriebsrichtung an. Sie bestimmt, in
+welcher Weise die assoziierte Datei bearbeitet wird. Es gibt folgende drei
+Betriebsarten:
+
+a) input:
+ Die Datei kann vom Programm nur gelesen werden. Durch 'input' wird bei
+ der Assoziierung automatisch auf den ersten Satz der Datei positioniert.
+ Ist die zu lesende Datei nicht vorhanden, wird ein Fehler gemeldet.
+
+b) output:
+ Die Datei kann vom Programm nur beschrieben werden. Durch 'output' wird
+ bei der Assoziierung automatisch hinter den letzten Satz der Datei
+ positioniert (bei einer leeren Datei also auf den ersten Satz). Ist die
+ Datei vor der Assoziierung nicht vorhanden, wird sie automatisch einge-
+ richtet.
+
+c) modify:
+ Die Datei kann vom Programm in beliebiger Weise gelesen und beschrieben
+ werden. Im Gegensatz zu den Betriebsrichtungen 'input' und 'output', bei
+ denen ausschließlich ein rein sequentielles Lesen oder Schreiben erlaubt
+ ist, kann bei 'modify' beliebig positioniert, gelöscht, eingefügt und neu
+ geschrieben werden. Hier ist nicht definiert, auf welchen Satz der Datei
+ man nach erfolgter Assoziierung steht. Die Datei wird automatisch einge-
+ richtet, wenn sie vor der Assoziierung nicht vorhanden war.
+
+Anmerkung:
+In jeder Betriebsrichtung sind nur bestimmte Operationen zugelassen. Z.B.
+sind bei 'input' keine Schreib-Prozeduren erlaubt. Vergl. dazu die nächsten
+Abschnitte.
+
+Neben der Betriebsrichtung 'input', 'output' oder 'modify' muß bei
+'sequential file' als zweiter Parameter der Name der zu bearbeitenden Datei
+angegeben werden. Beispiel:
+
+ TEXT VAR datei name, zeile;
+ put ("Bitte Name der zu bearbeitenden Datei eingeben:");
+ get (datei name);
+ FILE VAR f :: sequential file (input, dateiname);
+ ...
+ getline (f, zeile);
+ ...
+
+Hier wird der Name der zu bearbeitenden Datei zuerst eingelesen. Diese Datei
+wird mit 'f' in der Betriebsrichtung 'input' assoziiert, d.h. würde man z.B.
+die Prozedur
+
+ putline (f, irgendein text)
+
+an einer Stelle im Programm verwenden, wird ein Fehler gemeldet. Die Be-
+triebsrichtung hilft also, Fehler bei der Programmierung zu vermeiden.
+
+Mit den Prozeduren
+
+ modify (f)
+ input (f)
+ output (f)
+
+kann die Betriebsrichtung von Dateien geändert werden.
+
+Dateien brauchen im EUMEL-System vor Programmende nicht geschlossen zu
+werden, da sie vom System immer konsistent gehalten werden.
+
+Merke: Die Betriebsrichtung gibt an, wie man eine Datei bearbeiten will.
+'input' steht für Lesen, 'output' für Schreiben und 'modify' für Verändern.
+Jede Datei muß vor einer Benutzung mit 'sequential file' assoziiert werden.
+Die Assoziierungsprozedur stellt die Kopplung zwischen dem Programm und dem
+EUMEL-Betriebssystem her.
+
+
+
+Operationen der Betriebsrichtung 'output'
+
+In der Betriebsrichtung 'output' sind nur Schreib-Operationen gestattet.
+'output' ist also für das Bearbeiten von Ausgabedateien vorgesehen.
+
+Mit den Prozeduren
+
+ put
+
+können INT-, REAL- und TEXT-Werte in eine Datei geschrieben werden. Die
+Prozedur
+
+ line
+
+sorgt dafür, daß eine neue Zeile in der Datei begonnen wird. Beispiel:
+
+ FILE VAR f :: sequential file (output, "daten");
+ put (f, "Daten:");
+ line (f);
+ schreibe daten.
+
+ schreibe daten:
+ INT VAR intwert;
+ REAL VAR textwert;
+ put ("bitte Daten eingeben (INT, REAL):");
+ REP
+ get (intwert);
+ put (f, intwert);
+ get (realwert);
+ put (f, realwert);
+ line (f);
+ UNTIL yes ("fertig") END REP.
+
+Durch die Assoziierungsprozedur mit der Betriebsrichtung 'output' wird
+hinter den letzten Satz der Datei positioniert, bei einer leeren Datei also
+auf den ersten Satz. In dem ersten Satz in unserem Beispiel wird also
+'Daten:' geschrieben. Durch die Prozedur 'line' geht man auf den nächsten
+Satz. Dann werden jeweils ein INT- und ein REAL-Wert in eine Datei-Zeile
+geschrieben, bis die Frage 'fertig' mit 'j' beantwortet wird.
+
+Die 'put'-Prozeduren schreiben die Werte jeweils in die aktuelle Datei-Zeile.
+Zwischen den Werten wird von den 'put'-Prozeduren jeweils ein Leerzeichen
+eingefügt. Im Gegensatz zu den 'put'-Prozeduren schreibt die Prozedur 'write'
+einen TEXT ohne ein anschließendes Leerzeichen in die aktuelle Datei-Zeile.
+Beispiel:
+
+ ...
+ write (f, "meine Daten:");
+ write (f, " ");
+ write (f, text (17 + 4));
+ (* das Gleiche wie: put (f, "meine Daten:"); put (f, 17 + 4) *)
+
+Auf eine neue Datei-Zeile kann auf zwei verschiedene Arten positioniert
+werden:
+
+a) Prozedur 'line':
+ Diese darf auch mit einem Parameter angegeben werden, der die Anzahl
+ Zeilen angibt. Beispiel:
+
+ line (f); (* positioniert auf die naechste Zeile *)
+ line (f, 1) (* das Gleiche *)
+ line (f, 4) (* Vier Zeilen weiter; dazwischen sind 3 Leerzeilen *)
+
+b) Überschreiten der Zeilengrenze:
+ Eine Datei-Zeile kann (voreingestellt) 77 Zeichen aufnehmen. Wird bei
+ einer Schreib-Operation diese Grenze überschritten, wird der auszugebende
+ Wert auf die nächste Zeile plaziert. Mit der Prozedur 'max line length'
+ kann die eingestellte Datei-Zeilenlänge gelesen oder verändert werden.
+ Beispiel:
+
+ FILE VAR f :: sequential file (output, "meine daten");
+ put (max line length (f)); (* ergibt 77 *)
+ max line length (f, 132);
+ put (max line length (f)) (* ergibt 132 *)
+
+ Ist die Länge des auszugebenden Textes größer als die verbleibende
+ Zeilenbreite, wird der Text auf der nächsten Zeile ausgegeben.
+
+Die 'putline'-Prozedur bietet die Möglichkeit, eine ganze Datei-Zeile auf
+einmal auszugeben. Eine Positionierung auf die nächste Datei-Zeile ('line')
+braucht dabei nicht vorgenommen werden. Beispiel:
+
+ TEXT VAR zeile :: "";
+ ...
+ zeile := ...;
+ putline (f, zeile);
+ ...
+
+Merke: In der Betriebsrichtung 'output' kann in eine Datei geschrieben
+werden. Dazu stehen die Prozeduren 'put', 'write' und 'putline' zur Verfü-
+gung. Die Prozedur 'line' positioniert auf die nächste Zeile der Ausgabe-
+datei. Mit 'max line length' kann die Länge einer Datei-Zeile verändert oder
+erfragt werden.
+
+
+
+Operationen der Betriebsrichtung 'input'
+
+In der Betriebsrichtung 'input' sind nur Lese-Operationen gestattet. 'input'
+ist also für das Bearbeiten von Eingabedateien vorgesehen.
+
+Analog der Betriebsrichtung 'output' sind bei 'input' 'get'-Prozeduren vor-
+handen, die INT-, REAL- oder TEXT-Werte aus einer Datei lesen. Beispiel:
+
+ FILE VAR f :: sequential file (input, "Betriebszeiten");
+ REAL VAR zeiten;
+ zeiten einlesen und berechnen.
+
+ zeiten einlesen und berechnen:
+ REP
+ get (f, zeiten);
+ IF zeiten = 0.0
+ THEN LEAVE zeiten einlesen und berechnen
+ FI; (* siehe auch 'eof'-Prozedur *)
+ berechne
+ END REP.
+
+ berechne:
+ ...
+
+Die 'get'-Prozeduren positionieren automatisch auf die nächste Zeile, sofern
+keine Werte mehr in der aktuellen Zeile vorhanden sind. Mit der Prozedur
+'line' kann explizit auf die nächste Zeile positioniert werden. Damit können
+die restlichen Daten einer Zeile überschlagen werden. Für die 'get'-Proze-
+duren gilt, daß jeder zu lesende Wert entweder beim nächsten Leerzeichen
+oder beim Zeilenende aufhört. Beispiel:
+
+ FILE VAR f :: sequential file (input, "text");
+ TEXT VAR wort;
+ lese worte.
+
+ lese worte:
+ REP
+ get (f, wort); (* Lesen eines Worts ohne Leerzeichen *)
+ put (wort); (* Schreiben eines Worts mit Leerzeichen *)
+ IF wort = "Ende"
+ THEN LEAVE lese worte
+ FI
+ END REP.
+
+
+Trennzeichen ("separator") zwischen den Worten sind also Leerzeichen, welche
+nicht eingelesen werden. Manchmal sollen jedoch Daten eingelesen werden, die
+durch andere Zeichen als dem Leerzeichen voneinander getrennt sind. Eine
+Möglichkeit, solche Daten zu behandeln, bietet die 'getline'-Prozedur. Sie
+liest (analog 'putline') eine ganze Zeile und positioniert auf die nächste
+Zeile. Dann kann man mit Hilfe von TEXT-Prozeduren solche Zeilen 'per Hand'
+auseinandernehmen. Als Beispiel zeigen wir ein Programm, welches den zweiten
+Wert einer Zeile lesen soll. Die Werte werden durch Kommata voneinander
+getrennt:
+
+ FILE VAR eingabe datei :: sequential file (input, "daten");
+ TEXT VAR zeile, wert;
+ lese jeweils zweiten wert;
+ verarbeite wert.
+
+ lese jeweils zweiten wert:
+ REP
+ getline (f, zeile);
+ IF zeile = "Ende"
+ THEN LEAVE lese jeweils zweiten wert
+ FI;
+ extrahiere zweiten wert
+ END REP.
+
+ extrahiere zweiten wert:
+ wert := subtext (zeile, anfang, ende).
+
+ anfang:
+ pos (zeile, ",") + 1.
+
+ ende:
+ pos (zeile, ",", anfang) + 1.
+
+ verarbeite wert:
+ ...
+
+Diese (etwas umständliche) Methode ist immer dann angebracht, wenn Zeilen
+unterschiedlich untersucht werden müssen. Eine einfachere Möglichkeit, die
+in vielen Fällen angewandt werden kann, bietet eine andere Form der 'get'-
+Prozedur, bei der man das oder die Trennzeichen angeben kann. Beispiel:
+
+ ...
+ extrahiere zweiten wert:
+ get (f, wert, ","); (* ersten Wert der Zeile ueberlesen *)
+ get (f, wert, ","). (* hier der richtige zweite Wert *)
+
+Hier wird also das Trennzeichen mit angegeben (dritter Parameter). Eine
+andere Methode müssen wir anwenden, wenn Daten nicht durch ein Trennzeichen
+unterschieden werden, sondern nur durch ihre Länge definiert sind. Beispiel:
+
+ ...
+ lese fuenfstellige werte:
+ REP
+ get (f, wort, 5);
+ verarbeite wert
+ ...
+ END REP.
+
+Bei dieser 'get'-Prozedur wird die Länge des einzulesenden Textes als
+dritter Parameter angegeben. Man beachte, daß die letzten zwei 'get'-Proze-
+duren nur TEXTe einlesen. Entsprechende Typwandlungen hat der Programmierer
+vorzunehmen.
+
+Merke: Die Betriebsrichtung 'input' erlaubt nur Lesen aus einer Eingabedatei.
+Für diesen Zweck gibt es die Prozeduren 'get', 'getline' und 'line'.
+
+
+
+Operationen der Betriebsrichtung 'modify'
+
+Die Betriebsrichtung 'modify' erlaubt das Lesen und Schreiben von Informa-
+tionen auf Dateien. Zusätzlich ist beliebiges Positionieren auf Dateien
+erlaubt. 'modify' ist also für Dateien gedacht, die man gleichzeitig als
+Ausgabe- und Eingabedateien behandeln will.
+
+Die Betriebsrichtung 'modify' erlaubt ein Ändern einer Datei ("updating"),
+wobei die sequentielle Natur der Datei erhalten bleibt.
+
+Eine Datei der Betriebsrichtung 'modify' muß ebenso mit 'sequential file'
+assoziiert werden, wie bei den zwei anderen Betriebsrichtungen. Während bei
+'input' auf den ersten bzw. bei 'output' auf den letzten Satz der Datei
+positioniert wird, ist bei 'modify' nicht definiert, auf welchem Satz der
+Datei nach erfolgter Assoziierung positioniert wird. Man muß also die erste
+Positionierung explizit vornehmen. Für die Zwecke der Positionierung gibt es
+die Prozeduren
+
+ to line (* auf eine bestimmte Zeile *)
+ col (* auf eine Spalte innerhalb der Zeile *)
+ down (* eine Zeile vorwaerts *)
+ up (* eine Zeile zurueck *)
+
+Neben diesen Positionierungsprozeduren gibt es die Informationsprozeduren:
+
+ lines (* Anzahl Zeilen in der Datei *)
+ line no (* aktuelle Zeilennummer *)
+ eof (* Dateiende? *)
+
+Beispiele:
+
+ down (f); (* wie: to line (f, line no (f) + 1) *)
+ (* Nicht über eof *)
+ up (f); (* wie: to line (f, line no (f) - 1) *)
+ (* Nicht über Zeile 1 *)
+
+Mit der Prozedur
+
+ read record
+
+kann der Satz, auf den aktuell positioniert wurde, gelesen werden. Mit
+
+ write record
+
+kann sein Inhalt geschrieben werden (also auch "überschreiben"). Mit den
+Prozeduren
+
+ insert record
+ delete record
+
+kann eine Zeile vor der aktuellen eingefügt (Position ist dann die einge-
+fügte Zeile) oder der aktuelle Satz gelöscht werden (Position ist dann der
+nächste Satz). Beispiele:
+
+ FILE VAR f :: sequential file (modify, "meine daten")
+ TEXT VAR zeile, neue zeile;
+ to line (f, 1);
+ read record (f, zeile); (* erste Zeile lesen *)
+ ...
+ insert record (f); (* neue erste Zeile *)
+ write record (f, neue zeile);
+ down (f); (* auf die 2. Zeile, die vorher die 1. war *)
+ delete record (f); (* diese loeschen, so dass die
+ Zeilenzahl wieder stimmt *)
+
+Das nächste Beispiel zeigt, wie hinter den letzten Satz einer Datei eine
+Zeile eingefügt werden kann (hier wird ausgenutzt, daß man in der Betriebs-
+richtung 'modify' hinter den letzten Satz der Datei positioniert werden
+kann):
+
+ FILE VAR f :: sequential file (modify, "test");
+ to line (f, lines (f)); (* auf die letzte Zeile *)
+ down (f);
+ insert record (f);
+ write record (f, "neue letzte Zeile");
+ ...
+
+Mit 'down' bzw. 'up' kann man auch um einige Zeilen auf einmal vorwärts oder
+rückwärts positionieren. Beispiele:
+
+ down (f, 17) (* 17 Zeilen vorwaerts *)
+ up (f, 13) (* 13 zeilen rueckwaerts *)
+
+Merke: In der Betriebsrichtung 'modify' können Dateien gelesen und/oder ge-
+schrieben werden ('read record' oder 'write record'). Positionierungen kön-
+nen mit 'down', 'up' oder 'to line' vorgenommen werden.
+
+
+
+Manipulationen von FILEs
+
+FILEs können im EUMEL-System auch als Einheiten behandelt werden. Dazu
+stehen die bereits erläuterten Prozeduren zur Verfügung, die wir hier der
+Vollständigkeit halber nochmals aufführen.
+
+Mit der Prozedur
+
+ exists
+
+kann erfragt werden, ob eine Datei bereits existiert. Beispiel:
+
+ TEXT VAR name;
+ REP
+ erfrage name;
+ UNTIL exists (name) END REP;
+ ...
+
+ erfrage name:
+ put ("Dateiname bitte:");
+ get (name);
+ line.
+
+Weitere Prozeduren:
+
+ forget (* Datei löschen *)
+ rename (* umbenennen *)
+ copy (* kopieren *)
+
+Für Programmierer ist eine Version der 'forget'-Prozedur interessant, die
+eine Datei ohne Kontroll-Anfrage löscht. Beispiel:
+
+ forget ("meine scratch datei", quiet)
+
+Merke: Mit 'exists' kann erfragt werden, ob ein FILE bereits existiert.
+
+
+
+Texte Suchen
+
+Mit den Prozeduren 'down' und 'up' kann man (ebenso wie im Editor) auch nach
+Texten suchen.
+
+Die Prozeduren 'down' bzw. 'up' suchen einen Text in der Datei. Beispiele:
+
+ down (f, "dieser text")
+ up (f, "noch'n text")
+
+Diese Prozeduren suchen direkt auf der Dateistruktur. Wird der gesuchte Text
+gefunden, steht man direkt auf dem gesuchten Text. Wird der Text nicht
+gefunden, steht man auf dem ersten (bei 'up') oder hinter dem letzten (bei
+'down') Zeichen der Datei. Die Position innerhalb der Zeile nach einer Suche
+kann mit
+
+ col (f)
+
+abgefragt werden. Um die Suche auf einen Bereich zu beschränken, kann man
+'down' bzw. 'up' mit einem weiterem Parameter versehen, der die max. Anzahl
+von Zeilen angibt. Beispiel:
+
+ FILE VAR f :: ...
+ ...
+ INT VAR akt zeilennr :: line no (f);
+ down (f, "pattern", 100);
+ (* sucht in den naechsten 100 Zeilen nach 'pattern' *)
+ IF line no (f) <> akt zeilen nr + 100
+ THEN gefunden
+ ELSE nicht gefunden
+ FI;
+ ...
+
+Achtung: 'down' bzw. 'up' beginnen die Suche immer mit dem nächsten Zeichen
+in Suchrichtung, so daß man mehrmals hintereinander suchen kann, ohne in
+eine Endlosschleife zu geraten (Erinnerung: wird ein Text gefunden, ist die
+Position innerhalb der Zeile das erste Zeichen des gesuchten Begriffs).
+
+Mit den Prozeduren (gleiche Parameterversorgung wie 'down' und 'up')
+
+ downety
+ uppety
+
+beginnt man mit der Suche immer auf der aktuellen Position. Darum sollte man
+diese Prozeduren mit Vorsicht verwenden. Mit der Prozedur
+
+ pattern found
+
+kann man anfragen, ob die letzte Suchoperation erfolgreich war oder nicht.
+Beispiel:
+
+ FILE VAR f :: ...
+ ...
+ INT VAR akt zeilennr :: line no (f);
+ down (f, "pattern", 100);
+ (* sucht in den naechsten 100 Zeilen nach 'pattern' *)
+ IF pattern found THEN gefunden
+ ELSE nicht gefunden
+ FI;
+ ...
+
+Mit der Prozedur
+
+ at
+
+kann man anfragen, ob man auf einem gewünschten Wort steht. Beispiel:
+
+ IF at (f, "pattern")
+ THEN ..
+ FI
+
+Die Prozedur
+
+ word
+
+liefert das aktuelle Wort der aktuellen Position einer Zeile. Beispiele:
+
+ TEXT VAR dieses wort :: word (f);
+ (* Zeichenkette von der aktuellen Position bis zum nächsten Blank oder
+ Zeilenende *)
+ dieses wort := word (f, "<");
+ (* Zeichenkette (Wort) von der aktuellen Position bis zum Zeichen '<'
+ oder Zeilenende *)
+ dieses wort := word (f, 13);
+ (* Zeichenkette (Wort) mit der Laenge 13 *)
+
+Merke: Die Prozeduren 'down' und 'up' suchen einen Text innerhalb einer
+Datei. Mit 'at' kann man anfragen, ob man auf dem gesuchten Begriff steht.
+'word' liefert das aktuelle Wort.
+
+
+
+FILE-Ausschnitte
+
+Hier wird erklärt, wie man mehrere Zeilen aus einer Datei auf einmal löschen
+und/oder verschieben und wie man nur einen Ausschnitt einer Datei zugänglich
+machen kann.
+
+Den einfachsten Zugang zu Datei-Abschnitten erhält ein Programmierer durch
+einige Anwendungsprozeduren, die u.a. auch im Editor verwandt werden. Dort
+gibt es die Möglichkeit, einen markierten Bereich "vorsichtig" zu löschen
+und u.U. an anderer Stelle wieder einzufügen (ESC RUBOUT und ESC RUBIN).
+Solche Prozeduren stehen auch einem Programmierer zur Verfügung. Beispiel:
+
+ FILE VAR f :: ....
+ ....
+ remove (f, 100); (* entfernt 100 Zeilen von der aktuellen
+ Position rueckwaerts (!) aus der Datei 'f' *)
+ to line (27); (* zum Beispiel *)
+ re insert (f) (* fuegt die "vorsichtig" geloeschten Zeilen vor
+ (!) die Zeile 27 ein *)
+
+Die Prozedur
+
+ remove
+
+löscht also eine angebbare Anzahl von Zeilen in der Datei (rückwärts von der
+aktuellen Zeilennummer ab) und schreibt diesen Datei-Abschnitt in einen
+internen Puffer. Man beachte, daß sich dabei natürlich die Zeilennummer der
+Datei ändert. Die entfernten Zeilen können aus dem internen Puffer an einer
+anderen Stelle durch
+
+ reinsert
+
+genau einmal wieder eingefügt werden. Sollen jedoch die mit 'remove' ent-
+fernten Zeilen wirklich gelöscht und nicht mehr an anderer Stelle eingesetzt
+werden, dann kann man die Prozedur
+
+ clear removed
+
+verwenden. Beispiel:
+
+ ...
+ remove (f, 50); (* loescht vorsichtig *)
+ clear removed (f); (* und endgueltig *)
+ ...
+
+Durch solche Löschungen oder Einfügungen entstehen Datei-Segmente.
+Innerhalb eines Segments kann direkt positioniert werden. Werden jedoch
+Löschungen oder Einfügungen vorgenommen (Sätze werden ein- oder ausgekettet),
+muß erst zu einem entsprechenden Segment positioniert und dann innerhalb des
+Segments auf den entsprechenden Satz positioniert werden. Das kann - je nach
+Anzahl der Segmente - zeitaufwendig sein. Deshalb existiert die Prozedur
+
+ segments
+
+mit der man feststellen kann, wieviel Datei-Segmente in der Datei existieren.
+(Sind es "zu viele", kann man die Datei "reorganisieren").
+
+Diese und die folgenden Prozeduren nutzen eine vom EUMEL-System bereitge-
+stellte Möglichkeit, Ausschnitte aus Dateien wie eigenständige Dateien zu
+behandeln. Beispiel:
+
+ FILE VAR f :: ...
+ ...
+ FRANGE VAR alter bereich;
+ set range (f, 200, 1, alter bereich);
+ (* Datei mit 200 Zeilen von der Spalte 1 der aktuellen Zeile *)
+ edit (f); (* Zeilen 1-200 editieren *)
+ set range (f, alter bereich); (* Datei zuruecksetzen *)
+ ...
+
+Von dem Beispiel-Programm wird die Datei 'f' bearbeitet. Die FRANGE-Variable
+dient hier dazu, sich den ursprünglichen Bereich der Datei 'f' (der auch
+schon eingeschränkt sein kann), zu merken. Mit der Prozedur 'set range' wird
+die Datei 'f' auf 200 Zeilen eingeschränkt (von der aktuellen Zeile 200
+Zeilen rückwärts). Mit der Prozedur 'edit' kann nun der Benutzer unseres
+Programms die (eingeschränkte) Datei beliebig editieren. Ihm steht am Anfang
+Zeilen 1 bis 200 zur Verfügung; die "ausgeblendeten" Datei-Teile kann er
+nicht verändern. Mit dem zweiten Aufruf von 'set range' wird der einge-
+schränkte (und u.U. veränderte) Datei-Bereich aufgehoben, so daß hier wieder
+alle ursprünglichen Datei-Zeilen zur Verfügung stehen.
+
+Solche Beschränkungen können natürlich mehrmals geschachtelt vorgenommen
+werden. Um nach Ablauf solcher Programmteile sicher wieder die ursprüngliche
+Datei (mit allen ihren Zeilen) zur Verfügung zu haben, gibt es die Prozedur
+
+ reset range (f)
+
+Sie setzt die Datei 'f' auf den größtmöglichen Bereich zurück.
+
+Merke: Mit 'remove' und 'reinsert' können Zeilen gelöscht und/oder ver-
+schoben werden. Mit dem Datentyp FRANGE und den Prozeduren 'set range'
+können Dateien eingeschränkt werden.
+
+
+
+5. Datenräume
+
+Die bis jetzt behandelten Dateien können nur TEXTe aufnehmen (bei einigen
+Schreib-/Lese-Operationen werden Daten in Texte umgewandelt, z.B. bei 'get'
+und 'put'). Damit ist gewährleistet, daß alle Programme im EUMEL-System
+(Editor, Drucker, Compiler, Benutzer-Programme usw.) auf gleiche Art und
+Weise auf Dateien zugreifen können, unabhängig davon, welche Daten wirklich
+gespeichert sind. Der folgende Abschnitt zeigt, wie man mit Dateien umgeht,
+die nicht vom Standardtyp FILE sind.
+
+
+
+Konzept des Datenraums
+
+Standarddateien (FILEs) können nur Texte aufnehmen, da sie ja hauptsächlich
+für die Kommunikation mit dem Menschen (vorwiegend mit Hilfe des Editors bzw.
+Ein-/Ausgabe) gedacht sind. Will man Zahlen in einen FILE ausgeben, so
+müssen diese zuvor in Texte umgewandelt werden. Hierfür stehen Standard-
+prozeduren zur Verfügung (z.B. 'put (f, 17)').
+
+Will man aber Dateien zur Kommunikation zwischen Programmen verwenden, die
+große Zahlenmengen austauschen, verursachen die Umwandlungen von Zahlen
+in TEXTe und umgekehrt unnötigen Rechenaufwand. Daher wurden in EUMEL� die
+Datenräume eingef�hrt, die es gestatten, beliebige Strukturen (Typen) in
+Dateien zu speichern. Solche Datenräume kann man weder mit dem Editor noch
+mit dem Standarddruckprogramm (print) bearbeiten, da diese ja den Typ des in
+der Datei gespeicherten Objektes nicht kennen.
+
+Einen Datenraum kann man sich als eine Sammlung von Daten vorstellen (u.U.
+leer), die ausschließlich von einem Programm her behandelt wird. Man kann
+einem Datenraum durch ein Programm einen Datentyp "aufprägen". Meist handelt
+es sich um Reihungen, weil die Benutzung von Datenräumen erst bei größeren
+Datenmengen lohnt. Nach einem solchen "Aufpräge"-Vorgang kann der Datenraum
+wie ein "normaler" Datentyp behandelt werden, mit dem Unterschied, daß die
+Daten in einem Datenraum (d.h. Datei) gespeichert werden. Somit können nach-
+folgende Programme auf die im Datenraum gespeicherten Daten zugreifen, so-
+fern sie den gleichen Datentyp auf den Datenraum aufprägen.
+
+Merke: Ein Datenraum ist eine Sammlung von Daten. Er kann ausschließlich
+durch ein Programm (und z.B. nicht durch den Editor) behandelt werden.
+Programme können Datenräumen Datentypen aufprägen und sie dann mit den ver-
+fügbaren Operationen dieses Datentyps manipulieren.
+
+
+Ein Beispiel
+
+Diesen etwas komplizierten Vorgang wollen wir an Hand eines Beispiels
+Schritt für Schritt erklären.
+
+Angenommen, Programmierer Meier hat ein Gehaltsprogramm zu erstellen. Er
+überlegt sich, das Programm in (mindestens) zwei Moduln (PACKETs) zu er-
+stellen:
+
+a) Berechnung der Gehaltssumme aus den Arbeitszeiten (also Bruttogehalt) und
+ dann
+b) Endgültige Berechnung der Gehälter durch Abzug von Steuern usw.
+
+Das Programm aus a) erstellt also eine Gehaltsliste für alle Beschäftigten
+des Betriebs. Die Gehaltsliste soll ebenfalls von Modul b) genutzt werden.
+
+Meier entschließt sich, die Gehaltsliste in einem Datenraum zu speichern.
+Das hat neben der effizienteren Bearbeitung noch den Vorteil, daß man die
+Gehaltsliste - ohne Programmierkenntnisse zu besitzen - nicht mit dem Editor
+bearbeiten kann (Datenschutz).
+
+Dem ELAN-Compiler muß Meier also mitteilen, daß die Reihung für die
+Gehaltsliste (oder irgendein anderer Datentyp) nicht im Speicherbereich des
+Programms, sondern in einem Datenraum gespeichert werden soll. Dies erfolgt
+mit dem Schlüsselwort BOUND, welches dem Datentyp bei der Deklaration
+vorangestellt wird. Beispiel:
+
+ BOUND ROW 1000 REAL VAR gehaltsliste
+
+Dieses BOUND-Objekt muß Meier noch mit einer Datei verbinden, man spricht
+von "ankoppeln". Die Ankopplung erfolgt durch den Operator ':='. Dies kann
+man gleich bei der Initialisierung vornehmen. Beispiel:
+
+ BOUND ROW 1000 REAL VAR gehaltsliste := new ("hugo")
+
+Die Prozedur 'new' kreiert dabei einen leeren Datenraum (hier mit dem Namen
+'hugo'), der mit Hilfe der Zuweisung (hier: Initialisierung) an die Variable
+'gehaltsliste' gekoppelt wird.
+
+Nun kann Meier mit der 'gehaltsliste' arbeiten wie mit allen anderen Feldern
+auch, mit dem Unterschied, daß die Daten, die er in 'gehaltsliste' speichert,
+eigentlich im Datenraum 'hugo' gespeichert sind. Beispiele:
+
+ gehaltsliste [5] := 10 000.0; (* Traumgehalt *)
+ gehaltsliste [index] INCR 200.0; (* usw. *)
+
+Meier kann auch Prozeduren schreiben, die auf der Gehaltsliste arbeiten.
+Beispiel:
+
+ PROC sort (ROW 1000 REAL VAR liste):
+ ...
+ END PROC sort;
+ ...
+ sort (gehaltsliste);
+ ...
+
+Man beachte, daß der formale Parameter der Prozedur 'sort' nicht mit BOUND
+spezifiziert werden darf (BOUND wird nur bei der Deklaration des Objekts
+angegeben). Das ist übrigens ein weiterer wichtiger Vorteil von BOUND-Objek-
+ten: man kann alle Prozeduren des EUMEL-Systems auch für BOUND-Objekte
+verwenden, nur die Datentypen müssen natürlich übereinstimmen.
+
+Nach der Bearbeitung des Moduls a) ist Meier nun sicher, daß seine Brutto-
+daten in dem Datenraum 'hugo' stehen. Meier braucht (genauso wie bei FILEs)
+den Datenraum nicht zu schließen. Im zweiten Modul muß Meier nun erneut ein
+BOUND-Objekt deklarieren.
+Deshalb deklariert Meier nun
+
+ BOUND ROW 1000 REAL VAR nettoliste :: old ("hugo");
+
+Hier muß Meier nun die Prozedur 'old' verwenden, weil der Datenraum bereits
+aus dem ersten Modul existiert. Nun kann Meier weiter programmieren, bis er
+letztendlich den Datenraum löscht:
+
+ forget ("hugo")
+
+Merke: Ein Datenobjekt eines beliebigen Datentyps kann mit einem vorange-
+stellten BOUND deklariert werden und an einen Datenraum gekoppelt werden.
+Der Datentyp ist dann auf den Datenraum aufgeprägt und man kann mit ihm
+arbeiten wie mit allen anderen Objekten dieses Datentyps.
+
+
+
+Datenräume als Datentyp
+
+Datenräume können auch als eigener Datentyp (DATASPACE) in einem Programm
+behandelt werden. Somit können Datenräume (als Ganzes) ohne Kenntnis eines
+eventuell (vorher oder später) aufgeprägten Typs verwandt werden.
+
+Als Operationen auf DATASPACE-Objekten sind nur Transporte, Löschen und
+Initialisieren zugelassen.
+
+ DATASPACE VAR ds :: old ("daten");
+
+Der Zuweisungsoperator bewirkt eine Kopie des Datenraums vom rechten auf
+den linken Operanden. Des weiteren gibt es eine DATASPACE Konstante 'nil-
+space', die eine leere Datenraum repräsentiert. Mit diesem Wert initialisiert
+der Datei-Manager Dateien, die neu kreiert werden.
+
+Eine neuer Datenraum kann durch
+
+ new ("name")
+
+eingerichtet werden. 'new' liefert gleichzeitig einen Datenraum und wird
+deshalb für Initialisierungen verwandt. Beispiel:
+
+ DATASPACE VAR datenraum :: new ("name1"); (* Kopie ! *)
+
+Ein bereits vorhandener Datenraum in der Benutzer-Task kann mit
+
+ old ("datei")
+
+erneut benutzt werden. 'old' liefert (wie 'new') einen DATASPACE, so daß
+'old' ebenfalls zur Initialisierung benutzt werden kann. Die Prozedur
+
+ nilspace
+
+liefert einen leeren Datenraum.
+
+Für Datenräume gelten zusätzlich einige der Prozeduren wie für FILEs, u.a.:
+
+ forget
+ fetch
+ save
+ rename
+
+Ausgenommen davon sind Prozeduren, die einen TEXT-File voraussetzen, wie
+z.B. 'crypt' und 'decrypt', 'put', 'putline' usw.
+
+Abschließend soll hier noch auf häufig gemachte Fehler hingewiesen werden:
+
+Wenn man an ein DATASPACE-Objekt zuweist (z.B.: DATASPACE VAR ds :=
+new ("mein datenraum")) so erhält man, wie oben erwähnt, eine Kopie des
+Datenraums in 'ds'. Koppelt man jetzt 'ds' an ein BOUND-Objekt an und führt
+Änderungen durch, so wirken diese nur auf die Kopie und nicht auf die Quelle
+(d.h. im Beispiel, daß die Datenraum 'hugo' nicht verändert wird, hier also
+leer bleibt). Für Änderungen in den vom Datei-Manager verwalteten Dateien
+ist also stets direkt anzukoppeln, wie es im Beispiel gezeigt wurde.
+
+Wenn man ein DATASPACE-Objekt benutzt, ohne den Datei-Manager zu verwenden,
+so muß man selbst dafür sorgen, daß dieses Objekt nach seiner Benutzung
+wieder gelöscht wird. Das Löschen geschieht durch die Prozedur 'forget'.
+Ferner ist zu beachten, daß vor der Ankopplung an ein BOUND-Objekt das
+DATASPACE-Objekt initialisiert wird (im Normalfall mit 'nilspace'). Beispiel:
+
+ DATASPACE VAR ds := nilspace;
+ BOUND ROW 1000 REAL VAR real feld := ds;
+ ....
+ real feld [index] := wert;
+ ....
+ forget (ds) (* Datei löschen, damit der Platz wieder verwendet wird *)
+
+Ein automatisches Löschen von DATASPACE-Objekten erfolgt auch nicht bei
+Programmende (sonst könnten sie ihre Funktion als Datei nicht erfüllen).
+Erst beim Löschen einer Task werden alle ihr gehörenden DATASPACE-Objekte
+freigegeben. Verboten ist weiterhin folgendes:
+
+ BOUND X ...;
+
+wobei 'X' mit BOUND deklariert wurde oder ein DATASPACE ist.
+
+Merke: Datenräume können durch 'new' erschaffen werden. Mit 'old' kann ein
+bereits vorhandener Datenraum angesprochen werden. Im Übrigen gelten auch
+einige der für FILEs vorhandenen Operationen.
+
+
+
+Datei-Typen definieren
+
+Durch die Datenräume und die Datentyp-Definition von ELAN ist es für
+Programmierer relativ einfach, neue Datei-Datentypen zu definieren.
+
+In der Regel reicht der Datentyp FILE für "normale" Anwendungen aus, jedoch
+kann es manchmal sinnvoll und notwendig sein, neue Datei-Typen für spezielle
+Aufgaben zu definieren.
+
+In diesem Abschnitt zeigen wir an dem Beispiel DIRFILE (welcher zwar im
+ELAN-Standard definiert, aber nicht im EUMEL-System realisiert ist), wie ein
+neuer Datei-Datentyp definiert wird:
+
+ PACKET dirfiles DEFINES DIRFILE, :=, dirfile, getline, ...:
+
+ LET maxsize = 1000;
+
+ TYPE DIRFILE = BOUND ROW maxsize TEXT;
+ (* DIRFILE besteht aus TEXTen; Zugriff erfolgt ueber einen
+ Schluessel, der den Index auf die Reihung darstellt *)
+
+ OP := (DIRFILE VAR dest, DATASPACE CONST space):
+ CONCR (dest) := space
+ END OP :=;
+
+ DATASPACE PROC dirfile (TEXT CONST name):
+ IF exists (name)
+ THEN old (name)
+ ELSE new (name)
+ FI
+ END PROC dirfile;
+
+ PROC getline (DIRFILE CONST df, INT CONST index, TEXT VAR record):
+ IF index <= 0
+ THEN errorstop ("access before first record")
+ ELIF index > maxsize
+ THEN errorstop ("access after last record")
+ ELSE record := df [index]
+ FI
+ END PROC getline;
+
+ PROC putline (DIRFILE CONST df, INT CONST index, TEXT VAR record):
+ ...
+ END PROC putline;
+
+ ...
+ END PACKET dirfiles;
+
+Die Prozedur 'dirfile' ist die Assoziierungsprozedur für DIRFILEs (analog
+'sequential file' bei FILEs). 'dirfile' liefert entweder einen bereits vor-
+handenen Datenraum oder richtet einen neuen ein. Um eine Initialisierung mit
+der 'dirfile'-Prozedur vornehmen zu können, braucht man auch einen Zu-
+weisungsoperator, der den Datenraum an den DIRFILE-Datentyp koppelt.
+
+Zugriffe auf einen DIRFILE sind nun relativ einfach zu schreiben. Im obigen
+Beispiel wird nur die Prozedur 'getline' gezeigt.
+
+Nun ist es möglich, Programme zu schreiben, die den DIRFILE-Datentyp
+benutzen. Beispiel:
+
+ DIRFILE VAR laeufer ::
+ dirfile ("Nacht von Borgholzhausen");
+ INT VAR nummer;
+ TEXT VAR name;
+
+ REP
+ put ("Startnummer bitte:");
+ get (nummer);
+ line;
+ put ("Name des Laeufers:");
+ get (name);
+ putline (laeufer, nummer, name);
+ line
+ UNTIL no ("weiter") END REP;
+ ...
+
+Merke: Neue Datei-Typen für spezielle Anwendungen kann man leicht selbst
+programmieren.
+
+
+
+6. Beschreibung der Prozeduren
+
+In diesem Abschnitt werden alle Operationen, die für Dateien zur Verfügung
+stehen, aufgeführt. Dabei werden die Operationen für FILEs und Datenräume
+mit (F) gekennzeichnet.
+
++
+ THESAURUS OP + (THESAURUS CONST left, right)
+ Zweck: Vereinigungsmenge von 'left' und 'right'.
+
+ THESAURUS OP + (THESAURUS VAR left, TEXT CONST name)
+ Zweck: Nimmt den TEXT 'name' in den Thesaurus 'left' auf. Beispiel:
+
+ save (SOME father + "hugo", archive)
+
+-
+ THESAURUS OP - (THESAURUS CONST left, right)
+ Zweck: Differenzmenge von 'left' und 'right'.
+
+ THESAURUS OP - (THESAURUS VAR left, TEXT CONST name)
+ Zweck: Liefert einen Thesaurus aus left, aber ohne den Eintrag 'name'.
+ Beispiel:
+
+ save (ALL myself - "hugo", archive)
+
+/
+ THESAURUS OP / (THESAURUS CONST left, right)
+ Zweck: Schnittmenge von 'left' und 'right'.
+
+ TASK OP / (TEXT CONST task name)
+ Zweck: Liefert aus einem Tasknamen den internen Tasknamen. '/' kann über-
+ all dort eingesetzt werden, wo ein interner Taskname verlangt wird.
+
+ALL
+ THESAURUS OP ALL (TASK CONST task)
+ Zweck: Liefert einen Thesaurus, der alle Dateinamen der angegebenen Task
+ enthält (auch der Benutzer-Task: 'myself').
+
+ THESAURUS OP ALL (TEXT CONST file name)
+ Zweck: Liefert einen Thesaurus, der die in 'file name' vorhandenen Datei-
+ namen (jede Zeile ein Name) enthält.
+
+at (F)
+ BOOL PROC at (FILE VAR f, TEXT CONST word)
+ Zweck: Abfrage, ob man auf 'word' in der Datei 'f' positioniert ist.
+ Beispiel:
+
+ ...
+ down (f, "muster")
+ IF at (f, "muster")
+ THEN gefunden
+ ELSE nicht gefunden
+ FI;
+ ...
+
+archive
+ PROC archive (TEXT CONST archive name)
+ Zweck: Anmeldung von Archiv-Operationen. 'archive name' wird zur Über-
+ prüfung für alle folgenden Archiv-Operationen verwandt, um die
+ unberechtigte Benutzung eines Archivs zu verhindern. Die Anmeldung
+ wird abgelehnt, wenn ein anderer Nutzer das Archiv belegt hat.
+
+ TASK PROC archive
+ Zweck: Liefert den internen Task-Bezeichner für die Verwendung in
+ Datei-Kommandos. Beispiel:
+
+ save ("datei", archive)
+
+brother
+ TASK PROC brother (TASK CONST task)
+ Zweck: Liefert den internen Task-Bezeichner der angegebenen "Bruder"-
+ Task.
+
+check
+ PROC check (TEXT CONST dateiname, TASK CONST task)
+ Zweck: Überprüft, ob die Datei 'dateiname' auf dem Archiv lesbar ist.
+ Beispiel:
+
+ check ("meine datei", archive)
+
+ PROC check (THESAURUS CONST t, TASK CONST task)
+ Zweck: Überprüft, ob die in dem Thesaurus 't' enthaltenen Dateien auf dem
+ Archiv lesbar sind. Beispiel:
+
+ check (ALL archive, archive)
+
+clear
+ PROC clear (TASK CONST task)
+ Zweck: Löscht alle Dateien der Task 'task'. Ist z.Z. nur für die Task
+ 'ARCHIVE' implementiert.
+
+clear removed (F)
+ PROC clear removed (FILE VAR f)
+ Zweck: Löscht die mit 'remove' "vorsichtig" gelöschten Zeilen aus der
+ Datei 'f' endgültig.
+
+close (F)
+ PROC close (FILE VAR file)
+ Zweck: Schließen der Datei 'file'. Im EUMEL-System ist der Aufruf von
+ 'close' nicht notwendig. 'close' wurde nur aufgenommen, um die
+ Kompatibilität zu Standard zu wahren.
+
+col (F)
+ PROC col (FILE VAR f, INT CONST position)
+ Zweck: Positionierung auf die Spalte 'position' innerhalb der aktuellen
+ Zeile.
+
+ INT PROC col (FILE CONST f)
+ Zweck: Liefert die aktuelle Position innerhalb der aktuellen Zeile.
+
+copy (F)
+ PROC copy (TEXT CONST source, destination)
+ Zweck: Kopiert die Datei 'source' in eine neue Datei mit dem Namen
+ 'destination' in der Benutzer-Task.
+ Fehlerfälle:
+ * destination file already exists
+ Eine Datei mit dem Namen 'destination' existiert bereits.
+ * source file does not exist
+ Die Ursprungsdatei mit dem Namen 'source' ist nicht vorhanden.
+ * directory overflow
+ Die Anzahl der zulässigen Dateien der Benutzer-Task ist über-
+ schritten.
+
+ PROC copy (DATASPACE CONST ds, TEXT CONST destination)
+ Zweck: Eintragen eines unbenannten DATASPACE in die Datei-Verwaltung.
+ Fehlerfälle:
+ * destination file already exists
+ Eine Datei mit dem Namen 'destination' existiert bereits.
+ * directory overflow
+ Die Anzahl der zulässigen Dateien der Benutzer-Task ist über-
+ schritten.
+
+create
+ PROC create (TEXT CONST name)
+ Zweck: Erschafft einen neuen Datenraum in der Benutzer-Task.
+ Fehlerfälle:
+ * file already exists
+ Eine Datei mit dem Namen 'name' existiert bereits in der Benutzer-
+ Task.
+ * directory overflow
+ Die Anzahl der zulässigen Dateien der Benutzer-Task ist über-
+ schritten.
+
+crypt (F)
+ PROC crypt (TEXT CONST name, parole)
+ Zweck: Verschlüsseln des Inhaltes der Datei 'name' mit Hilfe des Textes
+ 'parole' für Zwecke des Datenschutzes. Die Verschlüsselung ist
+ umso besser (bzw. umso schwieriger zu "knacken"), je länger der
+ Text 'parole' ist. Die Datei kann mit der Prozedur 'decrypt'
+ wieder entschlüsselt werden.
+
+ Eine Datei kann mehrfach verschlüsselt werden. Dabei gilt bei
+ einer Entschlüsselung das Klammerungsprinzip. Es muß also genau so
+ oft entschlüsselt werden, wie anfangs verschlüsselt wurde. Dabei
+ ist auf die richtige Angabe der 'parole'n zu achten. Beispiel:
+
+ crypt ("hugo", "verschluesselung1");
+ crypt ("hugo", "verschluesselung2");
+ ...
+ decrypt ("hugo", "verschluesselung2");
+ decrypt ("hugo", "verschluesselung1")
+
+ Achtung: 'crypt' und 'decrypt' sind nicht standardmäßig insertiert.
+
+decrypt (F)
+ PROC decrypt (TEXT CONST name, parole)
+ Zweck: Entschlüsselt die Datei 'name' mit Hilfe der angegebenen 'parole'.
+ Dabei ist darauf zu achten, daß die gleiche 'parole' anzugeben
+ ist, die verwendet wurde, um die Datei zu verschlüsseln (sonst
+ wirkt 'decrypt' wie ein erneuter Aufruf von 'crypt').Beim mehr-
+ fachen Ver- und Entschlüsseln ist das Klammerungsprinzip zu be-
+ achten (dazu vergl. 'crypt').
+
+delete record (F)
+ PROC delete record (FILE VAR file)
+ Zweck: Der aktuelle Satz der Datei 'file' wird gelöscht. Der folgende
+ Satz wird der aktuelle Satz. Die Datei 'file' muß mit der Verar-
+ beitungsart 'modify' assoziiert worden sein.
+
+do
+ PROC do (PROC (TEXT CONST) operate, THESAURUS CONST thesaurus)
+ Zweck: Ruft 'operate' mit allen im 'thesaurus' enthaltenen Dateinamen
+ nacheinander auf. Man beachte, daß bei Prozedur-Parametern der
+ Name der Prozedur hinter dessen Parametern geschrieben wird.
+ Beispiel:
+
+ do (PROC (TEXT CONST) reorganize, ALL myself)
+
+ PROC do (PROC (TEXT CONST, TASK CONST) operate,
+ THESAURUS CONST thesaurus, TASK CONST task)
+ Zweck: S.o.. Dabei ist zu beachten, daß 'task' als zweiter Parameter in
+ der Prozedur 'operate' eingesetzt wird. Beispiel:
+
+ do (PROC (TEXT CONST, TASK CONST) save,
+ SOME myself, father)
+ (* enspricht: *)
+ save (SOME myself, father)
+
+down (F)
+ PROC down (FILE VAR f)
+ Zweck: Positionieren um eine Zeile vorwärts in der Datei 'f'.
+
+ PROC down (FILE VAR f, INT CONST number)
+ Zweck: Positionieren um 'number' Zeilen vorwärts in der Datei 'f'.
+
+ PROC down (FILE VAR f, TEXT CONST pattern)
+ Zweck: Suche nach 'pattern' in der Datei 'f'. Wird 'pattern' gefunden,
+ ist die Position das erste Zeichen von 'pattern'. Andernfalls
+ steht man hinter dem letzten Zeichen der Datei. Achtung: 'down'
+ sucht vom nächsten Zeichen rechts ab, so daß wiederholtes Suchen
+ keine Endlosschleife ergibt.
+
+ PROC down (FILE VAR f, TEXT CONST pattern, INT CONST number)
+ Zweck: Wie obiges 'down', aber maximal nur 'number'-Zeilen weit.
+
+downety (F)
+ PROC downety (FILE VAR f, TEXT CONST pattern)
+ Zweck: Suche nach 'pattern' in der Datei 'f'. Wird 'pattern' gefunden,
+ ist die Position das erste Zeichen von 'pattern'. Andernfalls
+ steht man auf dem letzten Zeichen der Datei. Achtung: 'downety'
+ sucht (im Gegensatz zu 'down') vom aktuellen Zeichen.
+
+ PROC downety (FILE VAR f, TEXT CONST pattern, INT CONST number)
+ Zweck: Wie obiges 'downety', aber maximal nur 'number'-Zeilen weit.
+
+enter password
+ PROC enter password (TEXT CONST password)
+ Zweck: Einstellen eines Paßwortes in der Benutzer-Task für den Datei-
+ Verkehr mit einer Vater-Task. Der Parameter 'password' kann dabei
+ aus zwei Teilen bestehen, die durch ein "/"-Zeichen getrennt
+ werden müssen. Der erste Teil bedeutet das schreib-Passwort,
+ während der TEXT nach dem "/"-Zeichen das Lese-Paßwort beinhaltet.
+ Enthält der Parameter 'password' kein "/"-Zeichen, gilt der ange-
+ gebene TEXT sowohl für das Schreib- wie auch für das Lese-Paßwort.
+ Im Schreib- bzw. Lese-Teil des Paßworts kann man das "-"-Zeichen
+ angeben, um eine Datei vor überschreibendem oder lesendem Zugriff
+ zu schützen.
+
+ Die Paßwort-Überprüfung findet statt bei
+
+ - fetch (Überprüfung der Lese-Berechtigung)
+ - save (Überprüfung der Schreib-Berechtigung)
+ - erase (Überprüfung der Schreib-Berechtigung)
+
+eof (F)
+ BOOL PROC eof (FILE CONST file)
+ Zweck: Informationsprozedur auf das Ende eines FILEs. Liefert den Wert
+ TRUE, sofern hinter den letzten Satz eines FILEs positioniert
+ wurde.
+
+erase
+ PROC erase (TEXT CONST name)
+ Zweck: Löscht eine Datei mit dem Namen 'name' in der unmittelbaren
+ Vater-Task.
+ Fehlerfälle:
+ * ... gibt es nicht
+ Eine Datei mit dem Namen 'name' existiert in der unmittelbaren
+ Vater-Task nicht.
+ * wrong password
+ Es wurde mit der Prozedur 'enter password' nicht das richtige
+ Paßwort angegeben.
+
+ PROC erase (TEXT CONST name, TASK CONST task)
+ Zweck: Löscht eine Datei mit dem Namen 'name' in der Task 'task'. Bei-
+ spiel:
+
+ erase ("meine datei", father)
+
+ PROC erase (THESAURUS CONST thesaurus)
+ Zweck: Löscht die im 'thesaurus' angegebenen Dateien in der Vater-Task.
+ Beispiel (löscht alle Dateien in der Vater-Task, die in der Benut-
+ zer-Task vorhanden sind):
+
+ erase (ALL myself)
+
+ PROC erase (THESAURUS CONST thesaurus, TASK CONST manager)
+ Zweck: S.o..
+
+exists (F)
+ BOOL PROC exists (TEXT CONST name)
+ Zweck: Informationsprozedur zur Abfrage der Existenz einer Datei in der
+ Benutzer-Task. Beispiel:
+
+ IF exists ("dateiname")
+ THEN FILE VAR f :: sequential file ...;
+ ELSE errorstop ("Datei existiert nicht")
+ FI
+
+father
+ TASK PROC father
+ Zweck: Liefert den internen Task-Bezeichner der Vater-Task der Benutzer-
+ Task. Beispiel:
+
+ save ("datei", father)
+
+ TASK PROC father (TASK CONST task)
+ Zweck: Liefert den internen Task-Bezeichner von 'task'. Beispiel:
+
+ save ("datei", father (father)) (* Kopiert 'datei' zum "Opa" *)
+
+fetch
+ PROC fetch (TEXT CONST name)
+ Zweck: Einbringen einer Datei in die Benutzer-Task von dem "direkten"
+ Vater im Taskbaum.
+ Fehlerfälle:
+ * ... gibt es nicht
+ Die Datei existiert bei dem Vater nicht.
+ * directory overflow
+ Die Anzahl der zulässigen Dateien der Benutzer-Task ist über-
+ schritten.
+ * wrong password
+ Es wurde mit der Prozedur 'enter password' nicht das richtige
+ Paßwort angegeben.
+
+ PROC fetch (TEXT CONST name, TASK CONST task)
+ Zweck: Kopieren einer Datei in die Benutzer-Task von 'task'. Beispiel:
+
+ fetch ("datei", public)
+
+ PROC fetch (THESAURUS CONST thesaurus)
+ Zweck: Holt alle im 'thesaurus' enthaltenen Dateien von der Vater-Task.
+
+ PROC fetch (THESAURUS CONST thesaurus, TASK CONST manager)
+ Zweck: Holt alle im 'thesaurus' enthaltenen Dateien von der 'manager'-
+ Task.
+
+forget (F)
+ PROC forget (TEXT CONST name)
+ Zweck: Löschen einer Datei mit dem Namen 'name' in der Benutzer-Task.
+ Fehlerfälle:
+ * ... gibt es nicht
+ Die Datei mit dem Namen 'name' existiert nicht in der Benutzer-
+ Task.
+
+ PROC forget (DATASPACE VAR ds)
+ Zweck: Löschen des Datenraums 'ds'.
+
+ PROC forget (THESAURUS CONST thesaurus)
+ Zweck: Löscht die im 'thesaurus' enthaltenen Dateinamen in der Benutzer-
+ Task. Beispiel:
+
+ forget (SOME myself)
+
+ PROC forget (TEXT CONST file name, QUIET CONST q)
+ Zweck: Löschen der Datei 'file name' ohne Anfrage. Als zweiter Parameter
+ muß 'quiet' übergeben werden. Beispiel:
+
+ forget ("hugo", quiet)
+
+get (F)
+ PROC get (FILE VAR f, INT VAR number)
+ Zweck: Lesen eines INT-Wertes 'number' von der Datei 'f'.
+
+ PROC get (FILE VAR f, REAL VAR number)
+ Zweck: Lesen eines REAL-Wertes 'number' von der Datei 'f'.
+
+ PROC get (FILE VAR f, TEXT VAR text)
+ Zweck: Lesen eines TEXT-Wertes 'text' von der Datei 'f'.
+
+ PROC get (FILE VAR f, TEXT VAR text, TEXT CONST delimiter)
+ Zweck: Lesen eines TEXT-Wertes 'text' von der Datei 'f', bis das Zeichen
+ 'delimiter' angetroffen wird. Ein eventueller Zeilenwechsel in der
+ Datei wird dabei nicht übergangen.
+
+ PROC get (FILE VAR f, TEXT VAR text, INT CONST maxlength)
+ Zweck: Lesen eines TEXT-Wertes 'text' von der Datei 'f' mit 'maxlength'
+ Zeichen. Ein eventueller Zeilenwechsel in der Datei wird dabei
+ nicht übergangen.
+
+getline (F)
+ PROC get line (FILE VAR file, TEXT VAR record)
+ Zweck: Lesen einer Zeile 'record' von einer sequentiellen Datei 'file'.
+ Die Datei muß mit 'input' assoziiert sein (vergl. 'sequential
+ file').
+ Fehlerfälle:
+ * file not open
+ Die Datei 'file' ist gegenwärtig nicht assoziiert.
+ * input after end of file
+ Es wurde versucht, über die letzte Zeile einer Datei zu lesen.
+ * input access to output file
+ Es wurde versucht, von einem mit 'output' assoziierten FILE zu
+ lesen.
+
+global manager
+ PROC global manager
+ Zweck: Durch den Aufruf der Prozedur wird die Benutzer-Task zu einem
+ Datei-Manager. Danach können Söhne dieser Task eingerichtet
+ werden.
+
+input (F)
+ PROC input (FILE VAR f)
+ Zweck: Ändern der Verarbeitungsart von 'modify' oder 'output' in 'input'.
+ Dabei wird auf den ersten Satz der Datei positioniert.
+
+ TRANSPUTDIRECTION CONST input
+ Zweck: Assoziierung in Zusammenhang mit der Prozedur 'sequential file'
+ einer sequentiellen Datei mit der 'TRANSPUTDIRECTION' 'input' (nur
+ lesen).
+
+insert record (F)
+ PROC insert record (FILE VAR file)
+ Zweck: Es wird ein leerer Satz in die Datei 'file' vor die aktuelle
+ Position eingefügt. Dieser Satz kann anschließend mit 'write
+ record' beschrieben werden (d.h. der neue Satz ist jetzt der
+ aktuelle Satz). Die Datei 'file' muß mit der Verarbeitungsart
+ 'modify' assoziiert worden sein.
+
+line no (F)
+ INT PROC line no (FILE CONST file)
+ Zweck: Liefert die aktuelle Zeilennummer.
+
+line (F)
+ PROC line (FILE VAR file)
+ Zweck: Positionierung auf die nähhste Zeile der Datei 'file'. Die Datei
+ 'file' darf mit 'output' oder 'input' assoziiert sein. Wird ver-
+ sucht, über das Ende eines mit 'input' assoziierten FILEs zu
+ positionieren, wird keine Aktion vorgenommen.
+
+ PROC line (FILE VAR file, INT CONST lines)
+ Zweck: Positionierung auf 'lines' nächste Zeilen der Datei 'file'. Die
+ Datei 'file' darf mit 'output' oder 'input' assoziiert sein. Wird
+ versucht, über das Ende eines mit 'input' assoziierten FILEs zu
+ positionieren, wird keine Aktion vorgenommen. Ist 'lines' <= 0,
+ wird keine Aktion durchgeführt.
+
+lines (F)
+ PROC lines (FILE VAR f)
+ Zweck: Liefert die Anzahl der Zeilen der Datei 'f'.
+
+list
+ PROC list
+ Zweck: Listet alle Dateien der Benutzer-Task mit Namen und Datum des
+ letzten Zugriffs auf dem Terminal auf.
+
+ PROC list (FILE VAR f)
+ Zweck: Schreibt alle Dateien der Benutzer-Task mit Namen und Datum der
+ letzten Änderung in die Datei 'f'.
+
+ PROC list (TASK CONST task)
+ Zweck: Listet alle Dateien der angegebenen 'task' mit Namen und Datum der
+ letzten Änderung auf dem Terminal auf. Beispiel:
+
+ list (father)
+
+max line length (F)
+ INT PROC max line length (FILE CONST file)
+ Zweck: Informationsprozedur über die Anzahl von Zeichen in einer Zeile
+ der Datei 'file'. Standardmäßig sind die Anzahl der Zeichen einer
+ Zeile wie beim Editor 77 Zeichen.
+
+ PROC max line length (FILE VAR file, INT CONST number)
+ Zweck: Setzen der Anzahl von Zeichen einer Zeile in dem FILE 'file'.
+
+modify (F)
+ TRANSPUTDIRECTION CONST modify
+ Zweck: Diese Betriebsrichtung erlaubt das Vorwärts- und Rückwärts-Posi-
+ tionieren und das beliebige Einfügen und Löschen von Sätzen.
+ 'modify' wird für die Assoziierungsprozedur 'sequential file'
+ benötigt.
+
+ PROC modify (FILE VAR f)
+ Zweck: Ändern der Betriebsrichtung von 'input' oder 'output' in die Be-
+ triebsrichtung 'modify'.
+
+myself
+ TASK PROC myself
+ Zweck: Liefert den internen Task-Bezeichner der Benutzer-Task. Beispiel:
+
+ save (ALL myself, father)
+
+name
+ TEXT PROC name (TASK CONST task)
+ Zweck: Liefert den TEXT-Namen von 'task'. Beispiel:
+
+ put (name (myself))
+
+new (F)
+ DATASPACE PROC new (TEXT CONST name)
+ Zweck: Richtet eine neue Datei in der Benutzer-Task ein.
+ Fehlerfälle:
+ * file already exists
+ Die Datei mit dem Namen 'name' existiert bereits in der Benutzer-
+ Task.
+ * directory overflow
+ Die Anzahl der zulässigen Dateien in der Benutzer-Task ist über-
+ schritten.
+
+nilspace (F)
+ DATASPACE CONST nilspace
+ Zweck: Liefert einen leeren Datenraum.
+
+old (F)
+ DATASPACE PROC old (TEXT CONST name)
+ Zweck: Eine bereits vorhandene Datei der Benutzer-Task wird erneut zur
+ Bearbeitung angemeldet.
+ Fehlerfälle:
+ * ... gibt es nicht
+ Die Datei mit dem Namen 'name' ist nicht in der Benutzer-Task
+ vorhanden.
+
+output (F)
+ PROC output (FILE VAR file)
+ Zweck: Ändern der Verarbeitungsart von 'input' oder 'modify' in 'output'.
+ Dabei wird hinter den letzten Satz der Datei positioniert.
+
+ TRANSPUTDIRECTION CONST output
+ Zweck: In Verbindung mit der Prozedur 'sequential file' kann eine Datei
+ assoziiert werden mit der Betriebsrichtung 'output' (nur
+ schreiben).
+
+pattern found
+ BOOL PROC pattern found
+ Zweck: Liefert TRUE, sofern die letzte Suchoperation (siehe 'down' und
+ 'up') erfolgreich war, sonst FALSE.
+
+printer
+ TASK PROC printer
+ Zweck: Liefert den internen TASK-Bezeichner der SPOOLer-Task für den
+ Drucker. Beispiel:
+
+ save ("datei", printer)
+
+public
+ TASK PROC public
+ Zweck: Liefert den internen Task-Bezeichner von "PUBLIC". Beispiel:
+
+ fetch ("datei", public)
+
+put (F)
+ PROC put (FILE VAR f, INT CONST number)
+ Zweck: Ausgabe eines INT-Wertes 'number' in die Datei 'f'. Dabei wird ein
+ Leerzeichen an die Ausgabe angefügt.
+
+ PROC put (FILE VAR f, REAL CONST number)
+ Zweck: Ausgabe eines REAL-Wertes 'number' in die Datei 'f'. Dabei wird
+ ein Leerzeichen an die Ausgabe angefügt.
+
+ PROC put (FILE VAR f, TEXT CONST text)
+ Zweck: Ausgabe eines TEXT-Wertes 'text' in die Datei 'f'. Dabei wird ein
+ Leerzeichen an die Ausgabe angefügt.
+
+putline (F)
+ PROC putline (FILE VAR file, TEXT CONST record)
+ Zweck: Ausgabe eines TEXTes 'record' in die Datei 'file'. 'file' muß mit
+ 'output' assoziiert sein.
+ Fehlerfälle:
+ * file not open
+ Die Datei 'file' ist gegenwärtig nicht assoziiert.
+ * output access to input file
+ Es wurde versucht, auf einen mit 'input' assoziierten FILE zu
+ schreiben.
+
+read record (F)
+ PROC read record (FILE CONST file, TEXT VAR record)
+ Zweck: Liest den aktuellen Satz der Datei 'file' in den TEXT 'record'.
+ Die Position wird dabei nicht verändert. Die Datei 'file' muß mit
+ der Verarbeitungsart 'modify' assoziiert worden sein.
+
+reinsert (F)
+ PROC reinsert (FILE VAR f)
+ Zweck: Einfügen von "vorsichtig gelöschten" Zeilen (vergl. 'remove') an
+ der aktuellen Position.
+
+release
+ PROC release (TASK CONST task)
+ Zweck: Aufgabe der Reservierung des Archivs. Ein implizites 'release'
+ wird automatisch fünf Minuten nach der letzten Archiv-Operation
+ gegeben, sofern ein 'archive' eines anderen Nutzers vorliegt.
+ Beispiel:
+
+ release (archive)
+
+rename (F)
+ PROC rename (TEXT CONST oldname, newname)
+ Zweck: Umbenennen einer Datei von 'oldname' in 'newname'.
+
+remainder
+ THESAURUS PROC remainder
+ Zweck: Liefert nach der Unterbrechung einer Thesaurus-Operation den
+ "Rest"-Thesaurus.
+
+reorganize (F)
+ PROC reorganize (TEXT CONST filename)
+ Zweck: Reorganisiert eine Datei. Die durch eventuelles Einfügen und
+ Löschen entstandene Lücken werden eliminiert und die Anordung der
+ Sätze der Datei wird linearisiert.
+
+reset (F)
+ PROC reset (FILE VAR file)
+ Zweck: Positionieren in einem FILE auf den Anfang (bei mit 'input' asso-
+ ziierten FILEs) oder auf das Ende (bei mit 'output' assoziierten
+ FILEs).
+
+reset range (F)
+ PROC reset range (FILE VAR file)
+ Zweck: Setzt alle Einschränkungen auf 'file' zurück. Siehe auch 'set
+ range'.
+
+remove (F)
+ PROC remove (FILE VAR f, INT CONST anzahl)
+ Zweck: Löscht eine 'anzahl' von Zeilen "vorsichtig" aus der Datei 'f',
+ die mit 'reinsert' an anderer Stelle wieder eingesetzt werden
+ können.
+
+save
+ PROC save (TEXT CONST datei)
+ Zweck: Datei 'datei' wird an die unmittelbare Vater-Task übertragen.
+ Fehlerfälle:
+ * ... gibt es nicht
+ Eine Datei mit dem Namen 'datei' existiert nicht in der Benutzer-
+ Task.
+ * directory overflow
+ Die Anzahl der zulässigen Dateien in 'task' ist überschritten.
+ * wrong password
+ Es wurde mit der Prozedur 'enter password' nicht das richtige
+ Paßwort angegeben.
+
+ PROC save (TEXT CONST name, TASK CONST task)
+ Zweck: Datei mit dem Namen 'name' in Task 'task' kopieren. Beispiel:
+
+ save ("meine datei", father)
+
+ Fehlerfälle:
+ * ... gibt es nicht
+ Eine Datei mit dem Namen 'name' existiert nicht in der Benutzer-
+ Task.
+ * directory overflow
+ Die Anzahl der zulässigen Dateien in der angegebenen task ist
+ überschritten.
+ * wrong password
+ Es wurde mit der Prozedur 'enter password' nicht das richtige
+ Paßwort angegeben.
+
+ PROC save (THESAURUS CONST thesaurus)
+ Zweck: Kopiert die Dateien, die in 'thesaurus' enthalten sind, in die
+ Vater-Task. Beispiel:
+
+ save (SOME myself)
+
+ PROC save (THESAURUS CONST thesaurus, TASK CONST manager)
+ Zweck: Kopiert die Dateien, die in 'thesaurus' enthalten sind, in Task
+ 'manager'.
+
+segments (F)
+ INT PROC segments (FILE CONST f)
+ Zweck: Liefert die Anzahl der Datei-Segmente von 'f'. Nach 'reorganize'
+ besteht 'f' aus einem Segment. Einfügungen oder Löschungen
+ erhöhen die Segmentanzahl.
+
+sequential file (F)
+ FILE PROC sequential file (TRANSPUTDIRECTION CONST mode, DATASPACE VAR ds)
+ Zweck: Assoziierung einer sequentiellen Datei mit dem Dataspace 'ds' und
+ der Betriebsrichtung 'TRANSPUTDIRECTION' (vergl. 'modify', 'input'
+ bzw. 'output'). Diese Prozedur dient zur Assoziierung eines tempo-
+ rären Datenraums in der Benutzer-Task, der nach der Beendigung
+ des Programmlaufs nicht mehr zugriffsfähig ist (weil der Name des
+ Datenraums nicht mehr ansprechbar ist). Somit muß der Datenraum
+ explizit vom Programm gelöscht werden.
+
+ FILE PROC sequential file (TRANSPUTDIRECTION CONST mode, TEXT CONST name)
+ Zweck: Assoziierung einer sequentiellen Datei mit dem Namen 'name' und
+ der Betriebsrichtung 'TRANSPUTDIRECTION' (vergl. 'input' bzw.
+ 'output'). Existiert der FILE bereits, dann wird mit 'input' auf
+ den Anfang des FILEs, bei 'output' hinter den letzten Satz der
+ Datei positioniert. Existiert dagegen der FILE noch nicht und ist
+ die TRANSPUTDIRECTION 'output', wird ein neuer FILE eingerichtet.
+ Fehlerfall:
+ * input file not existing
+ Es wurde versucht, einen nicht vorhandenen FILE mit 'input' zu
+ assoziieren.
+
+set range (F)
+ PROC set range (FILE VAR f, INT CONST anz, INT CONST column, FRANGE VAR b)
+ Zweck: Schränkt die Datei 'f' auf 'anz' Zeilen beginnend bei der Position
+ 'column' der aktuellen Zeile. Der "alte" Datei-Bereich wird in 'b'
+ gespeichert.
+
+ PROC set range (FILE VAR f, FRANGE VAR b)
+ Zweck: Setzt die Datei 'f' auf die in 'b' gespeicherten Bereich zurück.
+
+son
+ TASK PROC son (TASK CONST task)
+ Zweck: Liefert den internen Task-Bezeichner der Sohn-Task. Beispiel:
+
+ put (name (son (myself)))
+
+SOME
+ THESAURUS OP SOME (THESAURUS CONST thesaurus)
+ Zweck: Bietet den angegebenen 'thesaurus' zum Editieren an. Dabei können
+ nicht erwünschte Namen gestrichen werden.
+
+ THESAURUS OP SOME (TASK CONST task)
+ Zweck: Bietet einen THESAURUS von 'task' zum Editieren an.
+
+ THESAURUS OP SOME (TEXT CONST file name)
+ Zweck: Bietet einen 'thesaurus', der aus 'file name' gebildet wird, zum
+ editieren an.
+
+to line (F)
+ PROC to line (FILE VAR f, INT CONST number)
+ Zweck: Positionierung auf die Zeile 'number'. Nur erlaubt in der
+ Betriebsrichtung 'modify'.
+
+task
+ TASK PROC task (TEXT CONST task name)
+ Zweck: Liefert den internen Task-Bezeichner von 'task name'. Beispiel:
+
+ save ("datei", task ("PUBLIC"))
+
+ (* das gleiche wie: *)
+
+ save ("datei", public)
+
+type (F)
+ INT PROC type (DATASPACE CONST ds)
+ Zweck: Liefert den frei wählbaren (INT-) Schlüssel des Datenraums 'ds'.
+ Wurde der Datenraum noch nie angekoppelt, so liefert die Prozedur
+ 'type' einen Wert < 0, erfolgte eine Ankopplung und hat ein
+ Programmierer für den Datenraum 'ds' noch keinen anderen Schlüssel
+ festgelegt, so liefert 'type' den Wert '0'.
+
+ PROC type (DATASPACE CONST ds, INT CONST type)
+ Zweck: Setzt den frei wählbaren Schlüssel 'type' für den Datenraum 'ds'
+ (vergl. obige Prozedur 'type').
+
+up (F)
+ PROC up (FILE VAR f)
+ Zweck: Positionieren um eine Zeile rückwärts in der Datei 'f'.
+
+ PROC up (FILE VAR f, INT CONST number)
+ Zweck: Positionieren um 'number' Zeilen rückwärts in der Datei 'f'.
+
+ PROC up (FILE VAR f, TEXT CONST pattern)
+ Zweck: Suche nach 'pattern' rückwärts in der Datei 'f'. Wird 'pattern'
+ gefunden, ist die Position das erste Zeichen von 'pattern'.
+ Andernfalls steht man auf dem ersten Zeichen der Datei. Achtung:
+ 'down' sucht vom nächsten Zeichen links ab, so daß wiederholtes
+ Suchen keine Endlosschleife ergibt.
+
+ PROC up (FILE VAR f, TEXT CONST pattern, INT CONST number)
+ Zweck: Wie obiges 'up', aber maximal nur 'number'-Zeilen weit.
+
+uppety (F)
+ PROC uppety (FILE VAR f, TEXT CONST pattern)
+ Zweck: Suche nach 'pattern' rückwärts in der Datei 'f'. Wird 'pattern'
+ gefunden, ist die Position das erste Zeichen von 'pattern'.
+ Andernfalls steht man auf dem ersten Zeichen der Datei. Achtung:
+ 'uppety' sucht (im Gegensatz zu 'up') vom aktuellen Zeichen.
+
+ PROC uppety (FILE VAR f, TEXT CONST pattern, INT CONST number)
+ Zweck: Wie obiges 'uppety', aber maximal nur 'number'-Zeilen weit.
+
+word (F)
+ TEXT PROC word (FILE CONST f)
+ Zweck: Liefert das aktuelle Wort (bis zum nächsten Leerzeichen oder
+ Zeilenende).
+
+ TEXT PROC word (FILE CONST f, TEXT CONST sep)
+ Zweck: Liefert einen Text von der aktuellen Position bis zum nächsten
+ 'sep-Zeichen oder Zeilenende.
+
+ TEXT CONST word (FILE CONST f, INT CONST len)
+ Zweck: Liefert einen Text von der aktuellen Position mit der Länge 'len'
+ bzw. bis zum Zeilenende.
+
+write (F)
+ PROC write (FILE VAR f, TEXT CONST text)
+ Zweck: Schreibt 'text' in die Datei 'f' (analog 'put (f, text)'), aber
+ ohne Trennblank.
+
+write record (F)
+ PROC write record (FILE VAR file, TEXT CONST record)
+ Zweck: Schreibt einen Satz in die Datei 'file' an die aktuelle Position.
+ Dieser Satz muß bereits vorhanden sein, d.h. mit 'write record'
+ kann keine leere Datei beschrieben werden, sondern es wird der
+ Satz an der aktuellen Position überschrieben. Die Position in der
+ Datei wird nicht verändert. Die Datei 'file' muß mit der Verar-
+ beitungsart 'modify' assoziiert worden sein.
+
+
diff --git a/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil8 b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil8
new file mode 100644
index 0000000..16e4d07
--- /dev/null
+++ b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil8
@@ -0,0 +1,1345 @@
+ EUMEL-Benutzerhandbuch
+
+ TEIL 8: Standardpakete
+
+
+1. Übersicht
+
+Hier werden die im EUMEL-System verfügbaren Prozeduren und Operatoren aufge-
+führt, die nicht bereits in anderen Teilen des Benutzerhandbuchs beschrieben
+wurden.
+
+Die meisten der hier beschriebenen Objekte werden nicht vom ELAN-Compiler,
+sondern von vorübersetzten Moduln (PACKETs) realisiert (vergl. dazu auch den
+Quellcode). Die in diesem Teil beschriebenen Prozeduren und Operatoren
+weisen einige wenige Modifikationen, aber beträchtliche Erweiterungen gegen-
+über dem Standard auf, um sie für die Zwecke des EUMEL-Systems anzupassen.
+Hier werden nur diejenigen Objekte aufgeführt, die bei einer System-Aus-
+lieferung dem EUMEL-System beigefügt sind. Jeder Installation ist es frei-
+gestellt, diesen "EUMEL-Standard" zu erweitern oder zu modifizieren.
+
+Die Operationen des EUMEL-Standards lassen sich in verschiedene Klassen -
+je nach Aufgabenbereich - ordnen.
+
+
+
+Ein-/Ausgabe
+
+Die Ein-/Ausgabe erfolgt im EUMEL-System in der Regel auf dem Terminal des
+Benutzers. Sie kann aber auch in einen File umgeleitet werden.
+
+Die Ein-/Ausgabe eines Programms erfolgt in der Regel auf dem Terminal des
+Benutzers, welches einem Prozeß zugeordnet ist. Die Eingabe vom Bildschirm
+kann man mit den Prozeduren
+
+ get
+
+programmieren, welche INT, REAL und TEXT-Werte einlesen. Bei der Eingabe
+kann der Eingabetext editiert werden (Zeichen löschen, einfügen, über-
+schreiben oder Lernsequenzen abrufen). Die Ausgabe erfolgt mit den Proze-
+duren
+
+ put
+
+(für INT-, REAL- und TEXT-Werte). Von den 'put'-Prozeduren wird ein Leer-
+zeichen an eine Ausgabe angefügt, um diese von der vorhergehenden zu trennen.
+Zusätzlich existiert die
+
+ write
+
+Prozedur, welche an die Ausgabe kein Leerzeichen anfügt. Mit
+
+ line
+
+kann man eine Positionierung auf eine neue Zeile bei der Ein-/Ausgabe er-
+wirken. Mit
+
+ getline
+ putline
+
+kann eine ganze Zeile eingelesen bzw. ausgegeben werden.
+
+Wie bereits erwähnt, erfolgt die Ein-/Ausgabe in der Regel auf dem Terminal
+des Benutzers. Es ist jedoch möglich, die Ein-/Ausgabe dieser Prozeduren
+"umzuleiten". Diese Umleitung erfolgt in eine oder von einer Datei. Dazu
+gibt es die Prozeduren
+
+ online (* liefert TRUE, wenn die Task an ein Terminal
+ gekoppelt ist *)
+ sysout ("name") (* Ausgabe erfolgt in die Datei 'name'. 'sysout
+ ("")' schaltet auf das Terminal zurück *)
+ sysout (* Liefert den Namen der eingestellten 'sysout'-
+ Datei. Wird "" geliefert, ist man an ein
+ Terminal gekoppelt *)
+ sysin ("name") (* Umschaltung der Eingabe vom Terminal auf die
+ Datei 'name'. sysin ("")' schaltet auf das
+ Terminal zurück *)
+ sysin (* Liefert den Namen der eingestellten 'sysin'-
+ Datei. Wird "" geliefert, ist man an ein
+ Terminal gekoppelt *)
+
+Wie bereits erwähnt, ist die Umschaltung nur für die Prozeduren 'get' und
+'put'/'write', sowie 'getline' und 'putline' und die Prozedur 'line' möglich.
+(Die folgenden Prozeduren haben immer eine Wirkung auf das Benutzer-
+Terminal). Die Prozedur
+
+ out
+
+schreibt wie 'write' einen Text auf den Bildschirm (läßt sich aber nicht
+"umleiten").
+
+ cout
+
+schreibt einen INT-Wert an die aktuelle Cursor-Position auf den Bildschirm
+und positioniert anschließend auf diese Position wieder zurück. Diese
+Prozedur wird vorwiegend für Kontroll-Ausgaben (z.B. Zeilennummern) benutzt.
+Ist die Task nicht angekoppelt, geht die Ausgabe ins "Leere"; das Programm
+der Task läuft also weiter (im Gegensatz zu 'put' auf den Bildschirm). Mit
+der Prozedur
+
+ cursor
+
+kann - neben der Möglichkeit des Arbeitens mit Steuerzeichen - auf eine
+bestimmte Position des Bildschirms positioniert werden. Mit
+
+ get cursor
+
+kann die aktuelle Position des Cursors auf dem Terminal des Benutzers er-
+fragt werden. Mit Hilfe der Prozedur
+
+ inchar
+
+kann ein Zeichen vom Bildschirm gelesen werden. Der Prozeß wartet solange,
+bis ein Zeichen eingegeben wird. Dagegen wird bei
+
+ incharety
+
+niltext geliefert, wenn kein Zeichen eingegeben wurde. Eine weitere 'inchare-
+ty'-Prozedur wartet zusätzlich noch eine angebbare Zeitdauer, ob ein Zeichen
+eingegeben wird. Der Operator
+
+ TIMESOUT
+
+stellt einen TEXT mehrfach auf dem Bildschirm dar. Die Prozedur
+
+ page
+
+positioniert auf einen "neuen Bildschirm": der Bildschirm wird gelöscht und
+der Cursor befindet sich anschließend in der linken oberen Ecke des Bild-
+schirms.
+
+
+
+Manipulation von Texten
+
+Ein Text kann im EUMEL-System bis zu 32 000 Zeichen haben. Für TEXTe
+stehen neben der Zuweisung die Vergleichsoperatoren
+
+ = , < , <= , > , >= , <>
+
+zur Verfügung. Dabei ist die lexikographische Reihenfolge der Zeichen (vergl.
+EUMEL-Zeichensatz) zu beachten. Zur Verkettung zweier TEXTe ist der
+
+ +
+
+Operator vorhanden. Der Operator
+
+ *
+
+nimmt eine Vervielfachung eines TEXTes vor. Der Operator
+
+ CAT
+
+konkateniert den linken mit dem rechten Operanden und weist das Resultat dem
+linken Operanden zu. Die Prozeduren
+
+ pos
+
+liefern die Position des ersten Auftretens eines TEXTes oder einer
+Zeichenklasse in einem anderen TEXT. Die Prozeduren
+
+ code
+
+konvertieren ein Zeichen in einen INT-Wert und umgekehrt (vergl. dazu den
+EUMEL-Zeichensatz) und dienen z.B. zur Behandlung von Zeichen, die nicht
+auf einer Tastatur zu finden sind. Die Prozedur
+
+ compress
+
+schneidet führende und nachfolgende Leerzeichen eines TEXTs ab, während
+
+ delete char (* ein Zeichen loeschen *)
+ insert char (* ein Zeichen einfuegen *)
+
+ein Zeichen einfügt bzw. löscht. Mit
+
+ change
+
+kann bei dem erstmaligen Auftreten eines Teiltextes in einem TEXT dieser
+ersetzt werden. Mit
+
+ change all
+
+kann jedesmal, wenn ein Teiltext in einem TEXT auftritt, dieser durch einen
+anderen Text ersetzt werden.
+
+ LENGTH (* oder *)
+ length
+
+liefert die Länge (d.h. die Anzahl der Zeichen in einem TEXT einschließlich
+der Leerzeichen) eines TEXTes. Mit
+
+ replace
+
+kann eine Ersetzung eines Teiltextes erzielt werden. Im Gegensatz zu
+'replace' kann sich bei 'change' die Länge des Textes ändern. Mit
+
+ SUB
+ subtext
+
+kann ein Zeichen ('SUB') oder ein Teiltext ('subtext') aus einem Text geholt
+werden.
+
+TEXTe werden im EUMEL-System über einen Heap realisiert, d.h. nicht wie
+andere Objekte auf einem Stack. Das hat u.a. zur Folge, daß TEXT-"Leichen"
+auf dem Heap nicht automatisch beseitigt werden. Darum kann der benötigte
+Speicherplatz durch TEXT-Operationen anwachsen. Der Heap kann nun von
+unnötigem Speicherplatz durch die Prozedur
+
+ collect heap garbage
+
+bereinigt werden. Die Größe des Heaps (in KB) kann durch die Prozedur
+
+ heap size
+
+erfragt werden. Übrigens überprüft der Standard-Monitor nach jedem Kommando
+die Heap-Größe und veranlaßt eine Bereinigung des Heaps, wenn dieser um
+mindestens 4 KB gewachsen ist.
+
+
+
+Mathematische Operationen
+
+Folgende mathematische Prozeduren bzw. Operatoren stehen im EUMEL zur Zeit
+zur Verfügung (manche Prozeduren stehen in mehr als einer Version zur
+Verfügung, z.B. die sin-Prozedur für Radiant und Winkelgrad):
+
+ ** (* Exponentiation *)
+ abs (* Absolutbetrag *)
+ arctan (* Arcus Tangens-Funktion *)
+ cos (* Kosinus-Funktion *)
+ e (* Eulersche Zahl (2.718282) *)
+ pi (* Die Zahl pi (3.141593) *)
+ exp (* Exponential-Funktion *)
+ floor (* REAL mit abgeschnittenen Nachkommastellen *)
+ frac (* Nachkommastellen eines REALs *)
+ random,
+ initialize random (* Zufallszahlen *)
+ ln, log2, log10 (* Logarithmus-Funktionen *)
+ max, min (* Minimum bzw. Maximum zweier Werte *)
+ MOD (* Modulo-Funktion *)
+ round (* Rundung *)
+ sign (* Vorzeichen feststellen *)
+ sin (* Sinus-Funktion *)
+ sqrt (* Wurzel-Funktion *)
+ tan (* Tangens-Funktion *)
+
+
+
+Konvertierungs-Operationen
+
+Mit den Prozeduren
+
+ text
+
+kann aus einem INT- bzw. REAL-Wert ein TEXT, während mit
+
+ int
+
+aus einem REAL- bzw. TEXT-Wert ein INT und mit
+
+ real
+
+aus einem INT- bzw. TEXT-Wert ein REAL gemacht werden kann. Mit
+
+ last conversion ok
+
+kann abgefragt werden, ob die letzte Umwandlung ohne Fehler bzw. fehlerhaft
+vorgenommen wurde. Mit
+
+ decimal exponent
+
+kann der Exponent eines REAL-Wertes ausgeblendet werden.
+
+
+
+Kommando-Dialog
+
+Die Prozeduren für den Kommando-Dialog dienen zur bequemen Programmierung
+von interaktiven Anfragen an einen Benutzer eines Programms. (Diese
+Prozeduren werden u.a. auch vom Monitor verwendet). Der Kommando-Dialog
+ist im Normalfall eingeschaltet. Mit der Prozedur
+
+ command dialogue
+
+kann man den Kommando-Dialog ein- bzw. ausschalten. Mit der Prozedur
+
+ say
+
+kann - sofern der Kommando-Dialog eingeschaltet ist - ein Text auf dem
+Bildschirm ausgegeben werden. Sofern der Kommando-Dialog eingeschaltet ist,
+schreibt die Prozedur
+
+ yes
+
+einen Text auf den Bildschirm des Benutzers. An den Text wird '(j/n) ?'
+angefügt. Die Prozedur 'yes' liefert den Wert TRUE, sofern der Benutzer auf
+die Frage mit dem Zeichen "j" antwortet und den Wert FALSE, sofern die
+Antwort "n" lautete. Die Prozedur
+
+ no
+
+arbeitet wie 'NOT yes'.
+
+
+
+Verschiedenes
+
+Mit den Prozeduren
+
+ stop
+ errorstop
+
+kann ein Abbruch (letztere mit Meldung; vergl. Fehlerbehandlung im System-
+handbuch) erreicht werden. Die Prozedur
+
+ clock
+
+liefert Zeitwerte als REAL-Wert, nämlich die verbrauchte CPU-Zeit einer Task
+oder die aktuelle Uhrzeit (inklusive Datum). Die Prozedur
+
+ time of day
+
+liefert die aktuelle Uhrzeit. Mit den Konvertierungsprozeduren
+
+ date
+ time
+
+können die Werte der Prozedur 'clock' in eine lesbare Form gebracht werden.
+Mit der Prozedur
+
+ pause
+
+kann eine bestimmte Zeitdauer gewartet werden, ohne den Prozessor zu be-
+lasten. Die Wartezeit wird abgebrochen, wenn die Zeitgrenze erreicht ist
+oder sobald ein Zeichen am Terminal des Benutzers eingegeben wurde. Dieses
+Zeichen wird nicht verarbeitet.
+
+
+
+2. Die EUMEL-Standardpakete
+
+Die elementaren Datentypen BOOL, INT, REAL, TEXT und die entsprechenden Zu-
+weisungsoperatoren werden hier nicht angegeben.
+
+=
+ BOOL OP = (INT CONST a, b)
+ Zweck: Vergleich.
+
+ BOOL OP = (REAL CONST a, b)
+ Zweck: Vergleich.
+
+ BOOL OP = (TEXT CONST left, right)
+ Zweck: Vergleich von zwei Texten auf Gleichheit (Texte mit ungleichen
+ Längen sind immer ungleich).
+
+<
+ BOOL OP < (INT CONST a, b)
+ Zweck: Vergleich auf kleiner.
+
+ BOOL OP < (REAL CONST a, b)
+ Zweck: Vergleich auf kleiner.
+
+ BOOL OP < (TEXT CONST left, right)
+ Zweck: Vergleich zweier Texte auf kleiner ('left' kommt lexikographisch
+ vor 'right').
+
+>
+ BOOL OP > (INT CONST a, b)
+ Zweck: Vergleich auf größer.
+
+ BOOL OP > (REAL CONST a, b)
+ Zweck: Vergleich auf größer.
+
+ BOOL OP > (TEXT CONST left, right)
+ Zweck: Vergleich zweier Texte auf größer ('left' kommt lexikographisch
+ nach 'right').
+
+<=
+ BOOL OP <= (INT CONST a, b)
+ Zweck: Vergleich auf kleiner gleich.
+
+ BOOL OP <= (REAL CONST a, b)
+ Zweck: Vergleich auf kleiner gleich.
+
+ BOOL OP <= (TEXT CONST left, right)
+ Zweck: Vergleich von zwei Texten auf kleiner gleich ('left' kommt
+ lexikographisch vor oder ist gleich 'right').
+
+>=
+ BOOL OP >= (INT CONST a, b)
+ Zweck: Vergleich auf größer gleich.
+
+ BOOL OP >= (REAL CONST a, b)
+ Zweck: Vergleich auf größer gleich.
+
+ BOOL OP >= (TEXT CONST left, right)
+ Zweck: Vergleich zweier Texte auf größer gleich ('left' kommt lexiko-
+ graphisch nach oder ist gleich 'right').
+
+<>
+ BOOL OP <> (INT CONST a, b)
+ Zweck: Vergleich auf Ungleichheit.
+
+ BOOL OP <> (REAL CONST a, b)
+ Zweck: Vergleich auf Ungleichheit.
+
+ BOOL OP <> (TEXT CONST left, right)
+ Zweck: Vergleich von zwei Texten auf Ungleichheit (Texte mit ungleichen
+ Längen sind stets ungleich).
+
++
+ INT OP + (INT CONST a)
+ Zweck: Monadischer Operator (Vorzeichen, ohne Wirkung).
+
+ REAL OP + (REAL CONST a)
+ Zweck: Monadischer Operator (Vorzeichen, ohne Wirkung).
+
+ INT OP + (INT CONST a, b)
+ Zweck: Addition.
+
+ REAL OP + (REAL CONST a, b)
+ Zweck: Addition.
+
+ TEXT OP + (TEXT CONST left, right)
+ Zweck: Verkettung der Texte 'left' und 'right' in dieser Reihenfolge. Die
+ Länge des Resultats ergibt sich aus der Addition der Längen der
+ Operanden.
+
+-
+ INT OP - (INT CONST a)
+ Zweck: Vorzeichen-Umkehrung.
+
+ REAL OP - (REAL CONST a)
+ Zweck: Vorzeichen-Umkehrung.
+
+ INT OP - (INT CONST a, b)
+ Zweck: Subtraktion.
+
+ REAL OP - (REAL CONST a, b)
+ Zweck: Subtraktion.
+
+*
+ INT OP * (INT CONST a, b)
+ Zweck: Multiplikation.
+
+ REAL OP * (REAL CONST a, b)
+ Zweck: Multiplikation.
+
+ TEXT OP * (INT CONST times, TEXT CONST source)
+ Zweck: 'times' fache Erstellung von 'source' und Verkettung. Dabei muß
+
+ times >= 0
+
+ sein, sonst wird 'niltext' geliefert.
+
+/
+ REAL OP / (REAL CONST a, b)
+ Zweck: Division.
+ Fehlerfall:
+ * Division durch 0
+
+**
+ INT OP ** (INT CONST arg, exp)
+ Zweck: Exponentiation mit 'exp' >= 0
+ Fehlerfälle:
+ * INT OP ** : negative exponent
+ Ein negativer Exponent ist nicht zugelassen.
+ * 0 ** 0 is not defined
+ 'arg' und 'exp' dürfen nicht beide 0 sein.
+
+ REAL OP ** (REAL CONST arg, exp)
+ Zweck: Exponentiation.
+ Fehlerfälle:
+ * hoch mit negativer basis
+ Der 'exp' muß >= 0.0 sein.
+ * 0**0 geht nicht
+ 'arg' und 'exp' dürfen nicht gleichzeitig 0.0 sein.
+
+ REAL OP ** (REAL CONST arg, INT CONST exp)
+ Zweck: Exponentiation.
+ Fehlerfall:
+ * 0.0 ** 0 geht nicht
+
+abs
+ INT PROC abs (INT CONST argument)
+ Zweck: Absolutbetrag eines INT-Wertes.
+
+ INT OP ABS (INT CONST argument)
+ Zweck: Absolutbetrag eines INT-Wertes.
+
+ REAL PROC abs (REAL CONST value)
+ Zweck: Absolutbetrag eines REAL-Wertes.
+
+ REAL OP ABS (REAL CONST value)
+ Zweck: Absolutbetrag eines REAL-Wertes.
+
+AND
+ BOOL OP AND (BOOL CONST a, b)
+ Zweck: Logisches und.
+
+arctan
+ REAL PROC arctan (REAL CONST x)
+ Zweck: Arcus Tangens-Funktion. Liefert einen Wert in Radiant.
+
+arctand
+ REAL PROC arctand (REAL CONST x)
+ Zweck: Arcus Tangens-Funktion. Liefert einen Wert in Grad.
+
+CAT
+ OP CAT (TEXT VAR left, TEXT CONST right)
+ Zweck: Hat die gleiche Wirkung wie
+
+ left := left + right
+
+ Hinweis: Der Operator 'CAT' hat eine geringere Heap-Belastung als
+ die Operation mit expliziter Zuweisung.
+
+change
+ PROC change (TEXT VAR destination, TEXT CONST old, new)
+ Zweck: Ersetzung des (Teil-) TEXTes 'old' in 'destination' durch 'new' bei
+ dem erstmaligen Auftreten. Ist 'old' nicht in 'source' vorhanden,
+ so wird keine Meldung abgesetzt (Abweichung vom Standard). Beachte,
+ daß sich dabei die Länge von 'destination' verändern kann.
+ Beispiel:
+
+ TEXT VAR mein text :: "EUMEL-Benutzerhandbuch";
+ change (mein text, "Ben", "N"); (* EUMEL-Nutzerhandbuch *)
+
+PROC change (TEXT VAR destination, INT CONST from, to, TEXT CONST new)
+ Zweck: Der TEXT 'new' wird in den TEXT 'destination' anstatt des TEXTes,
+ der zwischen 'from' und 'to' steht, eingesetzt. Beachte, daß sich
+ dabei die Länge von 'destination' ändern kann. Beispiel:
+
+ TEXT VAR mein text :: "EUMEL-Benutzerhandbuch";
+ change (mein text, 7, 9, "N"); (* wie oben *)
+
+change all
+ PROC change all (TEXT VAR destination, TEXT CONST old, new)
+ Zweck: Der Teiltext 'old' wird durch 'new' in 'destination' ersetzt. Im
+ Unterschied zur 'change'-Prozedur findet die Ersetzung nicht nur
+ bei dem erstmaligen Auftreten von 'old' statt, sondern so oft, wie
+ 'old' in 'destination' vorhanden ist. Beispiel:
+
+
+ TEXT VAR x :: "Das ist ein Satz";
+ change all (x, " ", ""); (* DasisteinSatz *)
+
+clock
+ REAL PROC clock (INT CONST index)
+ Zweck: Datum und Uhrzeit werden vom EUMEL-System für alle Tasks geführt.
+ Neben einer Uhr ('Realzeituhr'), die das Datum und die aktuelle
+ Uhrzeit enthält, wird eine Uhr für die von der Task verbrauchte
+ CPU-Zeit geführt ('CPU-Zeituhr'). Beide Zeiten werden vom System
+ als REALs realisiert. Die Prozedur 'clock' liefert die aktuellen
+ Werte dieser Uhren. Bei 'index = 0' wird die akkumulierte CPU-Zeit
+ der Task, bei 'index = 1' der Wert der Realzeituhr geliefert.
+
+ Mit den REAL-Werten der Uhren kann ohne weiteres gerechnet werden,
+ jedoch sind nur Werte > 0 definiert. Die REAL-Werte der Realzeit-
+ uhr beginnen beim 1.1.1900 um 0 Uhr. Es sind nur Werte für dieses
+ Jahrhundert zugelassen. Werte der Realzeituhr in lesbarer Form
+ kann man durch die Konvertierungsprozeduren 'date' (für den
+ aktuellen Tag) und 'time of day' (Uhrzeit) erhalten.
+
+ Um die benötigte CPU-Zeit eines Programms zu berechnen, muß man
+ die CPU-Zeituhr zweimal abfragen. Um solche Zeiten in lesbarer
+ Form zu erhalten, kann man die Konvertierungsprozedur 'time'
+ verwenden. Beispiel:
+
+ REAL CONST anfang :: clock (0);
+ berechnungen;
+ REAL CONST ende :: clock (0);
+ put ("benoetigte CPU-Zeit:");
+ put (time (ende - anfang))
+
+code
+ TEXT PROC code (INT CONST code)
+ Zweck: Wandelt einen INT-Wert 'code' in ein Zeichen um. 'code' muß
+
+ 1 <= code <= 254
+
+ sein.
+
+ INT PROC code (TEXT CONST text)
+ Zweck: Wandelt ein Zeichen 'text' in einen INT-Wert um. Ist
+
+ LENGTH text <> 1
+
+ dann wird der Wert -1 geliefert (also bei mehr als ein Zeichen
+ oder niltext).
+
+collect heap garbage
+ PROC collect heap garbage
+ Zweck: Bereinigung des Heaps von nicht mehr benötigten TEXTen.
+
+command dialogue
+ PROC command dialogue (BOOL CONST status)
+ Zweck: Ein- bzw. Ausschalten des Kommando-Dialogs. Ist der Kommando-
+ dialog eingeschaltet, dann funktionieren z.B. die Prozeduren 'yes'
+ bzw. 'no' und ein Aufruf der Prozedur 'errorstop' liefert eine
+ Fehlermeldung auf dem Terminal. Ist der Kommandodialog ausge-
+ schaltet, wird z.B. durch die Prozedur 'yes' kein Text ausgegeben
+ (es wird TRUE geliefert) und errorstop erzeugt keine Fehler-
+ meldungen.
+
+ BOOL PROC command dialogue
+ Zweck: Liefert den Wert TRUE, wenn der Kommando-Dialog eingeschaltet
+ ist, andernfalls FALSE.
+
+compress
+ TEXT PROC compress (TEXT CONST text)
+ Zweck: Liefert den TEXT 'text' ohne führende und nachfolgende Leerzeichen.
+
+cos
+ REAL PROC cos (REAL CONST x)
+ Zweck: Kosinus-Funktion. 'x' muß in Radiant angegeben werden.
+
+cosd
+ REAL PROC cosd (REAL CONST x)
+ Zweck: Cosinus-Funktion. 'x' muß in Winkelgrad angegeben werden.
+
+cout
+ PROC cout (INT CONST number)
+ Zweck: Schreibt 'number' an die aktuelle Cursor-Position auf den Bild-
+ schirm. Anschließend wird an diese Position wieder zurück positio-
+ niert. 'number' muß > 0 sein. Paßt 'number' nicht mehr auf die
+ Zeile, so ist die Wirkung von 'cout' nicht definiert. 'cout' gibt
+ den Wert von 'number' nur aus, wenn genügend freie Kanal-Kapazität
+ für diese Ausgabe vorhanden ist. Das hat zur Folge, daß Programme
+ nicht auf die Beendigung einer Ausgabe von 'number' warten müssen
+ und ggf. Ausgaben überschlagen werden.
+
+cursor
+ PROC cursor (INT CONST column, row)
+ Zweck: Positioniert den Cursor auf dem Bildschirm, wobei 'column' die
+ Spalte und 'row' die Zeile angibt. Die zulässigen Bereiche von
+ 'column' und 'row' sind geräteabhängig. Zur Zeit gilt auf allen
+ EUMEL-Geräten
+
+ 1 <= column <= 80
+ 1 <= row <= 24
+
+date
+ TEXT PROC date (REAL CONST time)
+ Zweck: Konvertierungsprozedur für das Datum, welches sich aus dem Aufruf
+ der Prozedur 'clock (1)' ergibt. Das Datum wird in der Form
+ 'tt.mm.jj' geliefert. Beispiel:
+
+ put (date (clock (1))) (* z.B.: 24.12.82 *)
+
+
+ REAL PROC date (TEXT CONST datum)
+ Zweck: Konvertierungsprozedur für ein Datum in der Form 'tt.mm.jj'.
+ Liefert einen REAL-Wert, wie ihn die Prozedur 'clock (1)' liefern
+ würde. Beispiel:
+
+ put (date ("24.12.82")) (* 6.270670e10 *)
+
+ TEXT PROC date
+ Zweck: Liefert das Tagesdatum. Wirkt wie 'date (clock (1))', ist jedoch
+ erheblich schneller.
+
+day
+ REAL CONST day
+ Zweck: Liefert die Anzahl der Sekunden eines Tages (86 400.0).
+
+decimal exponent
+ INT PROC decimal exponent (REAL CONST mantisse)
+ Zweck: Liefert aus einem REAL-Wert den dezimalen Exponenten als INT-Wert.
+
+DECR
+ OP DECR (INT VAR left, INT CONST right)
+ Zweck: Wirkt wie left := left - right
+
+ OP DECR (REAL VAR left, REAL CONST right)
+ Zweck: Wirkt wie left := left - right
+
+delete char
+ PROC delete char (TEXT VAR string, INT CONST delete pos)
+ Zweck: Löscht ein Zeichen aus dem Text 'string' an der Position 'delete
+ pos'. Für
+
+ delete pos <= 0
+
+ oder
+
+ delete pos > LENGTH string
+
+ wird keine Aktion vorgenommen.
+
+DIV
+ INT OP DIV (INT CONST a, b)
+ Zweck: INT-Division.
+ Fehlerfall:
+ * DIV by 0
+ Division durch Null.
+
+e
+ REAL CONST e
+ Zweck: Eulersche Zahl (2.718282).
+
+errorstop
+ PROC errorstop (TEXT CONST error message)
+ Zweck: Abbruch unter Ausgabe einer Fehlermeldung (vergl. Fehlerbehand-
+ lung).
+
+exp
+ REAL PROC exp (REAL CONST z)
+ Zweck: Exponentialfunktion.
+
+floor
+ REAL PROC floor (REAL CONST real)
+ Zweck: Schneidet die Nachkommastellen des REAL-Wertes 'real' ab.
+
+frac
+ REAL PROC frac (REAL CONST z)
+ Zweck: Liefert die Stellen eines REAL-Wertes hinter dem Dezimalpunkt.
+
+get
+ PROC get (INT VAR number)
+ Zweck: Einlesen eines INT-Wertes vom Bildschirm. Der einzulesende INT-
+ Wert kann bei der Eingabe vom Terminal editiert werden. Die
+ Eingabe kann vom Benutzer-Terminal so umgeleitet werden, daß sie
+ von einer Datei aus erfolgt (vergl. 'sysin').
+
+ PROC get (REAL VAR value)
+ Zweck: Einlesen eines REAL-Wertes vom Bildschirm. Der einzulesende
+ REAL-Wert kann bei der Eingabe vom Terminal editiert werden. Die
+ Eingabe kann vom Benutzer-Terminal so umgeleitet werden, daß sie
+ von einer Datei aus erfolgt (vergl. 'sysin').
+
+ PROC get (TEXT VAR word)
+ Zweck: Liest einen Text in die Variable 'word' mit maximal 255 Zeichen.
+ Es werden solange Zeichen vom Terminal gelesen, bis ein Leer-
+ zeichen oder ein Positionierungszeichen eingegeben wird. Dabei
+ werden führende Leerzeichen übergeben. Der einzulesende Text kann
+ bei der Eingabe editiert werden. Eine leere Eingabe ist nicht
+ erlaubt. Die Eingabe kann vom Benutzer-Terminal so umgeleitet
+ werden, daß sie von einer Datei aus erfolgt (vergl. 'sysin').
+
+ PROC get (TEXT VAR word, INT CONST laenge)
+ Zweck: Liest einen Text vom Bildschirm mit der Länge 'laenge' oder bis
+ ein Positionierungszeichen angetroffen wird. Der einzulesende Wert
+ kann bei der Eingabe editiert werden. Dabei gilt:
+
+ 1 <= laenge <= 255
+
+ PROC get (TEXT VAR word, TEXT CONST separator)
+ Zweck: Liest einen Text vom Bildschirm, bis ein Zeichen 'separator' ange-
+ troffen oder ein Positionierungszeichen eingegeben wird. Der ein-
+ zulesende Text kann bei der Eingabe editiert werden.
+
+get cursor
+ PROC get cursor (INT VAR x, y)
+ Zweck: Erfragung der aktuellen Cursor-Position. Die Koordinaten des Cur-
+ sors werden in 'x' und 'y' geliefert. Die aktuelle Cursor-Position
+ ist nach Ausgabe von 'HOME' (Code = 1) oder einer Positionierung
+ des Cursors mit der Prozedur 'cursor' stets definiert. Die Proze-
+ dur 'get cursor' liefert jedoch undefinierte Werte, wenn über den
+ rechten Rand einer Zeile hinausgeschrieben wurde (die Wirkung
+ einer solchen Operation hängt von der Hardware eines Terminals ab).
+
+getline
+ PROC get line (TEXT VAR line)
+ Zweck: Das System wartet auf eine Zeile vom Bildschirm (max. 255 Zeichen).
+ Eine leere Eingabe ist nicht möglich. Die Eingabe kann vom Benut-
+ zer-Terminal so umgeleitet werden, daß sie von einer Datei aus
+ erfolgt (vergl. 'sysin').
+
+heap size
+ INT PROC heap size
+ Zweck: Informationsprozedur für die Größe (in KB) des TEXT-Heaps.
+
+hour
+ REAL CONST hour
+ Zweck: Liefert die Anzahl der Sekunden einer Stunde (3600.0).
+
+inchar
+ PROC inchar (TEXT VAR character)
+ Zweck: Wartet solange, bis ein Zeichen von der Tastatur eingegeben wird,
+ und schreibt dieses Zeichen in die Variable 'character'.
+
+incharety
+ TEXT PROC incharety
+ Zweck: Versucht, ein Zeichen von der Tastatur zu lesen. Wurde kein
+ Zeichen eingegeben, wird niltext geliefert.
+
+ TEXT PROC incharety (INT CONST time limit)
+ Zweck: Versucht, ein Zeichen vom Bildschirm zu lesen. Dabei wird maximal
+ eine 'time limit' lange Zeit auf das Zeichen gewartet (gemessen in
+ Zehntel-Sekunden).
+
+INCR
+ OP INCR (INT VAR left, INT CONST right)
+ Zweck: Wirkt wie left := left + right
+
+ OP INCR (REAL VAR left, REAL CONST right)
+ Zweck: Wirkt wie left := left + right
+
+initialize random
+ PROC initialize random (INT CONST value)
+ Zweck: Initialisieren der 'random'-Prozedur, um nicht reproduzierbare
+ Zufallszahlen zu bekommen. Diese 'init random'-Prozedur gilt für
+ den "INT-Random Generator".
+
+ PROC initialize random (REAL CONST z)
+ Zweck: Initialisieren der 'random'-Prozedur mit verschiedenen Werten für
+ 'z', um nicht reproduzierbare Zufallszahlen zu bekommen. Diese
+ Prozedur gilt für den "REAL-Random Generator".
+
+insert char
+ PROC insert char (TEXT VAR string, TEXT CONST char, INT CONST insert pos)
+ Zweck: Fügt ein Zeichen 'char' in den Text 'string' an der Position
+ 'insert pos' ein. Für
+
+ insert pos > LENGTH string + 1
+
+ wird keine Aktion vorgenommen. Daher ist es möglich, mit dieser
+ Prozedur auch am Ende eines Textes (Position: LENGTH string + 1)
+ ein Zeichen anzufügen.
+
+int
+ INT PROC int (REAL CONST a)
+ Zweck: Konvertierungsprozedur.
+
+ INT PROC int (TEXT CONST number)
+ Zweck: Umwandlung eines Textes in einen INT-Wert. Der Text 'number' darf
+ ein "+"- oder "-"-Zeichen vor den Ziffern enthalten. Führende
+ Blanks werden überlesen. Enthält 'number' an einer Position ein
+ Zeichen, das nicht umgewandelt werden kann, so wird die Umwand-
+ lung gestoppt und der bis dahin umgewandelte Wert (bzw. der Wert 0)
+ geliefert.
+
+last conversion ok
+ BOOL PROC last conversion ok
+ Zweck: Liefert den Wert TRUE, sofern die letzte Konvertierungsprozedur
+ nicht auf einen Fehler bei der Umwandlung gestoßen ist, andernfalls
+ FALSE.
+
+length
+ INT PROC length (TEXT CONST text)
+ Zweck: Anzahl von Zeichen ("Länge") von 'text' einschließlich Leerzeichen.
+
+LENGTH
+ INT OP LENGTH (TEXT CONST text)
+ Zweck: Anzahl von Zeichen ("Länge") von 'text' einschließlich Leerzeichen.
+
+line
+ PROC line
+ Zweck: Es wird zum Anfang einer neuen Zeile positioniert.
+
+ PROC line (INT CONST number)
+ Zweck: Es werden 'number' Zeilenwechsel vorgenommen.
+
+ln
+ REAL PROC ln (REAL CONST x)
+ Zweck: Natürlicher Logarithmus.
+ Fehlerfall:
+ * ln mit nicht positiver Zahl
+ Nur echt positive Argumente sind zulässig.
+
+log2
+ REAL PROC log2 (REAL CONST z)
+ Zweck: Logarithmus zur Basis 2.
+ Fehlerfall:
+ * log2 mit negativer zahl
+ Nur echt positive Argumente sind zulässig.
+
+log10
+ REAL PROC log10 (REAL CONST x)
+ Zweck: Logarithmus zur Basis 10.
+ Fehlerfall:
+ * log10 mit negativer zahl
+ Nur echt positive Argumente sind zulässig.
+
+max
+ INT PROC max (INT CONST first, second)
+ Zweck: Liefert den Größten der beiden INT-Werte.
+
+ REAL PROC max (REAL CONST first, second)
+ Zweck: Liefert den Größten der beiden REAL-Werte.
+
+maxint
+ INT CONST maxint
+ Zweck: Größter INT-Wert im EUMEL-System (32 767).
+
+maxreal
+ REAL CONST maxreal
+ Zweck: Größter REAL-Wert im EUMEL-System (9.999999999999e126).
+
+max text length
+ INT CONST max text length
+ Zweck: Maximale Anzahl von Zeichen in einem TEXT (32 000).
+
+min
+ INT PROC min (INT CONST first, second)
+ Zweck: Liefert den Kleinsten der beiden INT-Werte. Beispiele:
+
+ min (3.0, 2.0) ==> 2.0
+ min (-2.0, 3.0) ==> -2.0
+
+ REAL PROC min (REAL CONST first, second)
+ Zweck: Liefert den Kleinsten der beiden REAL-Werte.
+
+MOD
+ INT OP MOD (INT CONST left, right)
+ Zweck: Liefert den Rest einer INT-Division. Beispiele:
+
+ 3 MOD 2 ==> 1
+ -3 MOD 2 ==> 1
+
+ Fehlerfall:
+ * DIV by 0
+ Division durch 0 ist verboten.
+
+ REAL OP MOD (REAL CONST left, right)
+ Zweck: Modulo-Funktion für REALs (liefert den Rest). Beispiele:
+
+ 5.0 MOD 2.0 ==> 1.0
+ 4.5 MOD 4.0 ==> 0.5
+
+no
+ BOOL PROC no (TEXT CONST question)
+ Zweck: Wirkt wie
+
+ NOT yes
+
+NOT
+ BOOL OP NOT (BOOL CONST a)
+ Zweck: Logische Negation.
+
+online
+ BOOL PROC online
+ Zweck: Liefert TRUE, wenn die Task mit einem Terminal gekoppelt ist.
+
+OR
+ BOOL OP OR (BOOL CONST a, b)
+ Zweck: Logisches oder.
+
+out
+ PROC out (TEXT CONST text)
+ Zweck: Ausgabe eines Textes auf dem Bildschirm. Im Unterschied zu 'put'
+ wird kein Blank an den ausgegebenen Text angefügt. 'out' kann
+ nicht umgeleitet werden (vergl. 'sysout').
+
+out subtext
+ PROC out subtext (TEXT CONST source, INT CONST from)
+ Zweck: Ausgabe eines Teiltextes von 'source' von der Position 'from' bis
+ Textende. Es wird keine Aktion vorgenommen für
+
+ from > LENGTH source
+
+ PROC out subtext (TEXT CONST source, INT CONST from, to)
+ Zweck: Ausgabe eines Teiltextes von 'source' von der Position 'from' bis
+ zur Position 'to'. Für
+
+ to > LENGTH source
+
+ wird für die fehlenden Zeichen Leerzeichen (blanks) ausgegeben.
+
+page
+ PROC page
+ Zweck: Es wird zum Anfang einer neuen Seite positioniert (hier: linke
+ obere Ecke des Bildschirms, wobei der Bildschirm gelöscht wird).
+
+pause
+ PROC pause (INT CONST time limit)
+ Zweck: Wartet 'time limit' in Zehntel-Sekunden. Bei negativen Werten ist
+ die Wirkung nicht definiert. Die Wartezeit wird nicht nur durch
+ das Erreichen der Grenze abgebrochen, sondern auch durch die
+ Eingabe eines beliebigen Zeichens.
+
+pi
+ REAL CONST pi
+ Zweck: Die Zahl pi (3.141593).
+
+pos
+ INT PROC pos (TEXT CONST source, pattern)
+ Zweck: Liefert die erste Position des ersten Zeichens von 'pattern' in
+ 'source', falls 'pattern' gefunden wird. Wird 'pattern' nicht
+ gefunden oder ist 'pattern' niltext, so wird der Wert '0' ge-
+ liefert. Beispiel:
+
+ TEXT VAR t1 :: "abcdefghijk...xyz",
+ t2 :: "cd";
+ ... pos (t1, t2) ... (* liefert 3 *)
+ ... pos (t2, t1) ... (* liefert 0 *)
+
+ INT PROC pos (TEXT CONST source, pattern, INT CONST from)
+ Zweck: Wie obige Prozedur, jedoch wird erst ab der Position 'from' ab
+ gesucht. Dabei gilt folgende Einschränkung:
+
+ length (pattern) < 255
+
+INT PROC pos (TEXT CONST source, low char, high char, INT CONST from)
+ Zweck: Liefert die Position des ersten Zeichens 'x' in 'source' ab der
+ Position 'from', so daß
+
+ low char <= x <= high char
+
+ 'low char' und 'high char' müssen TEXTe der Länge 1 sein. Wird
+ kein Zeichen in 'source' in dem Bereich zwischen 'low char' und
+ 'high char' gefunden, wird der Wert '0' geliefert. Beispiel:
+
+ (* Suche nach dem ersten Zeichen <> blank nach einer Leerspalte *)
+ TEXT VAR zeile :: "BlaBla Hier gehts weiter";
+ INT VAR pos erstes blank :: pos (zeile, " "),
+ ende leerspalte :: pos (zeile, ""33"", ""254"", pos erstes blank);
+
+put
+ PROC put (INT CONST number)
+ Zweck: Ausgabe eines INT-Wertes auf dem Bildschirm. Anschließend wird
+ ein Leerzeichen ausgegeben. Die Ausgabe kann umgeleitet werden
+ (vergl. 'sysout').
+
+ PROC put (REAL CONST real)
+ Zweck: Ausgabe eines REAL-Wertes auf dem Bildschirm. Anschließend wird
+ ein Leerzeichen ausgegeben. Die Ausgabe kann umgeleitet werden
+ (vergl. 'sysout')
+
+ PROC put (TEXT CONST text)
+ Zweck: Ausgabe eines Textes auf dem Bildschirm. Nach der Ausgabe von
+ 'text' wird ein Blank ausgegeben, um nachfolgenden Ausgaben auf
+ der gleichen Zeile voneinander zu trennen. Hardwareabhängig sind
+ die Aktionen, wenn eine Ausgabe über eine Zeilengrenze (hier:
+ Bildschirmzeile) vorgenommen wird. Meist wird die Ausgabe auf der
+ nächsten Zeile fortgesetzt. Die Ausgabe kann umgeleitet werden
+ (vergl. 'sysout').
+
+putline
+ PROC putline (TEXT CONST text)
+ Zweck: Ausgabe von 'text' auf dem Bildschirm. Nach der Ausgabe wird auf
+ den Anfang der nächsten Zeile positioniert. Gibt man TEXTe nur mit
+ 'putline' aus, so ist gesichert, daß jede Ausgabe auf einer neuen
+ Zeile beginnt. Hardwareabhängig sind die Aktionen, wenn eine Aus-
+ gabe über eine Zeilengrenze (hier: Bildschirmzeile) vorgenommen
+ wird. Meist wird die Ausgabe auf der nächsten Zeile fortgesetzt.
+ Die Ausgabe kann umgeleitet werden (vergl. 'sysout').
+
+random
+ INT PROC random (INT CONST lower bound, upper bound)
+ Zweck: Pseudo-Zufallszahlen-Generator im Intervall 'upper bound' und
+ 'lower bound' einschließlich. Es handelt sich hier um den "INT
+ Random Generator".
+
+ REAL PROC random
+ Zweck: Pseudo-Zufallszahlen-Generator im Intervall 0 und 1. Es handelt
+ sich hier um den "REAL Random Generator".
+
+real
+ REAL PROC real (INT CONST a)
+ Zweck: Konvertierungsprozedur.
+
+ REAL PROC real (TEXT CONST text)
+ Zweck: Konvertierung eines TEXTes 'text' in einen REAL-Wert. Achtung: Zur
+ Zeit werden keine Überprüfungen vorgenommen, d.h. in dem TEXT
+ muß ein REAL-Wert stehen.
+
+replace
+ PROC replace (TEXT VAR destination, INT CONST position, TEXT CONST source)
+ Zweck: Ersetzung eines Teiltextes in 'destination' durch 'source' an der
+ Position 'position' in 'destination'. Es muß gelten
+
+ 1 <= position <= LENGTH destination
+
+ d.h. 'position' muß innerhalb von 'destination' liegen und 'source'
+ muß von der Position 'position' ab in 'destination' einsetzbar
+ sein. Dabei bleibt die Länge von 'destination' unverändert.
+
+round
+ REAL PROC round (REAL CONST real, INT CONST digits)
+ Zweck: Runden eines REAL-Wertes auf 'digits' Stellen. Für positive Werte
+ wird auf Nachkommastellen gerundet. Beispiel:
+
+ round (3.14159, 3)
+
+ liefert '3.142'. Für negative 'digits'-Werte wird auf Vorkomma-
+ stellen gerundet. Beispiel:
+
+ round (123.456, -2)
+
+ liefert '100.0'. Abweichung vom Standard: Es wird mit 'digits'-
+ Ziffern gerundet.
+
+say
+ PROC say (TEXT CONST message)
+ Zweck: Sofern der Kommando-Dialog eingeschaltet ist (vergl. 'command
+ dialogue'), wird der TEXT 'message' an die augenblickliche Cursor-
+ Position geschrieben.
+
+sign
+ INT PROC sign (INT CONST argument)
+ Zweck: Feststellen des Vorzeichens eines INT-Wertes. Folgende Werte
+ werden geliefert:
+
+ argument > 0 ==> 1
+ argument = 0 ==> 0
+ argument < 0 ==> -1
+
+ INT OP SIGN (INT CONST argument)
+ Zweck: Feststellen des Vorzeichens eines INT-Wertes.
+
+ INT PROC sign (REAL CONST number)
+ Zweck: Feststellen des Vorzeichens eines REAL-Wertes.
+
+ INT OP SIGN (REAL CONST number)
+ Zweck: Feststellen des Vorzeichens eines REAL-Wertes.
+
+sin
+ REAL PROC sin (REAL CONST x)
+ Zweck: Sinus-Funktion. 'x' muß in Radiant (Bogenmaß) angegeben werden.
+
+sind
+ REAL PROC sind (REAL CONST x)
+ Zweck: Sinus-Funktion. 'x' muß im Winkelgrad angegeben werden.
+
+smallreal
+ REAL PROC smallreal
+ Zweck: Kleinster darstellbarer REAL-Wert im EUMEL-System für den
+
+ 1.0 - smallreal <> 1.0
+ 1.0 + smallreal <> 1.0
+
+ gilt (1.0E-12).
+
+sqrt
+ REAL PROC sqrt (REAL CONST z)
+ Zweck: Wurzel-Funktion.
+ Fehlerfall:
+ * sqrt von negativer Zahl
+ Das Argument muß größer gleich 0.0 sein.
+
+stop
+ PROC stop
+ Zweck: Abbruch (vergl. Fehlerbehandlung).
+
+SUB
+ TEXT OP SUB (TEXT CONST text, INT CONST pos)
+ Zweck: Liefert ein Zeichen aus 'text' an der Position 'pos'. Entspricht
+
+ subtext (text, pos, pos)
+
+ Anmerkung: Effizienter als obiger Prozedur-Aufruf. Für
+
+ pos <= 0
+ pos > LENGTH text
+
+ wird niltext geliefert.
+
+subtext
+ TEXT PROC subtext (TEXT CONST source, INT CONST from)
+ Zweck: Teiltext von 'source', der bei der Position 'from' anfängt. Die
+ Länge des Resultats ergibt sich also zu
+
+ LENGTH source - from + 1
+
+ d.h. von der Position 'from' bis zum Ende von 'source'. 'from' muß
+ innerhalb von 'source' liegen. Ist from < 1, dann wird 'source'
+ geliefert. Falls from > LENGTH source ist, wird niltext geliefert.
+
+ TEXT PROC subtext (TEXT CONST source, ITT CONST from, to)
+ Zweck: Teiltext von 'source' von der Position 'from' bis einschließlich
+ der Position 'to'. Die Länge des Resultats ist also
+
+ from - to + 1
+
+ Dabei muß gelten
+
+ 1 <= from <= to <= LENGTH source
+
+ d.h. die Positionen 'from' und 'to' müssen in dieser Reihenfolge
+ innerhalb von 'source' liegen. Ist
+
+ to >= LENGTH source
+
+ wird 'subtext (source, from)' ausgeführt. Für die Bedingungen für
+ 'from' siehe vorstehende Beschreibung von 'subtext'.
+
+sysin
+ PROC sysin (TEXT CONST file name)
+ Zweck: Eingabe-Routinen ('get', 'getline' und 'line') lesen nicht mehr
+ vom Benutzer-Terminal, sondern aus der Datei 'file name'.
+
+ TEXT PROC sysin
+ Zweck: Liefert den Namen der eingestellten 'sysin'-Datei. "" bezeichnet
+ das Benutzer-Terminal.
+
+sysout
+ PROC sysout (TEXT CONST file name)
+ Zweck: Ausgabe-Routinen ('put', 'putline', 'write', 'line') gehen nicht
+ mehr zum Benutzer-Terminal, sondern in die Datei 'file name'.
+
+ TEXT PROC sysout
+ Zweck: Liefert den Namen der eingestellten 'sysout'-Datei. "" bezeichnet
+ das Benutzer-Terminal.
+
+tan
+ REAL PROC tan (REAL CONST x)
+ Zweck: Tangens-Funktion. 'x' muß in Radiant angegeben werden.
+
+tand
+ REAL PROC tand (REAL CONST x)
+ Zweck: Tangens-Funktion. 'x' muß in Winkelgrad angegeben werden.
+
+text
+ TEXT PROC text (INT CONST number)
+ Zweck: Umwandlung eines INT-Wertes in einen Text. Negative Werte werden
+ mit einem "-"-Zeichen geliefert.
+
+ TEXT PROC text (INT CONST number, laenge)
+ Zweck: Umwandlung eines INT-Wertes 'number' in einen Text mit der Länge
+ 'laenge'. Für
+
+ LENGTH (text (number)) < laenge
+
+ werden die Ziffern rechtsbündig in einen Text mit der Länge
+ 'laenge' eingetragen. Fehlende Ziffern der gewünschten 'laenge'
+ werden im TEXT vorne mit Leerzeichen aufgefüllt. Für
+
+ LENGTH (text (number)) > laenge
+
+ wird ein Text mit der Länge 'laenge' geliefert, der mit
+ "*"-Zeichen gefüllt ist.
+
+ TEXT PROC text (REAL CONST real)
+ Zweck: Konvertierung eines REAL-Wertes in einen TEXT. Ggf. wird der TEXT
+ in Exponenten-Darstellung geliefert.
+
+ TEXT PROC text (REAL CONST real, laenge)
+ Zweck: Siehe oben. 'laenge' gibt die Anzahl von Zeichen an.
+
+ TEXT PROC text (REAL CONST real, INT CONST laenge, fracs)
+ Zweck: Konvertierung eines REAL-Wertes in einen TEXT. Dabei gibt 'laenge'
+ die Länge des Resultats einschließlich des Dezimalpunktes und
+ 'fracs' die Anzahl der Dezimalstellen an. Kann der REAL-Wert nicht
+ wie gewünscht dargestellt werden, wird
+
+ laenge * "*"
+
+ geliefert.
+
+ TEXT PROC text (TEXT CONST source, INT CONST laenge)
+ Zweck: Teiltext aus 'source' mit der Länge 'laenge', beginnend bei der
+ Position 1 von 'source'. Es muß gelten
+
+ 1 <= laenge <= LENGTH source
+
+ d.h. der gewünschte Teiltext muß aus 'source' ausblendbar sein.
+ Wenn
+
+ laenge > LENGTH source
+
+ die Länge des gewünschten Resultats ist größer als die Länge von
+ 'source' ist, wird der zu liefernde TEXT mit der an 'laenge'
+ fehlenden Zeichen mit Leerzeichen aufgefüllt.
+
+ TEXT PROC text (TEXT CONST source, INT CONST laenge, from)
+ Zweck: Teiltext aus 'source' mit der Länge 'laenge', beginnend an der
+ Position 'from' in dem TEXT 'source'. Entspricht
+
+ text (subtext (source, from, LENGTH source), laenge)
+
+ Es muß
+
+ laenge >= 0
+ 1 <= from <= LENGTH source
+
+ gelten, d.h. 'from' muß eine Position angeben, die innerhalb von
+ 'source' liegt. Für
+
+ laenge > LENGTH source - from + 1
+
+ also wenn die angegebene Länge 'laenge' größer ist als der auszu-
+ blendende Text, wird das Resultat rechts mit Leerzeichen aufge-
+ füllt. Wenn
+
+ laenge < LENGTH source - from + 1
+
+ d.h. wenn die angegebene Länge kleiner ist als der Teiltext von
+ 'from' bis zum letzten Zeichen von 'source', wird das Resultat mit
+ der Länge
+
+ LENGTH source - from + 1
+
+ geliefert.
+
+time
+ TEXT PROC time (REAL CONST time)
+ Zweck: Konvertierungsprozedur für die Zeiten der CPU-Zeituhr. Liefert die
+ Zeiten in der Form 'hh:mm:ss.s'. Vergl. dazu 'clock'.
+
+ TEXT PROC time (REAL CONST value, INT CONST laenge)
+ Zweck: Konvertiert die Zeit in externe Darstellung. Für die 'laenge'-
+ Werte ergibt sich:
+
+ laenge = 10 (* hh:mm:ss.s *)
+ laenge = 12 (* hhh:mm:ss.s *)
+
+REAL PROC time (TEXT CONST time)
+ Zweck: Konvertierungsprozedur für Texte der CPU-Zeituhr in REAL-Werte.
+
+time of day
+ TEXT PROC time of day (REAL CONST time)
+ Zweck: Konvertierungsprozedur für REALs, wie sie die Realzeituhr
+ liefert. Es wird die Tageszeit in der Form 'hh:mm' geliefert.
+ Beispiel:
+
+ put (time of day (clock (1))) (* z.B.: 17:25 *)
+
+
+ TEXT PROC time of day
+ Zweck: Liefert die aktuelle Tageszeit. Entspricht
+
+ time of day (clock (1))
+
+TIMESOUT
+ OP TIMESOUT (INT CONST times, TEXT CONST text)
+ Zweck: Ausgabe eines TEXTes 'text' 'times'mal. An die Ausgabe wird im
+ Gegensatz zu 'put' kein Leerzeichen angefügt. Es wird kein Text
+ ausgegeben für
+
+ times < 1
+
+write
+ PROC write (TEXT CONST text)
+ Zweck: Gibt 'text' ohne Trennblank aus ('put' mit Trennblank). Läßt sich
+ im Gegensatz zu 'out' in eine Datei umleiten (vergl. 'sysout').
+
+XOR
+ BOOL OP XOR (BOOL CONST a, b)
+ Zweck: Exklusives oder.
+
+yes
+ BOOL PROC yes (TEXT CONST question)
+ Zweck: Sofern der Kommando-Dialog (vergl. 'command dialogue') einge-
+ schaltet ist, wird der TEXT 'question' auf dem Bildschirm des
+ Benutzers geschrieben. Der TEXT 'question' wird dabei mit einem
+ Fragezeichen ergänzt. Der Benutzer kann nun am Terminal mit den
+ Zeichen 'j' oder 'n' antworten (oder: 'J', 'N', 'y', 'n', 'Y',
+ 'N'). Nach Eingabe eines dieser Zeichen wird von der Prozedur
+ 'yes' auf eine neue Zeile positioniert. Die Prozedur 'yes' liefert
+ den Wert TRUE bei der Eingabe von 'j' und den Wert FALSE bei der
+ Eingabe von 'n'. Ist der Kommando-Dialog nicht eingeschaltet,
+ liefert die Prozedur 'yes' den Wert TRUE.
+
diff --git a/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil9 b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil9
new file mode 100644
index 0000000..318dd06
--- /dev/null
+++ b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil9
@@ -0,0 +1,936 @@
+ EUMEL-Benutzerhandbuch
+
+ TEIL 9: Standard-Datentypen
+
+1. VECTOR und MATRIX
+
+Vektoren und Matrizen enthalten Elemente vom Datentyp REAL. Für beide Daten-
+typen sind die üblichen Operatoren definiert. Im Unterschied zu "normalen"
+'ROW n REAL' bzw. 'ROW n ROW m REAL' brauchen die Anzahl der Elemente, die
+sich in einem Vektor bzw. in einer Matrix befinden, nicht bereits zur Über-
+setzungszeit deklariert, sondern können "dynamisch" zur Laufzeit eines ELAN-
+Programms festgelegt werden. Somit ist es möglich, eine zur Übersetzungszeit
+noch unbekannte Anzahl von REAL-Elementen zu bearbeiten und dabei nur soviel
+Speicherplatz wie notwendig zu verwenden. Bei beiden Datentypen ist die
+maximale Anzahl von Elementen jeweils 4 000.
+
+Bei VECTOR und MATRIX ist auf die üblichen Rundungsfehler bei der Verwendung
+von REALs zu achten, die bei umfangreicheren Rechnungen unvermeidlich ent-
+stehen. Rundungsfehler durch Ein- bzw. Ausgaberoutinen können z.Zt. im
+EUMEL-System jedoch nicht vorkommen, weil REAL-Werte dezimal im Rechner
+abgespeichert werden (13 Stellen, von denen jedoch nur 7 ausgegeben werden).
+
+
+
+VECTOR
+
+Folgende VECTOR-Operationen stehen zur Verfügung:
+
+vector Erzeugung eines VECTOR-Objekts
+get Eingabe der Elemente vom Terminal
+put Ausgabe der Elemente auf das Terminal
+replace Ersetzung eines Elementes eines VECTORs
+SUB Zugriff auf ein REAL-Element eines VECTORs
+LENGTH Anzahl der Elemente eines VECTORs
+length dito
+NORM Euklidische Norm
+ +
+ -
+ *
+ /
+ :=
+ =
+ <>
+
+
+
+Beschreibung der VECTOR-Operationen
+
+Aus Optimierungsgründen (Heapbelastung) wurde der Datentyp INITVECTOR ge-
+schaffen. Dieser wird im VECTOR-Paket intern gehalten (wird nicht über das
+Interface herausgereicht) und kann somit nicht in einer Deklaration benutzt
+werden. INITVECTOR wird nur für die Operationen
+
+ :=
+ vector
+
+verwendet. Bei Verwendung eines Datenobjekts vom Datentyp INITVECTOR wird
+nicht soviel Speicherplatz wie bei einem Objekt vom Datentyp VECTOR benötigt.
+
+=
+ BOOL OP = (VECTOR CONST a, b)
+ Zweck: Vergleich zweier Vektoren. Der Operator liefert FALSE, wenn die
+ Anzahl der Elemente von 'a' und 'b' ungleich ist oder wenn zwei
+ Elemente mit gleichem Index ungleich sind. Beispiel:
+
+ VECTOR VAR x :: vector (10, 1.0),
+ y :: vector (15, 2.0),
+ z :: vector (10, 1.0);
+ ... x = y ... (* FALSE *)
+ ... x = z ... (* TRUE *)
+
+<>
+ BOOL OP <> (VECTOR CONST a, b)
+ Zweck: Vergleich zweier Vektoren auf Ungleichheit (NOT (a = b)).
+
+:=
+ OP := (VECTOR VAR ziel, VECTOR CONST quelle)
+ Zweck: Zuweisung. Nach der Zuweisung gilt auch
+
+ length (quelle) = length (ziel)
+
+ d.h. der linke Operand besitzt nach der Zuweisung genauso viele
+ Elemente wie 'quelle', unabhängig davon, ob 'ziel' vor der Zu-
+ weisung mehr oder weniger Elemente als 'quelle' besaß. Beispiel:
+
+ VECTOR VAR y :: vector (10, 1.0),
+ z :: vector (15, 2.0);
+ ...
+ y := z; (* length (y) liefert nun 15 ! *)
+
+ OP := (VECTOR VAR ziel, INITVECTOR CONST quelle)
+ Zweck: Dient zur Initialisierung eines VECTORs. Beispiel:
+
+ VECTOR VAR x :: vector (17);
+
+ 'vector' erzeugt ein Objekt vom Datentyp INITVECTOR. Dieses
+ Objekt braucht nicht soviel Speicherplatz wie ein VECTOR-Objekt.
+ Dadurch wird vermieden, daß nach erfolgter Zuweisung nicht ein
+ durch 'vector' erzeugtes Objekt auf dem Heap unnötig Speicher-
+ platz verbraucht.
+
++
+ VECTOR OP + (VECTOR CONST a)
+ Zweck: Monadisches '+' für VECTOR. Keine Auswirkung.
+
+ VECTOR OP + (VECTOR CONST a, b)
+ Zweck: Elementweise Addition der Vektoren 'a' und 'b'. Beispiel:
+
+ VECTOR VAR x, (* 'x' hat undefinierte Laenge *)
+ a :: vector (10, 1.0),
+ b :: vector (10, 2.0);
+ ...
+ x := a + b; (* 'x' hat nun 10 Elemente mit Werten '3.0' *)
+ Fehlerfall:
+ * VECTOR OP + : LENGTH a <> LENGTH b
+ 'a' und 'b' haben nicht die gleiche Anzahl von Elementen.
+
+-
+ VECTOR OP - (VECTOR CONST a)
+ Zweck: Monadisches '-'.
+
+ VECTOR OP - (VECTOR CONST a, b)
+ Zweck: Elementweise Subtraktion der Vektoren 'a' und 'b'.
+ Fehlerfall:
+ * VECTOR OP - : LENGTH a <> LENGTH b
+ 'a' und 'b' haben nicht die gleiche Anzahl von Elementen.
+
+*
+ REAL OP * (VECTOR CONST a, b)
+ Zweck: Skalarprodukt zweier Vektoren. Liefert die Summe der element-
+ weisen Multiplikation der Vektoren 'a' und 'b'. Beachte even-
+ tuelle Rundungsfehler! Beispiel:
+
+ REAL VAR a;
+ VECTOR VAR b :: vector (10, 2.0),
+ c :: vector (10, 2.0);
+ ...
+ a := b * c; (* 40.0 *)
+ Fehlerfall:
+ * REAL OP * : LENGTH a <> LENGTH b
+ 'a' und 'b' haben nicht die gleiche Anzahl von Elementen.
+
+ VECTOR OP * (VECTOR CONST a, REAL CONST s)
+ Zweck: Multiplikation des Vektors 'a' mit dem Skalar 's'.
+
+ VECTOR OP * (REAL CONST s, VECTOR CONST a)
+ Zweck: Multiplikation des Skalars 's' mit dem Vektor 'a'.
+
+/
+ VECTOR OP / (VECTOR CONST a, REAL CONST s)
+ Zweck: Division des Vektors 'a' durch den Skalar 's'. Beispiel:
+
+ VECTOR VAR a, (* 'a' hat undefinierte Laenge *)
+ b :: vector (10, 4.0);
+ ...
+ a := b / 2.0;
+ (* 'a' hat nun 10 Elemente mit Werten '2.0' *)
+
+get
+ PROC get (VECTOR VAR a, INT CONST l)
+ Zweck: Einlesen der Elemente von 'a' vom Terminal, wobei 'l' die Anzahl
+ der Elemente angibt.
+ Fehlerfall:
+ * PROC get : size <= 0
+ Die angeforderte Elementanzahl 'l' muß > 0 sein.
+
+length
+ INT PROC length (VECTOR CONST a)
+ Zweck: Liefert die Anzahl der Elemente von 'a'. Beispiel:
+
+ VECTOR VAR a :: vector (10, 1.0),
+ b :: vector (15, 2.0);
+ ...
+ ... length (a) ... (* 10 *)
+ ... length (b) ... (* 15 *)
+
+LENGTH
+ INT OP LENGTH (VECTOR CONST a)
+ Zweck: Liefert die Anzahl der Elemente von 'a'.
+
+NORM
+ REAL OP NORM (VECTOR CONST v)
+ Zweck: Euklidische Norm (Wurzel aus der Summe der Quadrate der Elemente).
+
+put
+ PROC put (VECTOR CONST v)
+ Zweck: Ausgabe der Werte der Elemente von 'v' auf dem Terminal.
+
+replace
+ PROC replace (VECTOR VAR v, INT CONST i, REAL CONST r)
+ Zweck: Zuweisung des i-ten Elementes von 'v' mit dem Wert von 'r'.
+ Beispiel:
+
+ VECTOR VAR v :: ...;
+ ...
+ replace (v, 13, 3.14);
+ (* Das 13. Element von 'v' bekommt den Wert '3.14' *)
+ Fehlerfälle:
+ * PROC replace : subscript overflow
+ Der Index 'i' mit dem Wert 'm' liegt außerhalb des Vektors (i >
+ LENGTH v).
+ * PROC replace : subscript underflow
+ Der Index 'i' mit dem Wert 'm' liegt außerhalb des Vektors
+ (i < 1).
+
+SUB
+ REAL OP SUB (VECTOR CONST v, INT CONST i)
+ Zweck: Liefert das 'i'-te Element von 'v'.
+ Fehlerfälle:
+ * OP SUB : subscript overflow
+ Der Index 'i' mit dem Wert 'm' liegt außerhalb des Vektors (i >
+ LENGTH v).
+ * OP SUB : subscript underflow
+ Der Index 'i' mit dem Wert 'm' liegt außerhalb des Vektors
+ (i < 1).
+
+vector
+ INITVECTOR PROC vector (INT CONST l)
+ Zweck: Erzeugen eines Vektors mit 'l' Elementen. Ein INITVECTOR-Objekt
+ benötigt nicht soviel Speicherplatz wie ein VECTOR-Objekt. Die
+ Elemente werden mit dem Wert '0.0' initialisiert.
+ Fehlerfall:
+ * PROC vector : size <= 0
+ Die angeforderte Elementanzahl 'l' muß > 0 sein.
+
+ INITVECTOR PROC vector (INT CONST l, REAL CONST value):
+ Zweck: Erzeugen eines Vektors mit 'l' Elementen. Ein INITVECTOR-Objekt
+ benötigt nicht soviel Speicherplatz wie ein VECTOR-Objekt. Die
+ Elemente werden mit dem Wert 'value' initialisiert. Beispiel:
+
+ VECTOR VAR v := vector (17, 3.14159);
+ (* 'v' hat 17 Elemente mit den Wert '3.14159' *)
+ Fehlerfall:
+ * PROC vector : size <= 0
+ Die angeforderte Elementanzahl 'l' muß > 0 sein.
+
+
+
+MATRIX
+
+Folgende Operationen stehen für MATRIX zur Verfügung:
+
+matrix Erzeugung eines MATRIX-Objekts
+idn Erzeugung einer Einheitsmatrix
+put Ausgabe der MATRIX auf dem Terminal
+get Eingabe der Matrix vom Terminal
+replace row Ersetzung einer Zeile
+replace column Ersetzung einer Spalte
+replace element Ersetzung eines Elements
+row Liefert einen VECTOR (Zeile einer MATRIX)
+column Liefert einen VECTOR (Spalte einer MATRIX)
+sub Liefert ein REAL-Elemement
+COLUMNS Anzahl Spalten
+ROWS Anzahl Zeilen
+INV Inverse
+DET Determinante
+TRANSP Transponierte
+transp Transponierte (speicherfreundlich)
+ +
+ -
+ *
+ :=
+ =
+ <>
+
+
+
+Beschreibung der MATRIX-Operationen
+
+Aus Optimierungsgründen (Heapbelastung) wurde der Datentyp INITMATRIX
+geschaffen. Dieser wird im MATRIX-Paket intern gehalten (wird nicht über das
+Interface herausgereicht) und kann somit nicht in einer Deklaration benutzt
+werden. INITMATRIX wird nur für die Operationen
+
+ :=
+ idn
+ matrix
+
+verwendet. Bei Verwendung eines Objekts vom Datentyp INITMATRIX wird nicht
+der Speicherplatz für eine MATRIX benötigt.
+
++
+ MATRIX OP + (MATRIX CONST m)
+ Zweck: Monadisches '+'. Keine Auswirkungen.
+
+ MATRIX OP + (MATRIX CONST l, r)
+ Zweck: Addition zweier Matrizen. Die Anzahl der Reihen und der Spalten
+ muß gleich sein. Beispiel:
+
+ MATRIX VAR a :: matrix (3, 43, 1.0),
+ b :: matrix (3, 43, 2.0),
+ summe;
+ summe := a + b;
+ (* Alle Elemente haben den Wert '3.0' *)
+ Fehlerfälle:
+ * MATRIX OP + : COLUMNS l <> COLUMNS r
+ Die Anzahl der Spalten von 'l' und 'r' sind nicht gleich.
+ * MATRIX OP + : ROWS l <> ROWS r
+ Die Anzahl der Zeilen von 'l' und 'r' sind nicht gleich.
+
+-
+ MATRIX OP - (MATRIX CONST m)
+ Zweck: Monadisches Minus. Beispiel:
+
+ MATRIX VAR a :: matrix (3, 4, 10.0)
+ a := - a; (* Alle Elemente haben den Wert '-10.0' *)
+
+ MATRIX OP - (MATRIX CONST l, r)
+ Zweck: Subtraktion zweier Matrizen. Die Anzahl der Reihen und Spalten
+ muß gleich sein.
+ Fehlerfälle:
+ * MATRIX OP - : COLUMNS l <> COLUMNS r
+ Die Anzahl der Spalten von 'l' und 'r' sind nicht gleich.
+ * MATRIX OP - : ROWS l <> ROWS r
+ Die Anzahl der Zeilen von 'l' und 'r' sind nicht gleich.
+
+*
+ MATRIX OP * (REAL CONST r, MATRIX CONST m)
+ Zweck: Multiplikation einer Matrix 'm' mit einem Skalar 'r'. Beispiel:
+
+ MATRIX VAR a :: matrix (3, 4, 2.0);
+ ...
+ a := 3 * a; (* Alle Elemente haben den Wert '6.0' *)
+
+ MATRIX OP * (MATRIX CONST m, REAL CONST r)
+ Zweck: Multiplikation einer Matrix 'm' mit einem Skalar 'r'.
+
+ MATRIX OP * (MATRIX CONST l, r)
+ Zweck: Multiplikation zweier Matrizen. Die Anzahl der Spalten von 'l'
+ und die Anzahl der Zeilen von 'r' müssen gleich sein. Beispiel:
+
+ MATRIX VAR a :: matrix (3, 4, 2.0),
+ b :: matrix (4, 2, 3.0),
+ produkt;
+ produkt := a * b;
+ (* Alle Elemente haben den Wert '24.0' *)
+ Fehlerfall:
+ * MATRIX OP * : COLUMNS l <> ROWS r
+ Die Anzahl der Spalten von 'l' muß mit der Anzahl der Zeilen
+ von 'r' übereinstimmen.
+
+ VECTOR OP * (VECTOR CONST v, MATRIX CONST m)
+ Zweck: Multiplikation des Vektors 'v' mit der Matrix 'm'.
+ Fehlerfall:
+ * VECTOR OP * : LENGTH v <> ROWS m
+ Die Anzahl der Elemente von 'v' stimmt nicht mit den Anzahl der
+ Zeilen von 'm' überein.
+
+ VECTOR OP * (MATRIX CONST m, VECTOR CONST v)
+ Zweck: Multiplikation der Matrix 'm' mit dem Vektor 'v'.
+ Fehlerfall:
+ * VECTOR OP * : COLUMNS m <> LENGTH v
+ Die Anzahl der Spalten von 'm' stimmt nicht mit der Anzahl der
+ Elementen von 'v' überein.
+
+=
+ BOOL OP = (MATRIX CONST l, r)
+ Zweck: Vergleich zweier Matrizen. Der Operator '=' liefert FALSE, wenn
+ die Anzahl Spalten oder Reihen der Matrizen 'l' und 'r' ungleich
+ ist und wenn mindestens ein Element mit gleichen Indizes der zwei
+ Matrizen ungleiche Werte haben. Beispiel:
+
+ MATRIX VAR a :: matrix (3, 3),
+ b :: matrix (3, 3, 1.0),
+ c :: matrix (4, 4);
+ ... a = b ...
+ (* FALSE wegen ungleicher Werte *)
+ ... a = c ...
+ (* FALSE wegen ungleicher Groesse *)
+ ... b = c ...
+ (* FALSE wegen ungleicher Groesse *)
+
+<>
+ BOOL OP <> (MATRIX CONST l, r)
+ Zweck: Vergleich der Matrizen 'l' und 'r' auf Ungleichheit.
+
+:=
+ OP := (MATRIX VAR l, MATRIX CONST r)
+ Zweck: Zuweisung von 'r' auf 'l'. Die MATRIX 'l' bekommt u.U. eine neue
+ Anzahl von Elementen. Beispiel:
+
+ MATRIX VAR a :: matrix (3, 4, 0.0),
+ b :: matrix (5, 5, 3.0);
+ ...
+ a := b; (* 'a' hat jetzt 5 x 5 Elemente *)
+
+ OP := (MATRIX VAR l, INITMATRIX CONST r)
+ Zweck: Dient zur Initialisierung einer Matrix. Beispiel:
+
+ MATRIX VAR x :: matrix (17, 4);
+
+ 'matrix' erzeugt ein Objekt vom Datentyp INITMATRIX. Dieses
+ Objekt braucht nicht soviel Speicherplatz wie ein MATRIX-Objekt.
+ Dadurch wird vermieden, daß nach erfolgter Zuweisung nicht ein
+ durch 'matrix' erzeugtes Objekt auf dem Heap unnötig Speicher-
+ platz verbraucht.
+
+column
+ VECTOR PROC column (MATRIX CONST m, INT CONST i)
+ Zweck: Die 'i'-te Spalte von 'm' wird als VECTOR mit 'ROWS m' Elementen
+ geliefert. Beispiel:
+
+ MATRIX CONST a :: matrix (3, 4);
+ VECTOR VAR b :: column (a, 1);
+ (* 'b' hat drei Elemente mit den Werten '0.0' *)
+ Fehlerfälle:
+ * PROC column : subscript overflow
+ Der Index 'i' liegt außerhalb der Matrix 'm' (i > COLUMNS m).
+ * PROC column : subscript underflow
+ Der Index 'i' liegt außerhalb der Matrix 'm' (i < 1).
+
+COLUMNS
+ INT OP COLUMNS (MATRIX CONST m)
+ Zweck: Liefert die Anzahl der Spalten von 'm'. Beispiel:
+
+ MATRIX VAR a :: matrix (3, 4),
+ b :: matrix (7, 10);
+ put (COLUMNS a); (* 4 *)
+ put (COLUMNS b); (* 10 *)
+
+DET
+ REAL OP DET (MATRIX CONST m)
+ Zweck: Es wird der Wert der Determinanten von 'm' geliefert.
+ Fehlerfall:
+ * OP DET : no square matrix
+ Die Matrix ist nicht quadratisch, d.h. ROWS m <> COLUMNS m
+
+get
+ PROC get (MATRIX VAR m, INT CONST rows, columns)
+ Zweck: Einlesen von Werten für die Matrix 'm' vom Terminal mit 'rows'-
+ Zeilen und 'columns'-Spalten.
+
+idn
+ INITMATRIX PROC idn (INT CONST size)
+ Zweck: Erzeugen einer Einheitsmatrix vom Datentyp INITMATRIX. Beispiel:
+
+ MATRIX VAR a :: idn (10);
+ (* Erzeugt eine Matrix mit 10 x 10 Elementen,
+ deren Werte '0.0' sind, mit der Ausnahme der
+ Diagonalelemente, die den Wert '1.0' haben. *)
+ Fehlerfall:
+ * PROC idn : size <= 0
+ Die angeforderte 'size' Anzahl Spalten oder Zeilen muß > 0 sein.
+
+INV
+ MATRIX OP INV (MATRIX CONST m)
+ Zweck: Liefert als Ergebnis die Inverse von 'm' (Achtung: starke Run-
+ dungsfehler möglich).
+ Fehlerfälle:
+ * OP INV : no square matrix
+ Die Matrix 'm' ist nicht quadratisch, d.h. ROWS m <> COLUMNS m
+ * OP INV : singular matrix
+ Die Matrix ist singulär.
+
+matrix
+ INITMATRIX PROC matrix (INT CONST rows, columns)
+ Zweck: Erzeugen eines Datenobjekts vom Datentyp INITMATRIX mit 'rows'
+ Zeilen und 'columns' Spalten. Alle Elemente werden mit dem Wert
+ '0.0' initialisiert. Beispiel:
+
+ MATRIX CONST :: matrix (3, 3);
+ Fehlerfälle:
+ * PROC matrix : rows <= 0
+ Die angeforderte Zeilenanzahl 'rows' muß > 0 sein.
+ * PROC matrix : columns <= 0
+ Die angeforderte Spaltenanzahl 'columns' muß > 0 sein.
+
+ INITMATRIX PROC matrix (INT CONST rows, columns, REAL CONST value)
+ Zweck: Erzeugen eines Datenobjekts vom Datentyp MATRIX mit 'rows'
+ Zeilen und 'columns' Spalten. Alle Elemente der erzeugten MATRIX
+ werden mit dem Wert 'value' initialisiert. Beispiel:
+
+ MATRIX CONST :: matrix (3, 3, 3.14);
+ Fehlerfälle:
+ * PROC matrix : rows <= 0
+ Die angeforderte Zeilenanzahl 'rows' muß > 0 sein.
+ * PROC matrix : columns <= 0
+ Die angeforderte Spaltenanzahl 'columns' muß > 0 sein.
+
+put
+ PROC put (MATRIX CONST m)
+ Zweck: Ausgabe der Werte einer Matrix auf dem Terminal.
+
+replace column
+ PROC replace column (MATRIX VAR m, INT CONST column index,
+ VECTOR CONST column value)
+ Zweck: Ersetzung der durch 'column index' definierten Spalte in der
+ MATRIX 'm' durch den VECTOR 'column value'. Beispiel:
+
+ MATRIX VAR a :: matrix (3, 5, 1.0);
+ VECTOR VAR b :: vector (3, 2.0);
+ ...
+ replace column (a, 2, b);
+ (* Die zweite Spalte von 'a' wird durch die Werte von 'b'
+ ersetzt *)
+ Fehlerfälle:
+ * PROC replace column : LENGTH columnvalue <> ROWS m
+ Die Anzahl der Zeilen der MATRIX 'm' stimmt nicht mit der Anzahl
+ der Elemente von 'columnvalue' überein.
+ * PROC replace column : column subscript overflow
+ Der Index 'columnindex' liegt außerhalb von 'm'
+ (columnindex > COLUMNS m).
+ * PROC sub : column subscript underflow
+ Der Index 'columnindex' liegt außerhalb von 'm'
+ (columnindex < 1).
+
+replace element
+ PROC replace element (MATRIX VAR m , INT CONST row, column,
+ REAL CONST value)
+ Zweck: Ersetzung eines Elementes von 'm' in der 'row'-ten Zeile und
+ 'column'-ten Spalte durch den Wert 'value'. Beispiel:
+
+ MATRIX VAR a :: matrix (5, 5);
+ ...
+ replace element (1, 1, 3.14159);
+ Fehlerfälle:
+ * PROC replace element : row subscript overflow
+ Der Index 'row' liegt außerhalb von 'm' (row > ROWS m).
+ * PROC replace element : row subscript underflow
+ Der Index 'row' liegt außerhalb von 'm' (row < 1).
+ * PROC replace element : column subscript overflow
+ Der Index 'column' liegt außerhalb von 'm' (column > COLUMNS m).
+ * PROC replace element : row subscript underflow
+ Der Index 'column' liegt außerhalb von 'm' (column < 1).
+
+replace row
+ PROC replace row (MATRIX VAR m, INT CONST rowindex,
+ VECTOR CONST rowvalue)
+ Zweck: Ersetzung der Reihe 'rowindex' in der MATRIX 'm' durch den
+ VECTOR 'rowvalue'. Beispiel:
+
+ MATRIX VAR a :: matrix (3, 5, 1.0);
+ VECTOR VAR b :: vector (5, 2.0);
+ ...
+ replace row (a, 2, b);
+ (* Die 2. Reihe von 'a' wird durch Werte von 'b' ersetzt *)
+ Fehlerfälle:
+ * PROC replace row : LENGTH rowvalue <> COLUMNS m
+ Die Anzahl der Spalten der MATRIX 'm' stimmt nicht mit der Anzahl
+ der Elemente von 'rowvalue' überein.
+ * PROC replace row : row subscript overflow
+ Der Index 'rowindex' liegt außerhalb von 'm' (rowindex > ROWS m).
+ * PROC sub : row subscript underflow
+ Der Index 'rowindex' liegt außerhalb von 'm' (rowindex < 1).
+
+row
+ VECTOR PROC row (MATRIX CONST m, INT CONST i)
+ Zweck: Die 'i'-te Reihe von 'm' wird als VECTOR mit 'COLUMNS m'
+ Elementen geliefert. Beispiel:
+
+ MATRIX CONST a :: matrix (3, 4);
+ VECTOR VAR b :: row (a, 1);
+ (* 'b' hat vier Elemente mit den Werten '0.0'*)
+ Fehlerfälle:
+ * PROC row : subscript overflow
+ Der Index 'i' liegt außerhalb der Matrix 'm' (i > ROWS m).
+ * PROC row : subscript underflow
+ Der Index 'i' liegt außerhalb der Matrix 'm' (i < 1).
+
+ROWS
+ INT OP ROWS (MATRIX CONST m)
+ Zweck: Liefert die Anzahl der Zeilen von 'm'. Beispiel:
+
+ MATRIX VAR a :: matrix (3, 4),
+ b :: matrix (7, 10);
+ ...
+ put (ROWS a); (* 3 *)
+ put (ROWS b); (* 7 *)
+
+sub
+ REAL PROC sub (MATRIX CONST m, INT CONST row, column)
+ Zweck: Liefert den Wert eines Elementes von 'm', welches durch die
+ Indizes 'row' und 'column' bestimmt wird. Beispiel:
+
+ MATRIX VAR m :: matrix (5, 10, 1.0);
+ put (sub (m, 3, 7));
+ Fehlerfälle:
+ * PROC sub : row subscript overflow
+ Der Index 'row' liegt außerhalb von 'm' (row > ROWS m).
+ * PROC sub : row subscript underflow
+ Der Index 'row' liegt außerhalb von 'm' (row < 1).
+ * PROC sub : column subscript overflow
+ Der Index 'column' liegt außerhalb von 'm' (column > ROWS m).
+ * PROC sub : row subscript underflow
+ Der Index 'column' liegt außerhalb von 'm' (column < 1).
+
+TRANSP
+ MATRIX OP TRANSP (MATRIX CONST m)
+ Zweck: Liefert als Ergebnis die transponierte Matrix 'm'.
+
+transp
+ PROC transp (MATRIX VAR m)
+ Zweck: Transponieren der Matrix 'm', wobei kaum zusätzlicher Speicher-
+ platz benötigt wird.
+
+
+
+2. COMPLEX
+
+Das COMPLEX-Paket ist im ausgelieferten Standard-System noch nicht vorüber-
+setzt, sondern wird im Quellcode ausgeliefert und kann so bei Bedarf von
+jeder EUMEL-Installation in die implementationsabhängigen Standard-Pakete
+aufgenommen werden.
+
+Folgende Operationen stehen für COMPLEX zur Verfügung:
+
+put Ausgabe auf dem Terminal
+get Eingabe auf dem Terminal
+complex zero Denotierungsprozedur
+complex one dito
+complex i dito
+complex dito
+real part Realteil eines komplexen Werts
+imag part Imaginärteil eines komplexen Werts
+phi Winkel in der Polardarstellung (Radiant)
+dphi dito, in Winkelgrad
+CONJ Konjugiert komplexer Wert
+sqrt Wurzelfunktion
+ +
+ -
+ *
+ /
+ :=
+ =
+ <>
+
+
+
+Beschreibung der COMPLEX-Operationen
+
+=
+ BOOL OP = (COMPLEX CONST a, b)
+ Zweck: Vergleich von 'a' und 'b' auf Gleichheit.
+
+:=
+ OP := (COMPLEX VAR a, COMPLEX CONST b)
+ Zweck: Zuweisung.
+
+<>
+ BOOL OP <> (COMPLEX CONST a, b)
+ Zweck: Vergleich von 'a' und 'b' auf Ungleichheit.
+
++
+ COMPLEX OP + (COMPLEX CONST a, b)
+ Zweck: Summe von 'a' und 'b'.
+
+-
+ COMPLEX OP - (COMPLEX CONST a, b)
+ Zweck: Differenz von 'a' und 'b'.
+
+*
+ COMPLEX OP * (COMPLEX CONST a, b)
+ Zweck: Multiplikation von 'a' mit 'b'.
+
+/
+ COMPLEX OP / (COMPLEX CONST a, b)
+ Zweck: Division von 'a' mit 'b'.
+
+ABS
+ REAL OP ABS (COMPLEX CONST x)
+ Zweck: REAL-Betrag von 'x'.
+
+complex
+ COMPLEX PROC complex (REAL CONST re, im)
+ Zweck: Denotierungsprozedur. Angabe in kartesischen Koordinaten.
+
+complex i
+ COMPLEX PROC complex i
+ Zweck: Denotierungsprozedur für den komplexen Wert '0.0 + i 1.0'.
+
+complex one
+ COMPLEX PROC complex one
+ Zweck: Denotierungsprozedur für den komplexen Wert '1.0 + i 0.0'.
+
+complex zero
+ COMPLEX PROC complex zero
+ Zweck: Denotierungsprozedur für den komplexen Wert '0.0 + i 0.0'.
+
+CONJ
+ COMPLEX OP CONJ (COMPLEX CONST number)
+ Zweck: Liefert den konjugiert komplexen Wert von 'number'.
+
+dphi
+ REAL PROC dphi (COMPLEX CONST x)
+ Zweck: Winkel von 'x' (Polardarstellung).
+
+get
+ PROC get (COMPLEX VAR a)
+ Zweck: Einlesen eines komplexen Wertes vom Bildschirm in der Form
+ zweier REAL-Denoter. Die Eingabe kann editiert werden.
+
+imag part
+ REAL PROC imag part (COMPLEX CONST number)
+ Zweck: Liefert den Imaginärteil des komplexen Wertes 'number'.
+
+phi
+ REAL PROC phi (COMPLEX CONST x)
+ Zweck: Winkel von 'x' (Polardarstellung) in Radiant.
+
+put
+ PROC put (COMPLEX CONST a)
+ Zweck: Ausgabe eines komplexen Wertes auf dem Bildschirm in Form zweier
+ REAL-Werte. Hinter jedem REAL-Wert wird ein Leerzeichen angefügt.
+
+real part
+ REAL PROC real part (COMPLEX CONST number)
+ Zweck: Liefert den Real-Teil des komplexen Wertes 'number'.
+
+sqrt
+ COMPLEX PROC sqrt (COMPLEX CONST x)
+ Zweck: Wurzelfunktion für komplexe Werte.
+
+
+
+3. LONGINT
+
+LONGINT ist ein Datentyp, für den (fast) alle Prozeduren und Operatoren des
+Datentyps INT implementiert wurden. LONGINT unterscheidet sich von INT
+dadurch, daß erheblich größere Werte darstellbar sind.
+
+Für den Datentyp LONGINT stehen folgende Operationen zur Verfügung:
+
+get Eingabe vom Terminal
+put Ausgabe vom Terminal
+ABS, abs Absolutbetrag
+INCR, DECR Addition und Zuweisung bzw. Subtraktion und Zuweisung
+DIV Division ohne Rest
+int, text Konvertierungen
+longint dito
+max, min Maximum bzw. Minimum zweier LONGINTs
+MOD Modulo-Funktion
+random Zufallszahlen
+sign Vorzeichen
+ <
+ >
+ <=
+ <>
+ =
+ -
+ +
+ *
+ **
+
+
+
+Beschreibung der LONGINT-Operationen
+
+<
+ BOOL OP < (LONGINT CONST left, right)
+ Zweck: Vergleichen zweier LONGINTs auf kleiner.
+
+>
+ BOOL OP > (LONGINT CONST left, right)
+ Zweck: Vergleichen zweier LONGINTs auf größer.
+
+<=
+ BOOL OP <= (LONGINT CONST left, right)
+ Zweck: Vergleichen zweier LONGINTs auf kleiner gleich.
+
+>=
+ BOOL OP >= (LONGINT CONST left, right)
+ Zweck: Vergleichen zweier LONGINTs auf größer gleich.
+
+<>
+ BOOL OP <> (LONGINT CONST left, right)
+ Zweck: Vergleichen zweier LONGINTs auf Ungleichheit.
+
+=
+ BOOL OP = (LONGINT CONST left, right)
+ Zweck: Vergleichen zweier LONGINTs auf Gleichheit.
+
+-
+ LONGINT OP - (LONGINT CONST argument)
+ Zweck: Vorzeichenumkehrung.
+
+ LONGINT OP - (LONGINT CONST left, right)
+ Zweck: Subtraktion zweier LONGINTs.
+
++
+ LONGINT OP + (LONGINT CONST argument)
+ Zweck: Monadischer Operator. Ohne Wirkung.
+
+ LONGINT OP + (LONGINT CONST left, right)
+ Zweck: Addition zweier LONGINTs.
+
+*
+ LONGINT OP * (LONGINT CONST left, right)
+ Zweck: Multiplikation von zwei LONGINTs.
+
+**
+ LONGINT OP ** (LONGINT CONST argument, exponent)
+ Zweck: Exponentiation zweier LONGINTs mit positivem Exponenten.
+ Fehlerfälle :
+ * LONGINT OP ** : negative exponent
+ Der 'exponent' muß >= 0 sein.
+ * 0 ** 0 is not defined
+ 'argument' und 'exponent' dürfen nicht gleich 0 sein.
+
+
+ LONGINT OP ** (LONGINT CONST argument, INT CONST exponent)
+ Zweck: Exponentiation eines LONGINT mit positiven INT Exponenten.
+ Fehlerfälle :
+ * LONGINT OP ** : negative exponent
+ Der 'exponent' muß >= 0 sein.
+ * 0 ** 0 is not defined
+ 'argument' und 'exponent' dürfen nicht gleich 0 sein.
+
+ABS
+ LONGINT OP ABS (LONGINT CONST argument)
+ Zweck: Absolutbetrag eines LONGINT.
+
+abs
+ LONGINT PROC abs (LONGINT CONST argument)
+ Zweck: Absolutbetrag eines LONGINT.
+
+DECR
+ OP DECR (LONGINT VAR resultat, LONGINT CONST ab)
+ Zweck: resultat := resultat - ab
+
+DIV
+ LONGINT OP DIV (LONGINT CONST left, right)
+ Zweck: Division zweier LONGINTs.
+ Fehlerfall :
+ * divide by zero
+ 'right' muß <> 0 sein.
+
+get
+ PROC get (LONGINT VAR zahl)
+ Zweck: Eingabe eines LONGINTs vom Terminal.
+
+ PROC get (FILE VAR file, LONGINT VAR zahl)
+ Zweck: Einlesen von 'zahl' aus der sequentiellen Datei 'file'. Die
+ Datei muß mit 'input' assoziiert sein (vergl. 'sequential file').
+ Fehlerfälle :
+ * file not open
+ Die Datei 'file' ist gegenwärtig nicht assoziiert.
+ * input after end of file
+ Es wurde versucht, über die letzte Zeile einer Datei zu lesen.
+ * input access to output file
+ Es wurde versucht, von einem mit 'output' assoziierten FILE zu
+ lesen.
+
+INCR
+ LONGINT OP INCR (LONGINT VAR resultat, LONGINT CONST dazu)
+ Zweck: resultat := resultat + dazu
+
+int
+ INT PROC int (LONGINT CONST longint)
+ Zweck: Konvertierung von LONGINT nach INT.
+ Fehlerfall :
+ * integer overflow
+ 'longint' ist größer als 'maxint'.
+
+longint
+ LONGINT PROC longint (INT CONST int)
+ Zweck: Konvertierung von 'int' nach LONGINT.
+
+ LONGINT PROC longint (TEXT CONST text)
+ Zweck: Konvertierung von 'text' nach LONGINT.
+
+max
+ LONGINT PROC max (LONGINT CONST left, right)
+ Zweck: Liefert das Maximum zweier LONGINTs.
+
+min
+ LONGINT PROC min (LONGINT CONST left, right)
+ Zweck: Liefert das Minimum zweier LONGINTs.
+
+MOD
+ LONGINT OP MOD (LONGINT CONST left, right)
+ Zweck: Modulo-Funktion für LONGINTs. Der Rest einer LONGINT-Division
+ wird ermittelt.
+ Fehlerfall :
+ * text (left) + 'MOD 0'
+ 'right' muß ungleich null sein.
+
+put
+ PROC put (LONGINT CONST longint)
+ Zweck: Ausgabe eines LONGINTs auf dem Bildschirm. Anschließend wird
+ ein Leerzeichen ausgegeben. Hardwareabhängig sind die Aktionen,
+ wenn eine Ausgabe über die Bildschirmzeilengrenze vorgenommen
+ wird. Meist wird jedoch die Ausgabe auf der nächsten Zeile fort-
+ gesetzt.
+
+ PROC put (FILE VAR file, LONGINT CONST zahl)
+ Zweck: Ausgabe von 'zahl' in die sequentielle Datei 'file'. 'file' muß
+ mit 'output' assoziiert sein.
+ Fehlerfälle :
+ * file not open
+ Die Datei 'file' ist gegenwärtig nicht assoziiert.
+ * output access to input file
+ Es wurde versucht, auf einem mit 'input' assoziierten FILE zu
+ schreiben.
+
+random
+ LONGINT PROC random (LONGINT CONST lower bound, upper bound)
+ Zweck: Pseudo-Zufallszahlen-Generator im Intervall 'lower bound' und
+ 'upper bound' einschließlich. Es handelt sich hier um den
+ 'LONGINT Random Generator'.
+
+SIGN
+ INT OP SIGN (LONGINT CONST longint)
+ Zweck: Feststellen des Vorzeichens von 'longint'. Liefert:
+
+ 0 wenn 'longint' = 0,
+ 1 wenn 'longint' > 0,
+ -1 wenn 'longint' < 0.
+
+sign
+ INT PROC sign (LONGINT CONST longint)
+ Zweck: Feststellen des Vorzeichens von 'longint'. Liefert:
+
+ 0 wenn 'longitt' = 0,
+ 1 wenn 'longint' > 0,
+ -1 wenn 'longint' < 0.
+
+text
+ TEXT PROC text (LONGINT CONST longint)
+ Zweck: Konvertierung von 'longint' nach TEXT.
+
+ TEXT PROC text (LONGINT CONST longint, INT CONST laenge)
+ Zweck: Konvertierung von 'longint' nach TEXT. Die Anzahl der Zeichen
+ soll 'laenge' betragen. Für
+
+ LENGTH (text (longint)) < laenge
+
+ werden die Zeichen rechtsbündig in einen Text mit der Länge
+ 'laenge' eingetragen. Ist der daraus entstehende TEXT kleiner
+ als 'laenge', werden die an 'laenge' fehlenden Zeichen im TEXT
+ mit Leerzeichen aufgefüllt. Für
+
+ LENGTH (text (longint)) > length
+
+ wird ein Text mit der Länge 'length' geliefert, der mit
+ '*'-Zeichen gefüllt ist.
+
diff --git a/doc/user-manual/1.7.3-pd/doc/source-disk b/doc/user-manual/1.7.3-pd/doc/source-disk
new file mode 100644
index 0000000..f769920
--- /dev/null
+++ b/doc/user-manual/1.7.3-pd/doc/source-disk
@@ -0,0 +1 @@
+173_publicdomain/03_benutzerhandbuch.img