summaryrefslogtreecommitdiff
path: root/doc/programmer-manual
diff options
context:
space:
mode:
authorLars-Dominik Braun <lars@6xq.net>2019-02-04 13:09:03 +0100
committerLars-Dominik Braun <lars@6xq.net>2019-02-04 13:09:03 +0100
commit04e68443040c7abad84d66477e98f93bed701760 (patch)
tree2b6202afae659e773bf6916157d23e83edfa44e3 /doc/programmer-manual
downloadeumel-src-04e68443040c7abad84d66477e98f93bed701760.tar.gz
eumel-src-04e68443040c7abad84d66477e98f93bed701760.tar.bz2
eumel-src-04e68443040c7abad84d66477e98f93bed701760.zip
Initial import
Diffstat (limited to 'doc/programmer-manual')
-rw-r--r--doc/programmer-manual/1.8.7/doc/programmierhandbuch.1650
-rw-r--r--doc/programmer-manual/1.8.7/doc/programmierhandbuch.2a1845
-rw-r--r--doc/programmer-manual/1.8.7/doc/programmierhandbuch.2b1395
-rw-r--r--doc/programmer-manual/1.8.7/doc/programmierhandbuch.3728
-rw-r--r--doc/programmer-manual/1.8.7/doc/programmierhandbuch.41692
-rw-r--r--doc/programmer-manual/1.8.7/doc/programmierhandbuch.51329
-rw-r--r--doc/programmer-manual/1.8.7/doc/programmierhandbuch.5b1481
-rw-r--r--doc/programmer-manual/1.8.7/doc/programmierhandbuch.61441
-rw-r--r--doc/programmer-manual/1.8.7/doc/programmierhandbuch.index449
-rw-r--r--doc/programmer-manual/1.8.7/doc/programmierhandbuch.inhalt249
-rw-r--r--doc/programmer-manual/1.8.7/doc/programmierhandbuch.titel52
-rw-r--r--doc/programmer-manual/1.8.7/source-disk1
12 files changed, 11312 insertions, 0 deletions
diff --git a/doc/programmer-manual/1.8.7/doc/programmierhandbuch.1 b/doc/programmer-manual/1.8.7/doc/programmierhandbuch.1
new file mode 100644
index 0000000..24f2b03
--- /dev/null
+++ b/doc/programmer-manual/1.8.7/doc/programmierhandbuch.1
@@ -0,0 +1,650 @@
+#headandbottom("1","EUMEL-Benutzerhandbuch","TEIL 1 : Einleitung","1")#
+#pagenr("%",1)##setcount(1)##block##pageblock#
+#headeven#
+#center#EUMEL-Benutzerhandbuch
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#TEIL 1 : Einleitung
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+1 - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #rigth#1 - %
+#end#
+
+TEIL 1 : Einleitung
+
+
+1.1 Allgemeines über EUMEL
+
+Dieses Buch bietet eine Übersicht über die Standardprozeduren des Betriebssystem
+EUMEL. Es bietet damit sowohl Hilfestellung für die Benutzung der standardmäßig
+vorhandenen Kommandos als auch für die Programmierung, also die Erweiterung
+dieses Kommandovorrats. Es ist jedoch kein Lehrbuch der Programmierung!
+
+In den ersten drei Kapiteln dieses Programmierhandbuches werden einige Grund­
+begriffe des Systems, die grundlegende Programmiersprache (ELAN) und der
+EUMEL-Editor erläutert.
+
+Das vierte Kapitel bietet eine Übersicht über diejenigen Prozeduren und Operatoren,
+die eher der 'Job-Control-Language' zugerechnet werden können, also häufig im
+Kommandodialog benutzt werden.
+
+Im fünften Teil sind diejenigen Operationen beschrieben, die meistenteils für die
+Programmierung benutzt werden. (Compiler, Operationen auf den elementaren Daten­
+typen, Dateien, Ein- und Ausgabe usw.).
+
+Diese Trennung ist jedoch recht willkürlich, es ist ja gerade eine der wichtigen Eigen­
+schaften dieses Betriebssystems, daß es keine Trennung zwischen der Kommando­
+sprache des Betriebssystems und Programmmiersprache für das System gibt. Jedes
+Systemkommando ist Aufruf einer ELAN Prozedur, jede neue Prozedur stellt eine
+Erweiterung des Kommandovorrats des Systems dar.
+
+Aus Gründen der Übersichtlichkeit der Zusammenstellung ist dieses Buch nicht frei
+von Vorwärtsverweisen!
+
+#page#
+
+1.2 Struktur des Betriebssystems EUMEL
+
+Grundlegend für das Verständnis des Betriebssystems EUMEL ist der Begriff der
+#on("b")#Task#off("b")#. Eine Task kann als theoretisch unendliche Wiederholung eines Systempro­
+gramms der Form:
+
+ 'nimm Kommando entgegen'
+ 'verarbeite Kommando'
+
+aufgefaßt werden. Einige Tasks existieren bereits als Grundstock des Systems,
+weitere werden von Benutzern des Systems erschaffen und dienen als persönliche
+Arbeitsumgebung für den 'Eigentümer'. Eine Task kann als benutzereigener, unab­
+hängiger Computer im Computer betrachtet werden, denn sie kann Kommandos
+entgegennehmen und ausführen und Daten verwalten und aufbewahren.
+
+Eine Task kann neu erzeugt werden, an einen Bildschirm gekoppelt werden und
+beendet werden.
+
+Das Tasksystem ist in einer baumartigen Struktur angeordnet. Außer der Wurzel 'UR'
+hat jede Task einen Vorgänger ('Vater-Task') und möglicherweise Nachfolger
+('Sohn-Tasks').
+
+#on("u")##ib#Task-Organisation#ie##off("u")#
+
+
+ SUPERVISOR
+ -
+ SYSUR
+ ARCHIVE
+ configurator
+ OPERATOR
+ shutup
+
+ UR
+ PUBLIC
+ Benutzertask1
+ Benutzertask2
+ Benutzertask3
+ .....
+
+
+
+Jeder Benutzer arbeitet innerhalb eines EUMEL-Systems, indem er eine Task an
+sein Terminal koppelt und dort Programme aufruft.
+
+Dateien sind grundsätzlich Eigentum einer Task. Es ist grundlegend für das Verständ­
+nis des Betriebssystems EUMEL, die Beziehung zwischen Tasks und Dateien zu
+erkennen.
+
+Eine Task ist ein Prozeß, der gegebenenfalls Dateien besitzt. Dateien können nur in
+einer Task existieren. Um eine Datei einer anderen Task zur Verfügung zu stellen,
+wird eine Kopie der Datei an die andere Task geschickt, die sendende Task ist da­
+nach Eigentümer des 'Originals', die empfangende Task Eigentümer der 'Kopie'.
+
+Soll eine Hierarchie von Dateien aufgebaut werden, so ist sie über eine Hierarchie
+von Tasks zu realisieren, da in einer Task alle Dateien gleichberechtigt sind.
+
+Bis zu dieser Stelle war stets von Dateien die Rede. Dateien sind jedoch ein Spezial­
+fall der grundlegenderen Struktur des Datenraumes.
+
+Ein #ib#Datenraum#ie# ist ein allgemeiner Datenbehälter. Ein Datenraum kann beliebige
+Daten aufnehmen und erlaubt direkten Zugriff auf diese Daten. Die Struktur der Daten
+im Datenraum unterscheidet sich nicht von der Struktur der Programmdaten. Der
+'innere Datentyp' eines Datenraums wird vom Programmierer festgelegt.
+
+Vorgeprägt vom System gibt es Textdateien, jeder andere Datentyp muß vom Pro­
+grammierer geprägt werden, um so Dateien erzeugen zu können, die Objekte eben
+dieses neuen Typs enthalten.
+#page#
+
+
+1.3 Eigenschaften des Betriebssystems
+
+Der erste Entwurf des Mikroprozessor-Betriebssystems EUMEL (#on("b")#E#off("b")#xtendable multi
+#on("b")#U#off("b")#ser #on("b")#M#off("b")#icroprozessor #on("b")#EL#off("b")#AN system) entstand 1979 mit dem Anspruch, auf Mikrocom­
+putern den Anwendern Hilfsmittel und Unterstützungen zu bieten, wie sie sonst nur
+auf Großrechnern zur Verfügung gestellt werden.
+
+Aspekte, die EUMEL von anderen Betriebssystemen für Mikrocomputer unterscheiden,
+sind:
+
+- Hardwareunabhängigkeit
+- Multitaskingkonzept
+- Multiuserbetrieb
+- Erweiterbarkeit
+- virtuelle Speicherverwaltung
+- Datensicherheit
+
+
+
+#on("u")##on("b")#Das EUMEL-Schichtenmodell#off("b")##off("u")#
+
+Die Hardwareunabhängigkeit des Betriebssystems EUMEL begründet sich in seinem
+Aufbau aus Schichten (sogenannten virtuellen Maschinen), die einen klar definierten
+Leistungsumfang haben.
+
+#center#beliebige Anwendungen
+#center#Textverarbeitung, Datenbanken etc.
+
+#center#Systemdienste: Monitor, Dateiverwaltung, Editor
+#center#Task-System
+#center#Standardpakete (BOOL, INT, REAL, TEXT)
+#center#ELAN-Compiler
+
+#center#EUMEL0
+#center#(virtueller Prozessor mit eigenem Befehlssatz)
+
+#center#SHard (Gerätetreiber)
+
+#center#Hardware
+
+
+Jede Schicht erwartet und erhält von ihren Nachbarn wohldefinierte Eingaben und gibt
+wohldefinierte Ausgaben weiter. Änderungen in einer Schicht müssen also in den
+angrenzenden Schichten beachtet werden, aber nicht in allen Teilen des Systems.
+
+Um EUMEL auf Rechner mit einem neuen Prozessortyp zu portieren, wird zunächst
+eine auf die Eigenheiten des Prozessors abgestimmte EUMEL0-Maschine entworfen
+und eine Hardwareanpassung (#ib#SHard#ie# : Software/Hardware-Interface) für einen
+Rechner mit diesem Prozessor hergestellt. Alle höheren Schichten des Systems
+bleiben unberührt. Weitere mit diesem Prozessortyp ausgestattete Rechner können mit
+EUMEL betrieben werden, indem ein SHard für dieses Rechnermodell geschrieben
+wird.
+
+Aus Benutzersicht ist wichtig, daß dadurch jegliche Software, die auf irgendeinem
+Rechner unter EUMEL verfügbar ist, auf jedem anderen Rechner, für den eine
+EUMEL Portierung existiert, lauffähig ist und gleiches Verhalten zeigt. Eine Vernet­
+zung beliebiger Rechner, auf die EUMEL portiert ist, ist problemlos möglich.
+
+Desweiteren ist für den Benutzer des Systems von Bedeutung, daß er von der hard­
+warenahen Schicht entfernt ist. Weder die Programmiersprache noch irgendwelche
+speziellen Systemfunktionen gewähren direkten Zugriff auf den Speicher oder Regi­
+sterinhalte. Diese Tatsache hat weitreichende Folgen in Hinsicht auf Datenschutz und
+Systemsicherheit.
+
+
+
+
+Multi-Tasking-/Multi-User-Betrieb
+Wie einleitend dargestellt, besteht ein EUMEL-System aus diversen Tasks. Durch
+eine Aufteilung der Prozessorzeit in Zeitscheiben ist eine (quasi) parallele Bedienung
+mehrerer Tasks möglich.
+
+Die multi-user-Fähigkeit des Betriebssystems wird durch den Anschluß mehrerer
+Bildschirmarbeitsplätze (Terminals) an V.24 Schnittstellen des Rechners erreicht.
+Dabei wird jeder Schnittstelle eine sogenannte Kanalnummer zugeordnet. Jeder
+Benutzer kann seine Task dann an einen Kanal (=Terminal) koppeln und an diesem
+Terminal gleichzeitig mit anderen Benutzern arbeiten.
+
+
+
+
+Prozeßkommunikation und Netzwerkfähigkeit
+Grundlage der Kommunikation ist die 'Manager-Eigenschaft' von Tasks. Eine Task
+ist 'Manager', wenn sie Aufträge anderer Tasks annehmen und ausführen kann.
+Insbesondere kann ein Manager veranlaßt werden, eine an ihn geschickte Datei anzu­
+nehmen, bzw. eine ihm gehörende Datei an die fordernde Task zu schicken.
+
+Derartige Kommunikationslinien verlaufen normalerweise in der Baumstruktur des
+Systems: z.B. ist die Task 'PUBLIC' (vergl. Seite 2) grundsätzlich Manager-Task.
+Eine unterhalb von PUBLIC liegende Task kann eine Datei an PUBLIC senden, bzw.
+von PUBLIC holen.
+
+Es ist auch möglich, eine Task für den Zugriff beliebiger anderer Tasks zu öffnen und
+somit beliebige Kommunikationspfade aufzubauen. Prinzipiell ist damit auch schon der
+Aufbau eines Netzwerkes beschrieben, denn sendende und empfangende Tasks
+können sich auf verschiedenen Rechnern befinden.
+
+Durch selbst erstellte Programme kann der Eigentümer einer 'Manager-Task' die
+Reaktion dieser Task auf einen Auftrag von außen bestimmen. Beispielsweise kann
+ein Manager derart programmiert werden, daß er nur Dateien empfängt und ausdruckt,
+aber niemals Dateien verschickt (Spool-Task).
+
+
+
+Erweiterbarkeit
+Die Programmiersprache ELAN ist im EUMEL-System gleichzeitig Programmier-
+und System-Kommandosprache (JCL), denn jedes Kommando ist Aufruf einer
+ELAN-Prozedur und jede vom Benutzer geschriebene ELAN-Prozedur erweitert
+den Kommandovorrat des Systems.
+
+Da alle EUMEL-Werkzeuge (einschließlich Editor) selbst ELAN-Programme sind,
+kann das System vom Benutzer selbst durch Hinzufügen eigener ELAN-Programme
+oder Programmpakete beliebig erweitert werden. Dabei können die bereits implemen­
+tierten Systemteile (z.B. die Fenstertechnik des Editors) genutzt werden.
+
+Ein Benutzer muß, um alle Möglichkeiten vom EUMEL zu nutzen, nur eine Sprache
+lernen und nicht - wie bei anderen Betriebssystemen - zwei unterschiedliche, eine
+Kommando- und eine Programmiersprache.
+
+ELAN selbst ist eine PASCAL-ähnliche Programmiersprache, die mit Hilfe der
+schrittweisen Verfeinerung (Refinement-Konzept) die Top-Down-Programmierung
+unterstützt. Das Paketkonzept, das der Modularisierung dient, und die freie Wahl von
+Bezeichnernamen sind Voraussetzung für übersichtliche und effiziente Programmie­
+rung.
+
+
+
+
+Virtuelle Speicherverwaltung
+Im EUMEL-System wird der Hauptspeicherplatz nach dem #on("b")#Demand-Paging-Prinzip#off("b")#
+verwaltet. Daten und Programme werden dazu in Seiten von 512 Byte aufgeteilt. Nur
+diejenigen Seiten, die wirklich benötigt werden, werden vom Hintergrundspeicher
+(Platte) in den Hauptspeicher geholt. Damit ist für den Benutzer bezüglich seiner
+Programm- bzw. Dateigrößen nicht mehr der Hauptspeicher, sondern die Hinter­
+grundkapazität von Bedeutung. Die Durchsatzgeschwindigkeit (Performance) ist
+abhängig von der Größe des RAM-Speichers und der Zugriffsgeschwindigkeit des
+Hintergrundmediums. Das Demand-Paging-Verfahren ist Grundlage für den
+Multi-User-Betrieb, wobei der Hauptspeicherplatz möglichst effizient zu nutzen und
+kein Benutzer zu benachteiligen ist.
+
+Beim Duplizieren eines Datenraumes wird im EUMEL-System lediglich eine logische,
+keine physische Kopie erzeugt. Zwei Seiten (zweier Datenräume) heißen dann gekop­
+pelt (geshared), wenn beide Seiten physisch demselben Block zugeordnet sind. Erst
+bei einem Schreibzugriff werden die Seiten entkoppelt (entshared) und tatsächlich
+physisch kopiert. Daher der Name "#on("b")#copy-on-write#off("b")#".
+
+Dieses Prinzip wird natürlich auch systemintern angewandt. Beispielsweise erbt eine
+Sohn-Task den Kommandovorrat der Vater-Task, indem der Standard-Datenraum,
+der die vorübersetzten ELAN-Prozeduren enthält, in der beschriebenen Weise kopiert
+wird. Prozeduren, die später hinzugefügt werden, werden natürlich nicht vererbt, da
+die Standard-Datenräume dann entkoppelt werden.
+
+
+
+
+Datensicherheit
+Störungen (inklusive Stromausfall) werden systemseitig durch eine automatische
+#on("b")#Fixpoint-Rerun-Logik#off("b")# aufgefangen, indem zum Zeitpunkt eines Fixpunkts der Inhalt
+des RAM Speichers, der seit dem letzten #ib#Fixpunkt#ie# verändert wurde auf den
+permanenten Speicher (Festplatte) geschrieben wird. Somit kann nach einer Störung
+immer auf den Systemzustand des letzten Fixpunktes aufgesetzt werden und die
+Datenverluste halten sich in erträglichen Grenzen.
+
+Der Zeitraum zwischen zwei Fixpunkten beträgt standardmäßig 15 Minuten, kann aber
+vom Benutzer anders eingestellt werden.
+
+Auch bei dieser Sicherung wird das Copy-on-write-Prinzip angewendet, so daß
+Platz- und Zeitaufwand gering sind und den normalen Ablauf nicht stören.
+
+#page#
+
+1.4 Wichtige Begriffe
+
+- #on("b")##ib#archive#ie##off("b")#. Spezielle Task zur Verwaltung des Diskettenlaufwerks. Da für die
+ längerfristige Datenhaltung und zur zusätzlichen Datensicherung Dateien auf
+ Disketten geschrieben werden, besitzt das EUMEL-System für diese Aufgabe
+ eine besondere Task, die die Bedienung vereinfacht und exklusiven Zugriff auf das
+ Laufwerk garantiert.
+
+- #on("b")##ib#configurator#ie##off("b")#. Besondere Task im Systemzweig des EUMEL-Systems. In
+ dieser Task ist die #ib#Konfiguration#ie# von Kanälen möglich, d.h. Kanal und
+ angeschlossenenes Gerät werden aufeinander abgestimmt.
+
+- #on("b")##ib#editor#ie##off("b")#. Programm zur Dateibearbeitung am Bildschirm. Das Programm wird
+ durch das ( Monitor- ) Kommando 'edit' und die Eingabe des Namens der ge­
+ wünschten Datei als Parameter gestartet.
+
+ Da ein Bildschirm normalerweise auf 80 Zeichen Zeilenbreite und 24 Zeilen be­
+ schränkt ist, kann der Editor als Fenster betrachtet werden, das über die mögli­
+ cherweise weitaus größere Datei bewegt wird und durch das der betrachtete Aus­
+ schnitt der Datei bearbeitet werden kann.
+
+- #on("b")##ib#manager task#ie##off("b")#. Task, die Aufträge von anderen Tasks entgegennehmen und
+ ausführen #on("u")#kann#off("u")#. Beispielsweise ist die Verwaltung von Dateien, die mehreren
+ Benutzern (= anderen Tasks) zugänglich sein sollen, eine typische Aufgabe für
+ einen Manager.
+
+- #on("b")##ib#Monitor#ie##off("b")#. Der Empfänger von Kommandos innerhalb einer Task ist der Monitor. Der
+ Monitor ist sichtbar durch eine Zeile, in der 'gib kommando' steht. In diese Zeile
+ werden #ib#Kommando#ie#s und erforderliche Parameter eingegeben.
+
+- #on("b")##ib#Supervisor#ie##off("b")#. Spezielle Task zur Überwachung eines EUMEL-Systems. Ein
+ Benutzer kann durch die Supervisor-Kommandos Leistungen von dieser Task
+ fordern: neue Task einrichten, Task wiederaufnehmen und diverse Informationen.
+
+- #on("b")##ib#Task#ie##off("b")#. Beliebig langlebiger Prozeß im EUMEL-System, der die Arbeits­
+ umgebung für Benutzer bildet. Jede Task besitzt einen #ib#Standard-Datenraum#ie#, der
+ Code und Compilertabellen der Task enthält und kann weitere Datenräume
+ (Dateien) besitzen.
+
+#page#
+
+1.5 Die Notation in diesem Buch
+
+Beachten Sie bitte folgende Regeln der Aufschreibung:
+
+- Funktionstasten werden ebenso wie besondere Tastenkombinationen explizit als
+ Tasten dargestellt:
+
+ <SV> <ESC> <e>
+
+
+- Alles, was Sie am Bildschirm Ihres Rechners schreiben oder lesen sollen, ist in
+ Textbereiche, die einen Bildschirm darstellen, eingefaßt.
+
+ Beispiel:
+
+____________________________________________________________________________
+ gib kommando:
+ edit ("mein programm")
+
+____________________________________________________________________________
+
+
+- Innerhalb des Handbuchs sind in der Aufschreibung die Konventionen der Pro­
+ grammiersprache ELAN berücksichtigt. Dabei sind folgende Besonderheiten zu
+ beachten:
+
+ 1) Kommandos werden grundsätzlich klein geschrieben.
+
+ 2) Dateinamen u.ä. sind Textdenoter und werden somit in Klammern und Anfüh­
+ rungsstriche gesetzt. In diesem Buch steht an den Stellen, wo ein Dateiname
+ auftaucht #on("i")# 'dateiname' #off("i")#; den Namen, den Sie tatsächlich verwenden, können
+ Sie frei wählen.
+
+ 3) Falls besondere Begriffe oder Beispiele innerhalb eines normalen Textes
+ auftreten, werden sie in einfache Anführungsstriche gesetzt.
+
+
+#page#
+
+1.6 Die Funktionstasten des EUMEL-Systems
+
+Die Lage der EUMEL-Funktionstasten entnehmen Sie bitte der speziellen Installa­
+tionsanleitung zu dem von Ihnen benutzten Gerät. #l pos (0.0)##l pos(4.0)#
+
+
+<v> <^> <>> <<> Positionierungstasten
+#table#
+
+<SHIFT> Umschalttaste
+
+<CR> Eingabe-/ Absatztaste
+
+<ESC> Kommandotaste
+
+<SV> Supervisortaste
+
+<HOP> Verstärkertaste
+
+<RUBOUT> Löschtaste
+
+<RUBIN> Einfügetaste
+
+<TAB> Tabulatortaste
+
+<MARK> Markiertaste
+
+<STOP> Stoptaste
+
+<WEITER> Weitertaste
+#tableend##clear pos#
+
+Weitere Informationen hierzu finden Sie in der Installationsanleitung zu dem von Ihnen
+benutzten Rechner oder Terminal.
+#page#
+
+1.7 Eine Beispielsitzung
+
+Im Folgenden wird eine Beispielsitzung skizziert, in der ein ELAN-Programm erstellt
+und getestet wird.
+
+ <SV> SUPERVISOR aufrufen
+
+
+
+____________________________________________________________________________
+
+ Terminal 2
+
+
+ EUMEL Version 1.8/M
+
+
+ gib supervisor kommando:
+ begin("meine erste Task")
+
+
+
+ ESC ? --> help
+ ESC b --> begin("") ESC h --> halt
+ ESC c --> continue("") ESC s --> storage info
+ ESC q --> break ESC t --> task info
+
+____________________________________________________________________________
+
+
+
+
+Durch das Kommando 'begin ("meine erste Task")', welches durch <CR> abgeschlos­
+sen werden muß, wird eine Task mit dem Namen 'meine erste Task' im Benutzer­
+zweig, also unterhalb von 'PUBLIC' angelegt. Würde diese Task bereits existieren, so
+könnten Sie sie mit 'continue ("meine erste Task")' an das Terminal holen.
+
+____________________________________________________________________________
+
+ gib kommando :
+ edit ("mein erstes Programm")
+
+____________________________________________________________________________
+
+
+In der Task eröffnen Sie eine Datei mit dem Kommando 'edit ("dateiname")'.
+
+
+____________________________________________________________________________
+
+ gib kommando :
+ edit ("mein erstes Programm")
+ "mein erstes Programm" neu einrichten (j/n) ? j
+
+____________________________________________________________________________
+
+
+Falls diese Datei neu ist, erfolgt eine Kontrollfrage (zur Kontrolle der gewünschten
+Schreibweise des Dateinamens), die Sie durch <j> bejahen.
+
+
+____________________________________________________________________________
+ ............ mein erstes Programm ............... Zeile 1 #markon#
+_
+____________________________________________________________________________
+
+
+
+
+
+
+In die noch leere Datei tippen Sie nun den Programmtext ein.
+
+
+____________________________________________________________________________
+ ............ mein erstes Programm ............... Zeile 1
+ _INT PROC ggt (INT CONST a, b):
+ INT VAR b kopie :: abs (b), a kopie :: abs (a);
+ WHILE b kopie <> 0 REPEAT
+ INT VAR rest := a kopie MOD b kopie;
+ a kopie := b kopie;
+ b kopie := rest
+ END REPEAT;
+ a kopie
+ END PROC gt;
+
+ REP
+ lies 2 zahlen ein;
+ gib groessten gemeinsamen teiler aus
+ UNTIL no ("weitertesten") PER.
+
+ lies 2 zahlen ein:
+ line; put ("2 Zahlen eingeben:");
+ INT VAR a, b;
+ get (a); get (b).
+
+ gib groessten gemeinsamen teiler aus:
+ put ("der größte gemeinsame Teiler von");
+ put (a); put ("und"); put (b); put ("ist"); put (ggt (a,b));
+ line.
+
+____________________________________________________________________________
+
+
+In dem Programmbeispiel wird ein Prozedur 'ggt' definiert, die den größten gemein­
+samen Teiler zweier Zahlen bestimmt. Die Prozedur soll für verschiedene Beispiele
+getestet werden; dies geschieht in dem Hauptprogramm, das solange Zahlen einliest
+und den größten gemeinsamen Teiler ausgibt, bis der Benutzer auf die Frage 'weiter­
+testen (j/n) ?' mit <n> antwortet.
+
+Haben Sie das Programm eingegeben, so können Sie die Bearbeitung dieser Pro­
+grammdatei durch Drücken der Tasten <ESC> <q> (nacheinander!) beenden.
+
+
+____________________________________________________________________________
+
+ gib kommando :
+ run ("mein erstes Programm")
+
+____________________________________________________________________________
+
+
+Um Ihr Programm zu übersetzen und auszuführen, geben Sie das Kommando
+'run ("dateiname")'.
+
+Der Verlauf der Übersetzung, die zwei Läufe über das Programm erfordert, ist am
+Zähler, der an der linken Seite des Bildschirms ausgegeben wird, zu erkennen.
+
+Werden beim Übersetzen des Programms Fehler entdeckt, so werden diese im 'note­
+book' parallel zur Programmdatei gezeigt. In dem Beispielprogramm wurde ein
+Schreibfehler in Zeile 9 gemacht.
+
+
+____________________________________________________________________________
+ ............ mein erstes Programm ............... Zeile 1
+ _INT PROC ggt (INT CONST a, b):
+ INT VAR b kopie :: abs (b), a kopie :: abs (a);
+ WHILE b kopie <> 0 REPEAT
+ INT VAR rest := a kopie MOD b kopie;
+ a kopie := b kopie;
+ b kopie := rest
+ END REPEAT;
+ a kopie
+ END PROC gt;
+
+ REP
+ .................. notebook ..................... Zeile 1 #markon#
+ Zeile 9 FEHLER bei >> gt <<
+ ist nicht der PROC Name
+
+
+____________________________________________________________________________
+
+
+
+Diesen Fehler müssen Sie nun verbessern.
+
+____________________________________________________________________________
+ ............ mein erstes Programm ............... Zeile 9
+ INT PROC ggt (INT CONST a, b):
+ INT VAR b kopie :: abs (b), a kopie :: abs (a);
+ WHILE b kopie <> 0 REPEAT
+ INT VAR rest := a kopie MOD b kopie;
+ a kopie := b kopie;
+ b kopie := rest
+ END REPEAT;
+ a kopie
+ END PROC ggt;_
+
+ REP
+ .................. notebook ..................... Zeile 1
+ Zeile 9 FEHLER bei >> gt <<
+ ist nicht der PROC Name
+
+____________________________________________________________________________
+
+
+
+
+Haben Sie das Programm korrigiert, so können Sie die Datei durch Drücken der
+Tasten <ESC> <q> (nacheinander!) wieder verlassen.
+
+
+____________________________________________________________________________
+
+ gib kommando :
+ run ("mein erstes Programm")
+
+____________________________________________________________________________
+
+
+Nach Eingabe von <R> wird das Programm erneut übersetzt.
+
+
+____________________________________________________________________________
+
+ Keine Fehler gefunden, 136 B Code, 82 B Paketdaten generiert
+
+
+ ******* ENDE DER UEBERSETZUNG *******
+
+
+ 2 Zahlen eingeben: _
+
+____________________________________________________________________________
+
+
+Das Programm war jetzt fehlerfrei. Nach der Übersetzung wurde die Ausführung
+gestartet. Nun können Beispiele getestet werden.
+
+____________________________________________________________________________
+
+ 2 Zahlen eingeben: 125 250
+ der größte gemeinsame Teiler von 125 und 225 ist 25
+ weitertesten (j/n) ?
+
+____________________________________________________________________________
+
+
+Beantwortet man die Frage mit <n>, so wird die Ausführung des Programms beendet.
+
+
+____________________________________________________________________________
+
+ gib kommando :
+
+____________________________________________________________________________
+
+
+Um die Arbeit in der Task zu beenden, geben Sie auch an dieser Stelle <ESC> <q>
+(nacheinander!) ein.
+
+Nach Verlassen der Task ist wiederum die EUMEL-Tapete auf dem Bildschirm. Jede
+weitere Aktion wird wiederum von hier aus durch <SV> begonnen. Insbesondere vor
+dem #ib#Ausschalten des Geräts#ie# muß nach <SV> eine Task des priviliegierten System­
+zweigs (oft: '#ib#shutup#ie#') mit <ESC> <c> an das Terminal gekoppelt werden, in der das
+Kommando 'shutup' gegeben wird.
+
diff --git a/doc/programmer-manual/1.8.7/doc/programmierhandbuch.2a b/doc/programmer-manual/1.8.7/doc/programmierhandbuch.2a
new file mode 100644
index 0000000..a204091
--- /dev/null
+++ b/doc/programmer-manual/1.8.7/doc/programmierhandbuch.2a
@@ -0,0 +1,1845 @@
+#headandbottom("1","EUMEL-Benutzerhandbuch","TEIL 2 : ELAN","2")#
+#pagenr("%",1)##setcount(1)##block##pageblock#
+#headeven#
+#center#EUMEL-Benutzerhandbuch
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#TEIL 2 : ELAN
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+2 - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right# 2 - %
+#end#
+
+TEIL 2: ELAN
+
+2.1 Besondere Eigenschaften von ELAN
+
+Kerneigenschaften von ELAN sind das #ib#Paketkonzept#ie# und die Methode des
+#ib#Refinements#ie#.
+
+#on("b")#Paketkonzept:#off("b")#
+ELAN bietet die Möglichkeit, neue Datentypen sowie Prozeduren und Operatoren auf
+diesen Datentypen zu definieren. Eine solche Definition von Algorithmen und Daten­
+typen kann zu einer logischen Einheit, einem Paket, zusammengefaßt werden. Pakete
+können in einer Task vorübersetzt werden und erweitern damit automatisch den
+Sprachumfang.
+
+#on("b")#Methode des Refinements:#off("b")#
+Die Methode des Refinements erlaubt das schrittweise Herleiten von Problemlösungen
+von der jeweils geeigneten Terminologie herunter zu den von ELAN standardmäßig
+angebotenen Sprachelementen. Durch diese Vorgehensweise wird in äußerst starkem
+Maße ein strukturierter Programmentwurf gemäß dem Top-Down-Prinzip gefördert.
+
+Die Programmiersprache ELAN wird im EUMEL-System zu folgenden Zwecken
+eingesetzt:
+
+- Systemimplementationssprache
+- Kommandosprache
+- Anwenderprogrammiersprache
+#page#
+
+2.2 Lexikalische Elemente
+
+Unter lexikalischen Elementen einer Programmiersprache versteht man die Elemente,
+in denen ein Programm notiert wird.
+
+In ELAN sind dies:
+
+- Schlüsselwörter
+- Bezeichner
+- Sonderzeichen
+- Kommentare
+
+
+
+
+2.2.1 Schlüsselwörter
+
+Einige Wörter haben in ELAN eine feste Bedeutung und können somit nicht frei
+gewählt werden. Solche Wörter werden im EUMEL-System in Großbuchstaben
+geschrieben, Leerzeichen dürfen nicht enthalten sein.
+
+Beispiele:
+
+
+VAR
+INT
+WHILE
+
+
+Wie später beschrieben wird, gibt es in ELAN auch die Möglichkeit, neue Schlüssel­
+wörter einzuführen.
+
+
+#page#
+
+2.2.2 Bezeichner
+
+Bezeichner oder Namen werden benutzt, um Objekte in einem Programmtext zu
+benennen und zu identifizieren (z.B: Variablennamen, Prozedurnamen).
+
+Namen werden in ELAN folgendermaßen formuliert:
+
+Das erste Zeichen eines Namens muß immer ein Kleinbuchstabe sein. Danach dürfen
+bis zu 254 Kleinbuchstaben, aber auch Ziffern folgen. Zur besseren Lesbarkeit können
+Leerzeichen in einem Namen erscheinen, die aber nicht zum Namen zählen. Sonder­
+zeichen sind in Namen nicht erlaubt.
+
+Beispiele für #on("b")#korrekte#off("b")# Bezeichner:
+
+
+das ist ein langer name
+x koordinate
+nr 1
+
+
+
+Beispiele für #on("b")#falsche#off("b")# Bezeichner:
+
+
+x*1
+1 exemplar
+Nr 1
+#page#
+
+2.2.3 Sonderzeichen
+
+Sonderzeichen sind Zeichen, die weder Klein- oder Großbuchstaben, noch Ziffern
+sind. Sie werden in ELAN als Trennzeichen oder als Operatoren benutzt.
+
+In ELAN gibt es folgende Trennungszeichen:
+
+- das Semikolon (';') trennt Anweisungen
+- der Doppelpunkt (':') trennt Definiertes und Definition
+- der Punkt ('.') wird als Endezeichen für bestimmte Programmabschnitte, als Dezi­
+ malpunkt und als Selektor-Zeichen für Datenstrukturen benutzt
+- das Komma (',') trennt Parameter
+- Klammernpaare ('(', ')') werden zum Einklammern von Parameterlisten oder Teil­
+ ausdrücken benutzt
+- mit Anführungszeichen ('"') werden Text-Denoter umrahmt
+- eckige Klammernpaare ('[', ']') werden zur Subskription benutzt.
+
+
+Als Operatornamen sind folgende Sonderzeichen erlaubt:
+
+- ein Sonderzeichen, sofern es nicht als Trennzeichen benutzt wird:
+ ! $ % & ' * + - / < = > ? § ^ ' ~
+- eine Kombination von zwei Sonderzeichen. Diese Kombination muß jedoch bereits
+ in ELAN existieren:
+ := <= >= <> **
+
+#page#
+
+2.2.4 Kommentare
+
+Kommentare dienen ausschließlich der Dokumentation eines Programms. Sie werden
+vom Compiler überlesen und haben somit keinen Einfluß auf die Ausführung eines
+Programms. Sie dürfen an beliebigen Stellen eines Programmtextes geschrieben
+werden, jedoch nicht innerhalb von Schlüsselwörtern und Namen. Ein Kommentar darf
+über mehrere Zeilen gehen. In ELAN sind Kommentare nur in wenigen Fällen notwen­
+dig, da Programme durch andere Mittel gut lesbar geschrieben werden können.
+
+Ein Kommentar in ELAN wird durch Kommentarklammern eingeschlossen. Es gibt
+folgende Formen von Kommentarklammern:
+
+(* Kommentar *)
+{ Kommentar }
+\#( Kommentar )#
+
+Die letzte Version '\#( Kommentar )\#' wird im EUMEL-System nicht
+unterstützt; statt dessen gibt es noch folgende Möglichkeit:
+
+\# Kommentar \#
+
+Da bei der Kommentarkennzeichnung mit \# für Kommentaranfang und -ende das
+gleiche Zeichen benutzt wird, ist eine Schachtelung hier nicht möglich.
+#page#
+
+2.3 Datenobjekte
+
+Eine Klasse von Objekten mit gleichen Eigenschaften wird in Programmiersprachen
+Datentyp genannt. Dabei hat ein Datentyp immer einen Namen, der die Klasse von
+Objekten sinnvoll kennzeichnet. Als ein Datenobjekt wird ein Exemplar eines Daten­
+typs (also ein spezielles 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 Datentypen
+auch als Eigenschaften von Datenobjekten ansehen. Für jeden Datentyp sind nur
+spezielle Operationen sinnvoll. Man kann nun Compilern die Aufgabe überlassen zu
+überprüfen, ob stets die richtige Operation auf einen Datentyp angewandt wird.
+
+
+
+2.3.1 Elementare Datentypen
+
+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 (INT)
+- reelle Zahlen (REAL)
+- Zeichen und Zeichenfolgen (TEXT)
+- Wahrheitswerte (BOOL).
+
+Diese Datentypen sind von der Sprache ELAN vorgegeben und werden elementare
+Datentypen genannt. Für effiziente Rechnungen mit elementaren Datentypen gibt es
+in den meisten Rechnern spezielle Schaltungen, so daß die Hervorhebung und be­
+sondere Rolle, die sie in Programmiersprachen spielen, gerechtfertigt ist. Zudem hat
+man Werte-Darstellungen (Denoter) innerhalb von Programmen für die elementaren
+Datentypen vorgesehen.
+
+
+
+2.3.1.1 Denoter für elementare Datentypen
+
+Die Darstellung eines Werts in einem Rechner zur Laufzeit eines Programms wird
+Repräsentation genannt. Wenn es eindeutig ist, daß es sich nur um die Repräsenta­
+tion im Rechner handelt, spricht man kurz von Werten. Um mit Objekten elementarer
+Datentypen arbeiten zu können, muß es in einem Programm die Möglichkeit geben,
+Werte eines Datentyps zu bezeichnen (denotieren). Die Werte-Darstellungen, 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
+Compiler feststellbaren - Datentyp. Aus der Form eines Denoters ist also der Daten­
+typ erkennbar:
+
+
+
+INT-Denoter:
+Sie 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. Negative Werte
+werden durch eine Aufeinanderfolge des monadischen Operators '-' (siehe 2.4.1.1)
+und eines INT- Denoters realisiert.
+
+
+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 wie ein Komma in der deutschen Schreibweise benutzt. Nega­
+tive REAL-Denoter gibt es wiederum nicht.
+
+Die zweite Form wird als "wissenschaftliche Notation" bezeichnet. Sie findet dann
+Verwendung, wenn sehr große Zahlen oder Zahlen, die nahe bei Null liegen, darge­
+stellt werden müssen.
+
+Beispiele:
+
+
+3.0 e5
+3.0e-5
+
+
+Der INT-Denoter hinter dem Buchstaben #on("b")#e#off("b")# gibt an, wie viele Stellen der Dezimal­
+punkt nach rechts (positive Werte) bzw. nach links (negative Werte) zu verschieben
+ist. Dieser Wert wird Exponent und der Teil vor dem Buchstaben #on("b")#e#off("b")# Mantisse genannt.
+
+
+TEXT-Denoter:
+Sie werden in Anführungszeichen eingeschlossen.
+
+Beispiele:
+
+
+"Das ist ein TEXT-Denoter"
+"Jetzt ein TEXT-Denoter ohne ein Zeichen: ein leerer Text"
+""
+
+
+Zu beachten ist, daß das Leerzeichen ebenfalls ein Zeichen ist. Soll ein Anführungs­
+zeichen in einem TEXT erscheinen (also gerade das Zeichen, welches einen Denoter
+beendet), so muß es doppelt geschrieben werden.
+
+Beispiele:
+
+
+"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.
+
+Beispiel:
+
+
+"da"251""
+
+
+ist gleichbedeutend mit "daß". Der Code-Wert eines Zeichens ergibt sich aus der
+EUMEL-Code-Tabelle (siehe 5.2.4.1), in der jedem Zeichen eine ganze Zahl zuge­
+ordnet ist.
+
+
+BOOL-Denoter:
+Es gibt nur zwei BOOL-Denoter:
+TRUE für "wahr" und FALSE für "falsch".
+
+
+
+2.3.1.2 LET-Konstrukt für Denoter
+
+Neben der Funktion der Abkürzung von Datentypen (siehe 2.6.3) kann das LET-
+Konstrukt auch für die Namensgebung für Denoter verwandt werden.
+
+Die LET-Vereinbarung sieht folgendermaßen aus:
+
+
+#on("i")##on("b")#LET#off("i")##off("b")# Name #on("i")##on("b")#=#off("i")##off("b")# Denoter
+
+
+Mehrere Namensgebungen können durch Komma getrennt werden.
+
+
+____________________________________________________________________________
+ .......................... Beispiele: .........................
+ LET anzahl = 27;
+ LET pi = 3.14159,
+ blank = " ";
+____________________________________________________________________________
+
+
+Der Einsatz von LET-Namen für Denoter hat zwei Vorteile:
+
+- feste Werte im Programm sind leicht zu ändern, da nur an einer Stelle des Pro­
+ gramms der Denoter geändert werden muß
+ (z.B.: In Vereinbarungen von Reihungen (siehe 2.6.1) können LET-Denoter, im
+ Gegensatz zu Konstanten, als Obergrenze angegeben werden. Dieser
+ Wert kann dann auch an anderen Stellen des Programms, z.B. in Schlei­
+ fen (siehe 2.4.2.5), benutzt werden. Bei Änderung der Reihungsgröße
+ braucht dann nur an einer Stelle des Programms der Wert geändert zu
+ werden.)
+- der Name gibt zusätzliche Information über die Bedeutung des Denoters.
+
+
+
+2.3.2 Zugriffsrecht
+
+Von manchen Datenobjekten weiß man, daß sie nur einmal einen Wert erhalten
+sollen. Sie sollen also nicht verändert werden. Oder man weiß, daß in einem Pro­
+grammbereich ein Datenobjekt nicht verändert werden soll. Um ein unbeabsichtigtes
+Verändern zu verhindern, wird in ELAN dem Datenobjekt ein zusätzlicher Schutz
+mitgegeben: das Zugriffsrecht oder Accessrecht.
+
+In der Deklaration eines Datenobjekts können folgende Accessattribute angegeben
+werden:
+
+- #on("i")##on("b")#VAR #off("i")##off("b")# für lesenden und schreibenden (verändernden) Zugriff
+
+- #on("i")##on("b")#CONST#off("i")##off("b")# für nur lesenden Zugriff.
+
+
+
+2.3.3 Deklaration
+
+Damit man Datenobjekte in einem Programm ansprechen kann, gibt man einem
+Datenobjekt einen Namen (wie z.B. einen Personennamen, unter der sich eine wirk­
+liche Person "verbirgt"). Will man ein Datenobjekt in einem Programm verwenden, so
+muß man dem Compiler mitteilen, welchen Datentyp und welches Accessrecht das
+Objekt haben soll. Das dient u.a. dazu, nicht vereinbarte Namen (z.B. verschriebene)
+vom Compiler entdecken zu lassen. Weiterhin ist aus dem bei der Deklaration ange­
+gebenen Datentyp zu entnehmen, wieviel Speicherplatz für das Objekt zur Laufzeit zu
+reservieren ist.
+
+Eine Deklaration oder Vereinbarung besteht aus der Angabe von
+
+- Datentyp
+- Zugriffsrecht ( #on("i")##on("b")#VAR#off("i")##off("b")# oder #on("i")##on("b")#CONST#off("i")##off("b")#)
+- Name des Datenobjekts.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT VAR mein datenobjekt;
+
+____________________________________________________________________________
+
+
+Verschiedene Datenobjekte mit gleichem Datentyp und Accessrecht dürfen in einer
+Deklaration angegeben werden; sie werden durch Kommata getrennt. Mehrere Dekla­
+rationen werden - genauso wie Anweisungen - durch das Trennzeichen Semikolon
+voneinander getrennt.
+
+____________________________________________________________________________
+ .......................... Beispiele: .........................
+ INT VAR mein wert, dein wert, unser wert;
+ BOOL VAR listen ende;
+ TEXT VAR zeile, wort;
+
+____________________________________________________________________________
+
+
+2.3.4 Initialisierung
+
+Um mit den vereinbarten Datenobjekten arbeiten zu können, muß man ihnen einen
+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 Fehler­
+kuelle zu vermeiden. Eine Wertgebung an ein Datenobjekt kann (muß aber nicht)
+bereits bei der Deklaration erfolgen. In ELAN wird dies Initialisierung genannt. Für mit
+CONST vereinbarte Datenobjekte ist die Initialisierung die einzige Möglichkeit, ihnen
+einen Wert zu geben. Die Initialisierung von Konstanten ist zwingend vorgeschrieben
+und wird vom Compiler überprüft.
+
+Die Initialisierung besteht aus der Angabe von
+
+- Datentyp
+- Zugriffsrecht ( #on("i")##on("b")#VAR#off("i")##off("b")# oder #on("i")##on("b")#CONST#off("i")##off("b")#)
+- Name des Datenobjekts
+- Operator #on("i")##on("b")#::#off("i")##off("b")# oder #on("i")##on("b")#:=#off("i")##off("b")#
+- Wert, den das Datenobjekt erhalten soll (Denoter, Ausdruck).
+
+____________________________________________________________________________
+ .......................... Beispiele: .........................
+ INT CONST gewuenschtes gehalt :: 12 000;
+ TEXT VAR zeile :: "";
+ REAL CONST pi :: 3.14159, zwei pi := 2.0 * pi;
+ BOOL VAR bereits sortiert :: TRUE;
+____________________________________________________________________________
+#page#
+
+2.4 Programmeinheiten
+
+Neben Deklarationen (Vereinbarungen) sind Programmeinheiten die Grundbestandteile
+von ELAN.
+
+
+Programmeinheiten können sein:
+
+#on("b")#- elementare Programmeinheiten #off("b")#
+ - Ausdruck
+ - Zuweisung
+ - Refinementanwendung
+ - Prozeduraufruf
+
+#on("b")#- zusammengesetzte Programmeinheiten #off("b")#
+ - Folge
+ - Abfrage
+ - Auswahl
+ - Wiederholung
+
+#on("b")#- abstrahierende Programmeinheiten #off("b")#
+ - Refinementbvereinbarung
+ - Prozedurvereinbarung
+ - Operatorvereinbarung
+ - Paketvereinbarung.
+#page#
+
+2.4.1 Elementare Programmeinheiten
+
+
+2.4.1.1 Ausdruck
+
+Ausdrücke sind eine Zusammenstellung von Datenobjekten (Denoter, VAR- oder
+CONST-Objekte) und Operatoren. Jeder korrekte Ausdruck liefert einen Wert. Der
+Typ des Ausdrucks wird bestimmt durch den Typ des Wertes, den der Ausdruck
+liefert.
+
+
+Operatoren
+
+Operatoren werden in ELAN durch ein oder zwei Sonderzeichen oder durch Groß­
+buchstaben als Schlüsselwort dargestellt (siehe 2.4.3.3).
+
+Als Operanden (also die Datenobjekte, auf die ein Operator "wirken" soll) dürfen
+VAR- und CONST-Datenobjekte, Denoter oder Ausdrücke verwendet werden. Typ
+der Operanden und des Resultats eines Operators werden in der Operatorvereinba­
+rung festgelegt (siehe 2.4.3.3).
+
+Man unterscheidet zwei Arten von Operatoren:
+
+#on("b")#- monadische Operatoren #off("b")#
+ Monadischen Operatoren haben nur einen Operanden, der rechts vom Operator­
+ zeichen geschrieben werden muß.
+
+ Beispiel:
+
+
+ - a
+ NOT x
+
+
+ Der '-' - Operator liefert den Wert von a mit umgekehrten Vorzeichen. a muß
+ dabei vom Datentyp INT oder REAL sein.
+ Der Operator 'NOT' realisiert die logische Negation. y muß vom Datentyp BOOL
+ sein.
+
+
+#on("b")#- dyadische Operatoren #off("b")#
+ Dyadische Operatoren haben zwei Operanden. Das Operatorzeichen steht zwi­
+ schen den beiden Operanden.
+
+ Beispiele:
+
+
+ a + b
+ a - b
+ a * b
+ a DIV b
+ a ** b
+ x < y
+ x <> y
+ x AND y
+ x OR y
+
+
+ In den ersten fünf Beispielen werden jeweils die Werte von zwei INT-Objekten a
+ und b addiert (Operatorzeichen: '+'), subtrahiert ('-'), multipliziert ('*'), dividiert
+ (ganzzahlige Division ohne Rest: 'DIV') und potenziert ('**').
+ Im sechsten und siebten Beispiel werden zwei BOOL-Werte x und y verglichen
+ und im achten und neunten Beispiel die logische Operation 'und' (Operator 'AND')
+ bzw. 'oder' (Operator 'OR') durchgeführt.
+
+
+Priorität von Operatoren
+
+Es ist erlaubt, einen Ausdruck wiederum als Operanden zu verwenden. Praktisch
+bedeutet dies, daß mehrere Operatoren und Datenobjekte zusammen in einem Aus­
+druck geschrieben werden dürfen.
+
+Beispiele:
+
+
+a + 3 - b * c
+- a * b
+
+
+Die Reihenfolge der Auswertung kann man durch Angabe von Klammern steuern.
+
+Beispiel:
+
+
+(a + b) * (a + b)
+
+
+Es wird jeweils erst 'a + b' ausgewertet und dann erst die Multiplikation durchge­
+führt. In ELAN ist es erlaubt, beliebig viel Klammernpaare zu verwenden (Regel: die
+innerste Klammer wird zuerst ausgeführt). Es ist sogar zulässig, Klammern zu ver­
+wenden, wo keine notwendig sind, denn überflüssige Klammernpaare werden überle­
+sen. Man muß jedoch beachten, daß Ausdrücke, und damit auch z.B. #on("b")#(a)#off("b")#, immer
+Accessrecht CONST haben.
+
+Beispiel:
+
+
+((a - b)) * 3 * ((c + d) * (c - d))
+
+
+Somit können beliebig komplizierte Ausdrücke formuliert werden.
+
+Um solche Ausdrücke einfacher zu behandeln und sie so ähnlich schreiben zu kön­
+nen, wie man es in der Mathematik gewohnt ist, wird in Programmiersprachen die
+Reihenfolge der Auswertung von Operatoren festgelegt. In ELAN wurden neun Ebe­
+nen, Prioritäten genannt, festgelegt:
+
+
+#on("bold")#Priorität Operatoren
+#off("bold")#
+
+ 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 erwähnten Operatoren in der Tabelle werden in der Beschreibung der Standard­
+prozeduren und -Operatoren besprochen).
+
+Operatoren mit der höchsten Priorität werden zuerst ausgeführt, dann die mit der
+nächst niedrigeren Priorität usw.. Operatoren mit gleicher Priorität werden von links
+nach rechts ausgeführt. Dadurch ergibt sich die gewohnte Abarbeitungsfolge 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 verwen­
+den.
+
+
+
+2.4.1.2 Zuweisung
+
+Ein spezieller Operator ist die Zuweisung.
+
+Form:
+
+
+Variable #on("i")##on("b")#:=#off("i")##off("b")# Wert
+
+
+Dieser Operator hat immer die geringste Priorität, wird also immer als letzter einer
+Anweisung ausgeführt. Die Zuweisung wird verwendet, um einer Variablen einen
+neuen Wert zu geben. Der Operator ':=' liefert kein Resultat (man sagt auch, er
+liefert keinen Wert) und verlangt als linken Operanden ein VAR-Datenobjekt, an den
+der Wert des rechten Operanden zugewiesen werden soll). Der Wert des linken Oper­
+anden wird also verändert. Der rechte Operand wird nur gelesen.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ a := b;
+
+____________________________________________________________________________
+
+
+Hier wird der Wert von 'b' der Variablen 'a' zugewiesen. Der vorher vorhandene Wert
+von 'a' geht dabei verloren. Man sagt auch, der Wert wird überschrieben.
+
+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 beachte
+dabei die Prioritäten der Operatoren '+' (Priorität 6) und ':=' (Prioritä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 Operato­
+ren hat.
+
+Oft kommt es vor, daß ein Objekt auf der linken und rechten Seite des Zuweisungs­
+operators erscheint, z.B. wenn ein Wert erhöht werden soll.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ a := a + 1;
+
+____________________________________________________________________________
+
+
+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 Datenobjekt unter­
+schiedliche Werte zu unterschiedlichen Zeitpunkten haben kann.
+
+
+
+2.4.1.3 Refinementanwendung
+
+In ELAN ist es möglich, Namen für Ausdrücke oder eine bzw. mehrere Anweisungen
+zu vergeben. Das Sprachelement, das diese Namensgebung ermöglicht, heißt Refi­
+nement. Die Ausführung eines solchen Namens heißt Refinementanwendung, die
+Namensgebung heißt Refinementvereinbarung (siehe 2.4.3.1). Die Ausdrücke oder
+Anweisungen bilden den Refinementrumpf. Ein Refinement kann man in einem Pro­
+gramm unter dem Refinementnamen ansprechen. Man kann sich die Ausführung so
+vorstellen, als würden der Refinementrumpf immer dort eingesetzt, wo der Name des
+Refinements als Operation benutzt wird.
+
+
+
+2.4.1.4 Prozeduraufruf
+
+Eine Prozedur ist eine Sammlung von Anweisungen und Daten, die zur Lösung einer
+bestimmten Aufgabe benötigt werden. Eine Prozedur wird in einer Prozedurvereinba­
+rung definiert (siehe 2.4.3.2). Eine solche Prozedur kann man in einem Programm
+unter einem Namen (eventuell unter Angabe von Parametern) ansprechen. Man
+spricht dann vom Aufruf einer Prozedur oder einer Prozeduranweisung.
+
+Formen des Prozeduraufrufs:
+
+- #on("b")#Prozeduren ohne Parameter#off("b")# werden durch den Prozedurnamen angesprochen.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ pause;
+
+____________________________________________________________________________
+
+
+ (Die Prozedur 'pause' wartet bis ein Zeichen eingegeben wird)
+
+
+- #on("b")#Prozeduren mit Parameter#off("b")# werden durch
+
+
+ Prozedurnamen #on("i")##on("b")#(#off("i")##off("b")# aktuelle Parameterliste #on("i")##on("b")#)#off("i")##off("b")#
+
+
+ aufgerufen. Eine Parameterliste ist entweder ein Datenobjekt oder mehrere durch
+ Kommata getrennte Datenobjekte.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ pause (10);
+
+____________________________________________________________________________
+
+
+ (Mit der Prozedur 'pause (INT CONST zeitgrenze)' kann für eine Zeitdauer von
+ 'zeitgrenze' in Zehntel-Sekunden gewartet werden. Die Wartezeit wird durch
+ Erreichen der Zeitgrenze oder durch Eingabe eines Zeichens abgebrochen)
+
+
+ Bei den aktuellen Parametern ist folgendes zu beachten:
+
+ a) Wird ein VAR-Parameter in der Definition der Prozedur vorgeschrieben, darf
+ kein Ausdruck als aktueller Parameter "übergeben" werden, weil an einen
+ Ausdruck nichts zugewiesen werden kann. Ausdrücke haben - wie bereits
+ erwähnt - das Accessrecht CONST.
+
+____________________________________________________________________________
+ ........................ Gegenbeispiel: .......................
+ TEXT VAR text1, text2;
+ text1 := "Dieses Beispiel ";
+ text2 := "Fehlermeldung";
+ insert char (text1 + text2, "liefert eine", 17);
+
+____________________________________________________________________________
+
+
+ (Die Prozedur 'insert char (TEXT VAR string, TEXT CONST char, INT CONST
+ pos)' fügt das Zeichen 'char' in den Text 'string' an der Position 'pos' ein)
+
+ 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.
+
+
+ In ELAN sind auch Prozeduren als Parameter erlaubt. Die Prozedur als aktueller
+ Parameter wird in der Parameterliste folgendermaßen angegeben:
+
+
+ Resultattyp #on("i")##on("b")#PROC#off("i")##off("b")# #on("i")##on("b")#(#off("i")##off("b")# virtuelle Parameterliste #on("i")##on("b")#)#off("i")##off("b")# Procname
+
+
+ Die Angabe des Resultattyps entfällt, wenn es sich nicht um eine wertliefernde
+ Prozedur handelt. Die virtuelle Parameterliste inklusive der Klammern entfällt, falls
+ die Prozedur keine Parameter hat. Die virtuelle Parameterliste beschreibt die
+ Parameter der Parameterprozedur. Es werden Datentyp und Zugriffsrecht eines
+ jeden Parameters angegeben, jedoch ohne Namen.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ wertetabelle (REAL PROC (REAL CONST) sin,
+ untergrenze, obergrenze, schrittweite);
+
+
+ (Die Prozedur 'sin' wird an die Prozedur 'wertetabelle' übergeben)
+
+____________________________________________________________________________
+
+
+2.4.2 Zusammengesetzte Programmeinheiten
+
+
+2.4.2.1 Folge
+
+Mehrere in einer bestimmten Reihenfolge auszuführende Anweisungen werden als
+Folge bezeichnet. In ELAN kann man eine oder mehrere Anweisungen in eine Pro­
+grammzeile schreiben oder eine Anweisung über mehrere Zeilen. Das setzt jedoch
+voraus, daß die Anweisungen voneinander getrennt werden. Die Trennung von Anwei­
+sungen erfolgt in ELAN durch das Trennsymbol Semikolon. Es bedeutet soviel wie:
+"führe die nächste Anweisung aus".
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ put ("mein");
+ put (1);
+ put (". Programm")
+
+____________________________________________________________________________
+
+
+(Die Prozedur 'put' gibt den als Parameter angegebenen Wert auf dem Ausgabegerät
+aus)
+
+
+
+2.4.2.2 Abfrage
+
+Mit Abfragen steuert man die bedingte Ausführung von Anweisungen. Abhängig von
+einer Bedingung wird in zwei verschiedene Programmabschnitte verzweigt.
+
+Der formale Aufbau einer Abfrage sieht folgendermaßen aus:
+
+
+#on("i")##on("b")#IF#off("i")##off("b")# Bedingung
+ #on("i")##on("b")#THEN#off("i")##off("b")# Abschnitt
+ #on("i")##on("b")#ELSE#off("i")##off("b")# Abschnitt
+#on("i")##on("b")#END IF#off("i")##off("b")#
+
+
+Der ELSE-Teil darf dabei auch fehlen. Anstelle von #on("i")##on("b")#END IF#off("i")##off("b")# darf auch die Abkürzung #on("i")##on("b")#FI#off("i")##off("b")# (IF von hinten gelesen) benutzt werden.
+
+In folgenden Beispielen wird der Absolutbetrag von 'a' ausgegeben:
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT VAR a;
+ get (a);
+ IF a < 0
+ THEN a := -a
+ END IF;
+ put (a)
+
+____________________________________________________________________________
+
+
+Die Umkehrung des Vorzeichens von a im THEN-Teil wird nur durchgeführt, wenn
+der BOOLesche Ausdruck ('a < 0') den Wert TRUE liefert. Liefert er den Wert
+FALSE, wird die Anweisung, die der bedingten Anweisung folgt (nach END IF), ausge­
+führt. Das obige Programm kann auch anders geschrieben werden:
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT VAR a;
+ get (a);
+ IF a < 0
+ THEN put (-a)
+ ELSE 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 ermöglicht es, 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.
+
+
+Abfragekette
+Bei Abfrageketten kann das ELIF-Konstrukt eingesetzt werden. (ELIF ist eine Zu­
+sammenziehung der Worte ELSE und IF).
+
+Anstatt
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ IF bedingung1
+ THEN aktion1
+ ELSE IF bedingung2
+ THEN aktion2
+ ELSE aktion3
+ END IF
+ END IF;
+
+____________________________________________________________________________
+
+
+kann man besser
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ IF bedingung1
+ THEN aktion1
+ ELIF bedingung2
+ THEN aktion2
+ ELSE aktion3
+ END IF;
+
+____________________________________________________________________________
+
+
+schreiben.
+
+
+
+2.4.2.3 Auswahl
+
+Die Auswahl wird benutzt, wenn alternative Anwendungen in Abhängikeit von Werten
+eines Datenobjekts ausgeführt werden sollen.
+
+Der formale Aufbau der Auswahl sieht folgendermaßen aus:
+
+
+#on("i")##on("b")#SELECT#off("i")##off("b")# INT-Ausdruck #on("i")##on("b")#OF#off("i")##off("b")#
+ #on("i")##on("b")#CASE#off("i")##off("b")# 1. Liste von INT-Denotern #on("i")##on("b")#:#off("i")##off("b")# Abschnitt
+ #on("i")##on("b")#CASE#off("i")##off("b")# 2. Liste von INT-Denotern #on("i")##on("b")#:#off("i")##off("b")# Abschnitt
+ .
+ .
+ .
+ #on("i")##on("b")#CASE#off("i")##off("b")# n. Liste von INT-Denotern #on("i")##on("b")#:#off("i")##off("b")# Abschnitt
+ #on("i")##on("b")#OTHERWISE#off("i")##off("b")# Abschnitt
+#on("i")##on("b")#END SELECT#off("i")##off("b")#
+
+
+Eine Liste von INT-Denotern besteht aus einem oder mehreren durch Kommata ge­
+trennten INT-Denotern. Der OTHERWISE-Teil darf auch fehlen. Man sollte ihn
+jedoch verwenden, um Fehlerfälle abzufangen.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ SELECT monat OF
+ CASE 2: IF schaltjahr
+ THEN tage := 29
+ ELSE tage := 28
+ END IF
+ CASE 4, 6, 9, 11: tage := 30
+ CASE 1, 3, 5, 7, 8, 10 ,12: tage := 31
+ OTHERWISE kein monat
+ END SELECT;
+
+____________________________________________________________________________
+
+
+(In diesem Programmausschnitt werden die Tage eines Monats bestimmt)
+
+
+
+2.4.2.4 Wertliefernde Abfrage und
+ wertliefernde Auswahl
+
+
+Soll eine Abfrage oder eine Auswahl einen Wert liefern, dann darf der ELSE- bzw.
+der OTHERWISE-Teil nicht fehlen und alle Zweige müssen einen Wert liefern.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ SELECT monat OF
+ CASE 2: IF schaltjahr
+ THEN 29
+ ELSE 28
+ END IF
+ CASE 4, 6, 9, 11: 30
+ CASE 1, 3, 5, 7, 8, 10 ,12: 31
+ OTHERWISE kein monat; 0
+ END SELECT;
+
+____________________________________________________________________________
+
+
+2.4.2.5 Wiederholung
+
+Die Wiederholung dient zur mehrfachen Ausführung von Anweisungen, meist in Ab­
+hängigkeit von einer Bedingung. Darum wird die Wiederholungsanweisung oft auch
+Schleife genannt und die in ihr enthaltenen Anweisungen Schleifenrumpf.
+
+Es gibt verschiedene Schleifentypen:
+
+- Endlosschleife
+- abweisende Schleife
+- nicht abweisende Schleife
+- Zählschleife.
+
+
+Endlosschleife
+Bei der Endlosschleife wird nicht spezifiziert, wann die Schleife beendet werden soll.
+
+Form:
+
+
+#on("i")##on("b")#REPEAT#off("i")##off("b")#
+ Abschnitt
+#on("i")##on("b")#END REPEAT#off("i")##off("b")#
+
+
+Anstelle von #on("i")##on("b")#REPEAT#off("i")##off("b")# darf die Abkürzung #on("i")##on("b")#REP#off("i")##off("b")# und anstelle von #on("i")##on("b")#END REPEAT#off("i")##off("b")#
+das Schlüsselwort #on("i")##on("b")#PER#off("i")##off("b")# (REP von hinten gelesen)
+benutzt werden.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ break;
+ REPEAT
+ fixpoint;
+ pause (18000)
+ END REPEAT
+
+____________________________________________________________________________
+
+
+Wird dieses Programm in einer Task im SYSUR-Zweig ausgeführt, so führt diese
+Task Fixpunkte im Abstand von 30 Minuten durch.
+
+
+
+Abweisende Schleife
+Bei der abweisenden Schleife wird die Abbruchbedingung an den Anfang der Schleife
+geschrieben.
+
+Form:
+
+
+#on("i")##on("b")#WHILE#off("i")##off("b")# Bedingung #on("i")##on("b")#REPEAT#off("i")##off("b")#
+ Abschnitt
+#on("i")##on("b")#END REPEAT#off("i")##off("b")#
+
+
+Bei jedem erneuten Durchlauf der Schleife wird überprüft, ob der BOOLesche Aus­
+druck den Wert TRUE liefert. Ist das nicht der Fall, wird die Bearbeitung mit der
+Anweisung fortgesetzt, die auf das Schleifenende folgt. Die Schleife wird abweisende
+Schleife genannt, weil der Schleifenrumpf nicht ausgeführt wird, wenn die Bedingung
+vor Eintritt in die Schleife bereits FALSE liefert.
+
+
+Nicht abweisende Schleife
+Anders verhält es sich bei der nicht abweisenden Schleife. Bei der nicht abweisenden
+Schleife wird die Abbruchbedingung an das Ende der Schleife geschrieben.
+
+Form:
+
+
+#on("i")##on("b")#REPEAT#off("i")##off("b")#
+ Abschnitt
+#on("i")##on("b")#UNTIL#off("i")##off("b")# Bedingung #on("i")##on("b")#END REPEAT#off("i")##off("b")#
+
+
+Hier wird der Schleifenrumpf auf jeden Fall einmal bearbeitet. Am Ende des Rumpfes
+wird die BOOLesche Bedingung abgefragt. Liefert sie 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 den beiden letztgenannten Arten der Wiederholungsanweisung 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.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ TEXT VAR wort, satz :: "";
+ REPEAT
+ get (wort);
+ satz CAT wort;
+ satz CAT " "
+ UNTIL wort = "." PER;
+
+____________________________________________________________________________
+
+
+Dises Programm liest solange Wörter ein und verbindet diese zu einem Satz, bis ein
+Punkt eingegeben wurde.
+
+
+
+Zählschleife
+Zählschleifen werden eingesetzt, wenn die genaue Anzahl der Schleifendurchläufe
+bekannt ist.
+
+Form:
+
+
+#on("i")##on("b")#FOR#off("i")##off("b")# Laufvariable #on("i")##on("b")#FROM#off("i")##off("b")# Anfangswert #on("i")##on("b")#UPTO#off("i")##off("b")# Endwert #on("i")##on("b")#REPEAT#off("i")##off("b")#
+ Abschnitt
+#on("i")##on("b")#END REPEAT#off("i")##off("b")#
+
+
+Bei Zählschleifen wird eine Laufvariable verwendet, die die INT-Werte von 'Anfangs­
+wert' bis 'Endwert' in Schritten von 1 durchläuft. 'Anfangswert' und 'Endwert' können
+beliebige INT-Ausdrücke sein. Diese Schleife zählt "aufwärts". Wird anstatt #on("i")##on("b")#UPTO#off("i")##off("b")#
+das Schlüsselwort #on("i")##on("b")#DOWNTO#off("i")##off("b")# verwendet, wird mit Schritten von 1 "abwärts" gezählt.
+
+Form:
+
+
+#on("i")##on("b")#FOR#off("i")##off("b")# Laufvariable #on("i")##on("b")#FROM#off("i")##off("b")# Endwert #on("i")##on("b")#DOWNTO#off("i")##off("b")# Anfangswert #on("i")##on("b")#REPEAT#off("i")##off("b")#
+ Abschnitt
+#on("i")##on("b")#END REPEAT#off("i")##off("b")#
+
+
+Die Laufvariable darf in der Schleife nicht verändert werden. Nach dem normalen
+Schleifenende ist der Wert der Laufvariablen nicht definiert.
+
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT VAR summe :: 0, i;
+ FOR i FROM 1 UPTO 100 REPEAT
+ summe INCR i
+ END REPEAT
+
+____________________________________________________________________________
+
+
+Dieses Programm berechnet die Summe der natürlichen Zahlen von 1 bis 100.
+
+
+Die verschiedenen Schleifenarten können kombiniert werden:
+
+
+#on("i")##on("b")#FOR#off("i")##off("b")# Laufvariable #on("i")##on("b")#FROM#off("i")##off("b")# Anfangswert #on("i")##on("b")#UPTO#off("i")##off("b")# Endwert
+#on("i")##on("b")#WHILE#off("i")##off("b")# Bedingung #on("i")##on("b")#REPEAT#off("i")##off("b")#
+ Abschnitt
+#on("i")##on("b")#END REPEAT#off("i")##off("b")#
+
+
+
+#on("i")##on("b")#FOR#off("i")##off("b")# Laufvariable #on("i")##on("b")#FROM#off("i")##off("b")# Anfangswert #on("i")##on("b")#UPTO#off("i")##off("b")# Endwert #on("i")##on("b")#REPEAT#off("i")##off("b")#
+ Abschnitt
+#on("i")##on("b")#UNTIL#off("i")##off("b")# Bedingung #on("i")##on("b")#END REPEAT#off("i")##off("b")#
+
+
+
+
+
+#on("i")##on("b")#WHILE#off("i")##off("b")# Bedingung #on("i")##on("b")#REPEAT#off("i")##off("b")#
+ Abschnitt
+#on("i")##on("b")#UNTIL#off("i")##off("b")# Bedingung #on("i")##on("b")#END REPEAT#off("i")##off("b")#
+
+#page#
+
+2.4.3 Abstrahierende Programmeinheiten
+
+
+2.4.3.1 Refinementvereinbarung
+
+In ELAN ist es möglich, Namen für Ausdrücke oder eine bzw. mehrere Anweisungen
+zu vergeben. Das Sprachelement, das diese Namensgebung ermöglicht, heißt Refi­
+nement. Die Ausführung eines solchen Namens heißt Refinementanwendung (siehe
+2.4.1.3), die Namensgebung heißt Refinementvereinbarung. Die Ausdrücke oder
+Anweisungen bilden den Refinementrumpf.
+
+Werden in einem Programm Refinements benutzt, dann wird der Programmteil bis
+zum ersten Refinement durch einen Punkt abgeschlossen. Die Refinementvereinba­
+rung sieht folgendermaßen aus:
+
+
+Name #on("i")##on("b")#:#off("i")##off("b")#
+ Abschnitt #on("i")##on("b")#.#off("i")##off("b")#
+
+
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ 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).
+
+____________________________________________________________________________
+
+
+Für den Namen 'einlesen von a und b' werden die Anweisungen 'get (a); get (b)' vom
+ELAN-Compiler eingesetzt. Man kann also die ersten vier Zeilen des Programms als
+eigentliches Programm ansehen, wobei die Namen durch die betreffenden Anwei­
+sungen ersetzt werden. Ein Refinement hat also keinen eigenen Datenbereich, d.h.
+Vereinbarungen, die in Refinements gemacht werden, gelten auch außerhalb des
+Refinements.
+
+
+
+Vorteile der Refinementanwendung
+Durch die sinnvolle Verwendung von Refinements wird ein Programm im Programm
+und nicht in einer separaten Beschreibung dokumentiert. Weiterhin kann ein Pro­
+gramm "von oben nach unten" ("top down") entwickelt werden: Das obige - zuge­
+geben einfache - Beispielprogramm wurde in drei Teile zerlegt und diese durch
+Namen beschrieben. Bei der Beschreibung von Aktionen durch Namen wird gesagt
+was gemacht werden soll. Es wird noch nicht beschrieben wie, denn auf dieser Stufe
+der Programmentwicklung braucht man sich um die Realisierung der Refinements
+(noch) keine Sorgen zu machen. Das erfolgt erst, wenn das Refinement programmiert
+werden muß. Dabei können wiederum Refinements verwendet werden usw., bis man
+auf eine Ebene "heruntergestiegen" ist, bei der eine (jetzt: Teil-) Problemlösung sehr
+einfach ist und man sie direkt hinschreiben kann. Man beschäftigt sich 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.
+Refinements ermöglichen:
+
+- "top down" - Programmierung
+- Strukturierung von Programmen und damit effiziente Fehlersuche und gute Wart­
+ barkeit
+- Dokumentation im Programmtext.
+
+
+Wertliefernde Refinements
+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ß die letzte Anwei­
+sung des Refinements einen Wert liefert.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT VAR a :: 1, b :: 2, c :: 3;
+ put (resultat).
+
+ resultat:
+ (a * b + c) ** 3.
+
+____________________________________________________________________________
+
+
+Man kann auch ein wertlieferndes Refinement mit mehreren Anweisungen schrei­
+ben.
+
+Allgemeine Regel:
+Die letzte Anweisung eines Refinements bestimmt, ob es einen Wert liefert - und
+wenn ja, von welchen Datentyp.
+
+
+
+2.4.3.2 Prozedurvereinbarung
+
+Eine Prozedur ist eine Sammlung von Anweisungen und Daten, die zur Lösung einer
+bestimmten Aufgabe benötigt werden.
+
+Der formale Aufbau einer Prozedur sieht folgendermaßen aus:
+
+
+#on("i")##on("b")#PROC#off("i")##off("b")# Prozedurname #on("i")##on("b")#:#off("i")##off("b")#
+ Prozedurrumpf
+#on("i")##on("b")#END PROC#off("i")##off("b")# Prozedurname
+
+
+Der Prozedurrumpf kann Deklarationen, Anweisungen und Refinements enthalten.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ PROC loesche bildschirm ab aktueller cursorposition:
+ out (""4"")
+ END PROC loesche bildschirm ab aktueller cursorposition
+
+____________________________________________________________________________
+
+
+Verwendung von 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)
+- Datenobjekte nur innerhalb eines Programmteils benötigt werden und diese nicht
+ von dem gesamten Programm angesprochen werden sollen.
+
+In den folgenden Programmfragmenten werden zwei Werte vertauscht. In der ersten
+Lösung wird ein Refinement, in der zweiten eine Prozedur verwandt.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ IF a > b
+ THEN vertausche a und b
+ END IF;
+ put (a);
+ put (b);
+ vertausche a und b.
+
+ vertausche a und b:
+ INT CONST x :: a;
+ a := b;
+ b := x.
+
+____________________________________________________________________________
+
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ PROC vertausche a und b:
+ INT CONST x :: a;
+ a := b;
+ b := x
+ END PROC vertausche a und b;
+
+ IF a > b
+ THEN vertausche a und b
+ END IF;
+ put (a);
+ put (b);
+ vertausche a und b;
+
+____________________________________________________________________________
+
+
+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) ein­
+ gesetzt, d.h. der Code ist zweimal vorhanden. Die Prozedur dagegen ist vom Code
+ nur einmal vorhanden, wird aber zweimal - durch das Aufführen des Prozedur­
+ namens - aufgerufen.
+
+2) Die Variable 'x' ist in der ersten Programmversion während des gesamten Ablauf
+ des Programms vorhanden, d.h. ihr Speicherplatz ist während dieser Zeit belegt.
+ 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 vor­
+ handen, sein Speicherplatz wird danach freigegeben. Solche Datenobjekte, die nur
+ kurzfristig Speicher belegen, werden dynamische Datenobjekte genannt.
+
+ Prozeduren sind also ein Mittel, um die Speicherbelegung zu beeinflussen.
+
+3) Da Refinements keinen eigenen Datenbereich haben, kann die Variable 'x' in der
+ ersten 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, es ist also ein lokales
+ Datenobjekt der Prozedur. Innerhalb der Prozedur dürfen globale Datenobjekte
+ (also Objekte, die außerhalb von Prozeduren deklariert wurden) auch angespro­
+ chen werden.
+
+ Eine Prozedur in ELAN bildet im Gegensatz zu Refinements einen eigenen Gültig­
+ keitsbereich hinsichtlich Datenobjekten und Refinements, die innerhalb der Pro­
+ zedur deklariert werden. Prozeduren sind somit ein Mittel, um die in ihr dekla­
+ rierten Datenobjekte hinsichtlich der Ansprechbarkeit nach Außen "abzuschotten".
+
+
+
+Prozeduren mit Parametern
+Prozeduren mit Parametern erlauben es, gleiche Anweisungen mit unterschiedlichen
+Datenobjekten auszuführen.
+
+Form:
+
+
+#on("i")##on("b")#PROC#off("i")##off("b")# Prozedurname #on("i")##on("b")#(#off("i")##off("b")# formale Parameterliste #on("i")##on("b")#)#off("i")##off("b")# #on("i")##on("b")#:#off("i")##off("b")#
+ Prozedurrumpf
+#on("i")##on("b")#END PROC#off("i")##off("b")# Prozedurnamen
+
+
+Die Parameterliste besteht aus einem oder mehreren durch Kommata getrennten Para­
+metern. Ein Parameter wird mit Datentyp, Accessrecht und Namen angegeben.
+Ähnlich wie bei der Datendeklaration braucht man für aufeinanderfolgende Parameter
+mit gleichem Datentyp und gleichem Accessrecht die Attribute nur einmal anzugeben.
+Parameter mit Accessrecht #on("i")##on("b")#CONST#off("i")##off("b")# sind Eingabeparameter, Parameter mit Access­
+recht #on("i")##on("b")#VAR#off("i")##off("b")# realisieren Ein-/Ausgabeparameter.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ 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 Parameter
+genannt. Sie stehen als Platzhalter für die bei einem Prozeduraufruf einzusetzenden
+aktuellen Parameter (in obigen Beispiel die Datenobjekte 'eins', 'zwei' und 'drei').
+
+
+
+Prozeduren als Parameter
+Es ist auch möglich, Prozeduren als Parameter zu definieren.
+
+Eine Prozedur als Parameter wird folgendermaßen in der Parameterliste spezifiziert:
+
+Resultattyp #on("i")##on("b")#PROC#off("i")##off("b")# #on("i")##on("b")#(#off("i")##off("b")# virtuelle Parameterliste #on("i")##on("b")#)#off("i")##off("b")# Prozedurname
+
+
+Die Angabe des Resultattyps entfällt, wenn es sich nicht um eine wertliefernde Proze­
+dur handelt. Die virtuelle Parameterliste inklusive der Klammern entfällt, falls die
+Prozedur keine Parameter hat. Die virtuelle Parameterliste beschreibt die Parame­
+ter der Parameterprozedur. Es werden Datentyp und Zugriffsrecht eines jeden Para­
+meters angegeben, jedoch ohne Namen.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ PROC wertetabelle (REAL PROC (REAL CONST) funktion,
+ REAL CONST untergrenze, obergrenze,
+ schrittweite):
+
+ REAL VAR wert;
+ putline ("W E R T E T A B E L L E");
+ putline ("-----------------------");
+ wert := untergrenze;
+ REPEAT
+ put (text (wert, 10, 5));
+ put (text (funktion (wert), 10, 5));
+ line;
+ wert INCR schrittweite
+ UNTIL wert > obergrenze PER
+
+ END PROC wertetabelle;
+
+ (* Prozeduraufruf: *)
+ wertetabelle (REAL PROC (REAL CONST) sin, 0.0, pi, 0.2)
+
+____________________________________________________________________________
+
+
+Wertliefernde Prozeduren
+Eine wertliefernde Prozedur sieht folgendermaßen aus:
+
+
+Resultattyp #on("i")##on("b")#PROC#off("i")##off("b")# Prozedurname #on("i")##on("b")#(#off("i")##off("b")# formale Parameterliste #on("i")##on("b")#)#off("i")##off("b")# #on("i")##on("b")#:#off("i")##off("b")#
+ wertliefernder Prozedurrumpf
+#on("i")##on("b")#END PROC#off("i")##off("b")# Prozedurnamen
+
+
+
+Die Parameterliste inklusive Klammerung kann fehlen. Der Prozedurrumpf muß einen
+Wert mit dem in Resultattyp angegeben Datentyp liefern.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT PROC max (INT CONST a, b):
+ IF a > b
+ THEN a
+ ELSE b
+ END IF
+ END PROC max;
+
+ put (max (3, 4))
+
+____________________________________________________________________________
+
+
+(In diesem Beispiel wird das Maximum von 'a' und 'b' ermittelt und ausgegeben)
+
+#page#
+
+2.4.3.3 Operatorvereinbarung
+
+Operatoren können in ELAN ähnlich wie Prozeduren definiert werden. Operatoren
+müssen einen und können maximal zwei Operatoren besitzen (monadische und dyadi­
+sche Operatoren).
+
+Form:
+
+
+Resultattyp #on("i")##on("b")#OP#off("i")##off("b")# Opname #on("i")##on("b")#(#off("i")##off("b")# ein oder zwei Parameter #on("i")##on("b")#)#off("i")##off("b")# #on("i")##on("b")#:#off("i")##off("b")#
+ Operatorrumpf
+#on("i")##on("b")#END OP#off("i")##off("b")# Opname
+
+
+Der Resultattyp wird nur bei wertliefernden Operatoren angegeben.
+
+Als Operatornamen sind erlaubt:
+
+- ein Sonderzeichen, sofern es nicht als Trennzeichen benutzt wird:
+ ! $ % & ' * + - / < = > ? § ^ ' ~
+- eine Kombination von zwei Sonderzeichen. Diese Kombination muß jedoch bereits
+ in ELAN existieren:
+ := <= >= <> **
+- ein Schlüsselwort (siehe 2.2.1).
+
+
+
+Vereinbarung eines monadischen Operators
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT OP SIGN (REAL CONST argument):
+ IF argument < 0.0 THEN -1
+ ELIF argument = 0.0 THEN 0
+ ELSE 1
+ FI
+ END OP SIGN
+
+____________________________________________________________________________
+
+
+(Der Operator 'SIGN' liefert abhängig vom Vorzeichen des übergebenen Wertes den
+INT-Wert -1, 0 oder 1)
+
+
+
+Vereinbarung eines dyadischen Operators
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ TEXT OP * (INT CONST anzahl, TEXT CONST t):
+ INT VAR zaehler :: anzahl;
+ TEXT VAR ergebnis :: "";
+ WHILE zaehler > 0 REP
+ ergebnis := ergebnis + t;
+ zaehler := zaehler - 1
+ END REP;
+ ergebnis
+ END OP *;
+
+____________________________________________________________________________
+
+
+(Der Operator '*' verkettet 'anzahl'- mal den Text 't')
+
+
+
+2.4.3.4 Paketvereinbarung
+
+Pakete sind in ELAN eine Zusammenfassung von Datenobjekten, Prozeduren, Opera­
+toren und Datentypen. Diese bilden den Paketrumpf. Elemente eines Pakets (Prozedu­
+ren, Operatoren, Datentypen) können außerhalb des Pakets nur angesprochen werden,
+wenn sie in der Schnittstelle des Pakets, die auch "interface" genannt wird, aufge­
+führt werden. Mit anderen Worten: es können alle Elemente eines Pakets von außen
+nicht angesprochen werden, sofern sie nicht über die Schnittstelle "nach außen ge­
+reicht" werden. Pakete können separat übersetzt werden, so daß der "Zusammen­
+bau" eines umfangreichen Programms aus mehreren Paketen möglich ist.
+
+Der formale Aufbau eines Pakets sieht folgendermaßen aus:
+
+
+#on("i")##on("b")#PACKET#off("i")##off("b")# Paketname #on("i")##on("b")#DEFINES#off("i")##off("b")# Schnittstelle #on("i")##on("b")#:#off("i")##off("b")#
+ Paketrumpf
+#on("i")##on("b")#END PACKET#off("i")##off("b")# Paketname
+
+
+In der Schnittstelle werden Prozeduren und Operatoren nur mit ihrem Namen, durch
+Kommata getrennt, angegeben. Weiterhin können Datentypen und mit CONST verein­
+barte Datenobjekte in der Schnittstelle aufgeführt werden, aber keine VAR-Datenob­
+jekte, weil diese sonst über Paket-Grenzen hinweg verändert werden könnten.
+
+Im Gegensatz zu einer Prozedur kann ein PACKET nicht aufgerufen werden (nur die
+Elemente der Schnittstelle können benutzt werden).
+
+Pakete werden zu folgenden Zwecken eingesetzt:
+
+- Spracherweiterung
+- Schutz vor fehlerhaftem Zugriff auf Datenobjekte
+- Realisierung von abstrakten Datentypen.
+
+
+
+Spracherweiterung
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ 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 Paket, das eine Tausch-Prozedur für INT-Datenobjekte bereitstellt. Das
+PACKET kann übersetzt und dem ELAN-Compiler bekannt gemacht werden
+(EUMEL: "insertieren"). Ist das geschehen, kann man 'swap' wie alle anderen Proze­
+duren (z.B. 'put', 'get') in einem Programm verwenden. Tatsächlich werden die mei­
+sten 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 Operato­
+ren in jedem ELAN-System vorhanden sein müssen. Solche Pakete werden Stan­
+dard-Pakete genannt. Jeder Installation - aber auch jedem Benutzer - steht es
+jedoch frei, zu den Standard-Paketen zusätzliche Pakete dem Compiler bekannzu­
+geben, und damit den ELAN-Sprachumfang zu erweitern.
+
+
+
+Schutz vor fehlerhaftem Zugriff auf Datenobjekte
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ PACKET stack handling DEFINES push, pop, init stack:
+
+ LET max = 1000;
+ ROW max INT VAR stack; (* siehe Kapitel Reihung, 2.6.1. *)
+ 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;
+
+____________________________________________________________________________
+
+
+Dieses Packet realisiert einen Stack. Den Stack kann man über die Prozeduren 'init
+stack', 'push' und 'pop' benutzen.
+#page#
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ 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.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ 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 Verwendung von
+Programmen und Datenobjekten. Wichtig ist weiterhin, daß die Realisierung des
+Stacks ohne weiteres geändert werden kann, ohne daß Benutzerprogramme im 'main
+packet' geändert werden müssen, sofern die Schnittstelle nicht verändert wird. Bei­
+spielsweise kann man sich entschließen, den Stack nicht durch eine Reihung, son­
+dern durch eine Struktur zu realisieren. Davon bleibt ein Benutzerprogramm unbe­
+rührt.
+
+
+
+Realisierung von abstrakten Datentypen
+Der Vollständigkeit halber wird folgendes Beispiel hier gezeigt. Wie neue Datentypen
+definiert werden, wird in Kapitel 2.7.1. erklärt.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ 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.
+
+
+
+2.4.4 Terminatoren für Refinements,
+ Prozeduren und Operatoren
+
+
+Das LEAVE-Konstrukt wird verwendet, um eine benannte Anweisung (Refinement,
+Prozedur oder Operator) vorzeitig zu verlassen. Es ist auch möglich, geschachtelte
+Refinements zu verlassen.
+
+Form:
+
+#on("i")##on("b")#LEAVE#off("i")##off("b")# Name
+
+
+Durch eine (optionale) WITH-Angabe kann auch eine wertliefernde benannte Anwei­
+sung verlassen werden.
+
+Form:
+
+#on("i")##on("b")#LEAVE#off("i")##off("b")# Name #on("i")##on("b")#WITH#off("i")##off("b")# Ausdruck
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT OP ** (INT CONST basis, exp):
+ IF exp = 0
+ THEN LEAVE ** WITH 1
+ ELIF exp < 0
+ THEN LEAVE ** WITH 0
+ FI;
+
+ INT VAR zaehler, ergebnis;
+ ergebnis := basis;
+ FOR zaehler FROM 2 UPTO exp REP
+ ergebnis := ergebnis * basis
+ PER;
+ ergebnis
+ END OP **
+
+____________________________________________________________________________
+
+
+(Diese Operation realisiert die Exponentiation für INT-Werte)
+
+
+
+2.4.5 Generizität von Prozeduren
+ und Operatoren
+
+
+In ELAN ist es möglich, unterschiedlichen Prozeduren bzw. Operatoren gleiche
+Namen zu geben. Solche Prozeduren (Operatoren) werden generische Prozeduren
+(Operatoren) genannt. Die Identifizierung erfolgt durch Anzahl, Reihenfolge und Daten­
+typ der Parameter (Operanden).
+
+Deshalb werden Prozeduren und Operatoren unter Angabe des Prozedur- bzw. des
+Operatorkopfes dokumentiert.
+
+Beispiele:
+
+
+INT OP MOD (INT CONST l, r)
+REAL OP MOD (REAL CONST l, r)
+
+
+Der MOD-Operator liefert den Rest einer Division. Er ist sowohl für INT- wie auch
+für REAL-Datenobjekte definiert.
+
+
+
+PROC put (INT CONST wert)
+PROC put (REAL CONST wert)
+PROC put (TEXT CONST wert)
+
+
+Die put-Prozedur ist für INT-, REAL- und TEXT-Datenobjekte definiert.
+
+
+
+Priorität von generischen Operatoren
+Bei der Neudefinition von Operatoren kann man bereits benutzte Sonderzeichen oder
+Schlüsselwörter benutzen. In diesem Fall bekommt der neudefinierte Operator die
+gleiche Priorität wie der bereits vorhandene Operator.
+
+
+
+2.4.6 Rekursive Prozeduren
+ und Operatoren
+
+
+Alle Prozeduren und Operatoren dürfen in ELAN rekursiv sein.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT PROC fakultaet (INT CONST n):
+ IF n > 0
+ THEN fakultaet (n-1) * n
+ ELSE 1
+ END IF
+ END PROC fakultaet
+
+____________________________________________________________________________
+
+
+Die Fakultätsfunktion ist kein gutes Beispiel für eine Rekursion, denn das Programm
+kann leicht in eine iterative Version umgewandelt werden:
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ 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 dem Beispiel der Ackermann-Funktion:
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ 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
+
+____________________________________________________________________________
+
+
+Das eigentliche Einsatzgebiet von rekursiven Algorithmen liegt aber bei den 'back­
+track'-Verfahren. Diese werden eingesetzt, wenn eine exakte algorithmische Lösung
+nicht bekannt ist oder nicht gefunden werden kann und man verschiedene Versuche
+machen muß, um zu einem Ziel (oder Lösung) zu gelangen.
+
diff --git a/doc/programmer-manual/1.8.7/doc/programmierhandbuch.2b b/doc/programmer-manual/1.8.7/doc/programmierhandbuch.2b
new file mode 100644
index 0000000..c2103ba
--- /dev/null
+++ b/doc/programmer-manual/1.8.7/doc/programmierhandbuch.2b
@@ -0,0 +1,1395 @@
+#headandbottom("52","EUMEL-Benutzerhandbuch","TEIL 2 : ELAN","2")#
+#pagenr ("%", 52)##setcount(1)##block##pageblock#
+#headeven#
+#center#EUMEL-Benutzerhandbuch
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#TEIL 2 : ELAN
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+2 - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#2 - %
+#end#
+
+
+2.5 Programmstruktur
+
+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.
+Dies soll eine Empfehlung sein, in welcher Reihenfolge die Elemente eines PACKETs
+geschrieben werden sollen:
+
+Ein "main packet" kann aus folgenden Elementen bestehen:
+
+a) Deklarationen und Anweisungen. Diese müssen nicht in einer bestimmten Reihen­
+ folge 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 Pro­
+ grammierpraxis, die meisten Deklarationen an den Anfang eines Programms oder
+ Programmteils (Refinement, Prozedur) zu plazieren.
+
+ <Deklarationen> ;
+ <Anweisungen>
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT VAR erste zahl, zweite zahl;
+
+ page;
+ put ("erste Zahl = "); get (erste zahl);
+ put ("zweite Zahl ="); get (zweite zahl)
+
+____________________________________________________________________________
+
+
+b) Deklarationen, Refinements und Anweisungen. In diesem Fall ist es notwendig, die
+ Refinements hintereinander zu plazieren. Refinement-Aufrufe und/oder
+ Anweisungen sollten textuell vorher erscheinen.
+
+ <Deklarationen> ;
+ <Refinement-Aufrufe und/oder Anweisungen> .
+ <Refinements>
+
+ Innerhalb der Refinements sind Anweisungen und/oder Deklarationen möglich.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT VAR erste zahl, zweite zahl;
+
+ loesche bildschirm;
+ lies zwei zahlen ein.
+
+ loesche bildschirm:
+ page.
+
+ lies zwei zahlen ein:
+ put ("erste Zahl = "); get (erste zahl);
+ put ("zweite Zahl ="); get (zweite zahl).
+
+____________________________________________________________________________
+
+
+c) Deklarationen, Prozeduren und Anweisungen. Werden Prozeduren vereinbart,
+ sollte man sie nach den Deklarationen plazieren. Danach sollten die Anweisungen
+ folgen:
+
+ <Deklarationen> ;
+ <Prozeduren> ;
+ <Anweisungen>
+
+ Mehrere 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 wieder­
+ um 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.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT VAR erste zahl, zweite zahl;
+
+ PROC vertausche (INT VAR a, b):
+ INT VAR x;
+
+ x := a;
+ a := b;
+ b := x
+ END PROC vertausche;
+
+ put ("erste Zahl = "); get (erste zahl);
+ put ("zweite Zahl ="); get (zweite zahl);
+ IF erste zahl > zweite zahl
+ THEN vertausche (erste zahl, zweite zahl)
+ FI
+
+____________________________________________________________________________
+
+
+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 Refine­
+ ments). In PACKET-Refinements dürfen natürlich keine Datenobjekte verwandt
+ werden, die lokal zu einer Prozedur sind.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ INT VAR erste zahl, zweite zahl;
+
+ PROC vertausche (INT VAR a, b):
+ INT VAR x;
+
+ x := a;
+ a := b;
+ b := x
+ END PROC vertausche;
+
+ loesche bildschirm;
+ lies zwei zahlen ein;
+ ordne die zahlen.
+
+ loesche bildschirm:
+ page.
+
+ lies zwei zahlen ein:
+ put ("erste Zahl = "); get (erste zahl);
+ put ("zweite Zahl ="); get (zweite zahl).
+
+ ordne die zahlen:
+ IF erste zahl > zweite zahl
+ THEN vertausche (erste zahl, zweite zahl)
+ FI
+
+____________________________________________________________________________
+#page#
+
+2.6 Zusammengesetzte Datentypen
+
+In ELAN gibt es die Möglichkeit, gleichartige oder ungleichartige Datenobjekte zu
+einem Objekt zusammenzufassen.
+
+
+2.6.1 Reihung
+
+Die Zusammenfassung gleichartiger Datenobjekte, wird in ELAN eine Reihung (ROW)
+genannt. Die einzelnen Objekte einer Reihung werden Elemente genannt.
+
+Eine Reihung wird folgendermaßen deklariert:
+
+- Schlüsselwort #on("i")##on("b")#ROW#off("i")##off("b")#
+- Anzahl der zusammengefaßten Elemente
+ (INT-Denoter oder durch LET definierter Name)
+- Datentyp der Elemente
+- Zugriffsrecht ( #on("i")##on("b")#VAR#off("i")##off("b")# oder #on("i")##on("b")#CONST#off("i")##off("b")# )
+- Name der Reihung.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ ROW 10 INT VAR feld
+
+____________________________________________________________________________
+
+
+Im obigen Beispiel wird eine Reihung von 10 INT-Elementen deklariert. ROW 10 INT
+ist ein (neuer, von den elementaren unterschiedlicher) Datentyp, für den keine Opera­
+tionen definiert sind, außer der Zuweisung. Das Accessrecht (VAR im obigen Bei­
+spiel) 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 sehr schnell
+einsichtig, wenn man bedenkt, 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 unter­
+schiedliche Operationen definiert. Man müßte nun für jeden dieser zusammengesetz­
+ten 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 vorgege­
+bene Operationen auf zusammengesetzte Datentypen gibt.
+
+Zugegebenermaßen könnte man mit solchen Datentypen, die nur über eine Operation
+verfügen (Zuweisung), nicht sehr viel anfangen, wenn es nicht eine weitere vorgege­
+bene Operation gäbe, die Subskription. Sie erlaubt es, auf die Elemente einer Reih­
+ung zuzugreifen und den Datentyp der Elemente "aufzudecken".
+
+Form:
+
+Rowname #on("i")##on("b")#[#off("i")##off("b")# Indexwert #on("i")##on("b")#]#off("i")##off("b")#
+
+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
+oder Index (in obigem Beispiel '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 überall da verwendet
+werden, wo ein entsprechender Datentyp benötigt wird (Ausnahme: nicht als Schlei­
+fenvariable).
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ 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
+
+____________________________________________________________________________
+
+
+In diesen Beispielen werden Reihungen als Parameter benutzt.
+
+Diese beiden Prozeduren werden im folgenden Beispiel benutzt um 10 Werte einzu­
+lesen und die Summe zu berechnen:
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ 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).
+
+____________________________________________________________________________
+
+
+Da es möglich ist, von jedem Datentyp eine Reihung zu bilden, kann man natürlich
+auch von einer Reihung eine Reihung bilden:
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ 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 zuzugreifen:
+
+
+matrix [3]
+
+
+liefert ein Datenobjekt mit dem Datentyp ROW 10 INT.
+
+Subskribiert man jedoch 'matrix' nochmals, so erhält man ein INT:
+
+
+matrix [2] [8]
+
+
+(jede Subskription "schält" von Außen ein ROW vom Datentyp ab).
+#page#
+
+2.6.2 Struktur
+
+Strukturen sind Datenverbunde wie Reihungen, aber die Komponenten können unglei­
+chartige Datentypen haben. Die Komponenten von Strukturen heißen Felder (Reihun­
+gen: 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ß.
+
+Die Deklaration einer Struktur sieht folgendermaßen aus:
+
+- Schlüsselwort #schl ("STRUCT#off("i")##off("b")#
+- unterschiedliche Datenobjekte in Klammern. Die Datenobjekte werden mit Datentyp und Namen angegeben
+- Zugriffsrecht ( #on("i")##on("b")#VAR#off("i")##off("b")# oder #on("i")##on("b")#CONST#off("i")##off("b")# )
+- Name der Struktur.
+
+____________________________________________________________________________
+ ........................... 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.
+
+Die Selektion hat folgende Form:
+
+Objektname #on("i")##on("b")#.#off("i")##off("b")# Feldname
+
+Beispiele:
+
+
+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:
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ STRUCT (TEXT produkt name, INT artikel nr) VAR erzeugnis
+
+____________________________________________________________________________
+
+
+Die obige Struktur ist ein anderer Datentyp als im ersten Beispiel dieses Abschnitts,
+da die Namen der Felder zur Unterscheidung hinzugezogen werden. Für Strukturen -
+genauso wie bei Reihungen - kann man sich neue Operationen definieren.
+
+Im folgenden Programm werden eine Struktur, die Personen beschreibt, die Prozedu­
+ren 'put', 'get' und der dyadische Operator HEIRATET definiert. Anschließend werden
+drei Paare verHEIRATET.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ 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;
+
+____________________________________________________________________________
+
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ 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 Reihen­
+folge vorzunehmen, wie die Datentypen aufgebaut wurden (von außen nach innen).
+#page#
+
+2.6.3 LET-Konstrukt für zusammengesetzte Datentypen
+
+
+Die Verwendung von Strukturen oder auch Reihungen kann manchmal schreibauf­
+wendig sein. Mit dem LET-Konstrukt darf man Datentypen 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.
+
+Form:
+
+#on("i")##on("b")#LET#off("i")##off("b")# Name #on("i")##on("b")#=#off("i")##off("b")# Datentyp
+
+Der Name darf nur aus Großbuchstaben (ohne Blanks) bestehen.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ 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 wird, kann stattdessen der Name
+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 später
+erklärt werden, nicht mehr der Fall ist).
+
+Neben der Funktion der Abkürzung von Datentypen kann das LET-Konstrukt auch
+zur Namensgebung für Denoter verwandt werden (siehe 2.3.1.2).
+
+
+
+2.6.4 Denoter für zusammengesetzte
+ Datentypen (Konstruktor)
+
+
+Oft ist es notwendig, Datenverbunden Werte zuzuweisen (z.B.: bei der Initialisierung).
+Dies 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
+
+____________________________________________________________________________
+
+
+Eine andere Möglichkeit für die Wertbesetzung von Datenverbunden ist der Konstruk­
+tor:
+
+Form:
+
+Datentyp #on("i")##on("b")#:#off("i")##off("b")# #on("i")##on("b")#(#off("i")##off("b")# Wertliste #on("i")##on("b")#)#off("i")##off("b")#
+
+In der Wertliste wird für jede Komponente des Datentyps, durch Kommata getrennt,
+ein Wert aufgeführt. Besteht eine der Komponenten wiederum aus einem Datenver­
+bund, muß innerhalb des Konstruktors wiederum ein Konstruktor eingesetzt werden.
+
+____________________________________________________________________________
+ ........................... 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 Datenverbundes
+in einem Programm zu notieren.
+
+Konstruktoren sind natürlich für Reihungen auch möglich:
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ ROW 7 INT VAR feld;
+ feld := ROW 7 INT : ( 1, 2, 3, 4, 5, 6, 7);
+____________________________________________________________________________
+#page#
+
+2.7 Abstrakte Datentypen
+
+
+2.7.1 Definition neuer Datentypen
+
+Im Gegensatz zur LET-Vereinbarung für Datentypen, bei der lediglich ein neuer
+Name für einen bereits vorhandenen Datentyp eingeführt wird 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-Verein­
+barung ein gänzlich neuer Datentyp eingeführt.
+
+Form:
+
+#on("i")##on("b")#TYPE#off("i")##off("b")# Name #on("i")##on("b")#=#off("i")##off("b")# Feinstruktur
+
+Der Name darf nur aus Großbuchstaben (ohne Blanks) bestehen. Die Feinstruktur
+(konkreter Typ, Realisierung des Datentyps) kann jeder bereits definierte Datentyp
+sein.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ TYPE PERSON = STRUCT (TEXT name, vorname, INT alter)
+
+____________________________________________________________________________
+
+
+Der neudefinierte Datentyp wird abstrakter Datentyp genannt. Im Gegensatz zu
+Strukturen und Reihungen stehen für solche Datentypen noch nicht einmal die Zuwei­
+sung zur Verfügung. Ein solcher Datentyp kann genau wie alle anderen Datentypen
+verwendet werden (Deklarationen, Parameter, wertliefernde Prozeduren, als Kompo­
+nenten in Reihungen und Strukturen usw.).
+
+Wird der Datentyp über die Schnittstelle des PACKETs anderen Programmteilen zur
+Verfügung gestellt, so müssen Operatoren und/oder Prozeduren für den Datentyp
+ebenfalls "herausgereicht" werden. Da dann der neudefinierte Datentyp genauso wie
+alle anderen Datentypen verwandt werden kann, aber die Komponenten (Feinstruktur)
+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ßer­
+ halb des definierenden PACKETs zur Verfügung steht)
+
+
+
+2.7.2 Konkretisierung
+
+Um neue Operatoren und/oder Prozeduren für einen abstrakten Datentyp zu schrei­
+ben, 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 ab­
+strakten Typ zum Datentyp der Feinstruktur.
+
+Form:
+
+#on("i")##on("b")#CONCR#off("i")##off("b")# #on("i")##on("b")#(#off("i")##off("b")# Ausdruck #on("i")##on("b")#)#off("i")##off("b")#
+
+____________________________________________________________________________
+ ........................... 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 Strukturen, dann wird
+durch eine Selektion oder Subskription eine implizite Konkretisierung vorgenommen.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ TYPE LISTE = ROW 100 INT;
+
+ LISTE VAR personal nummer;
+ ...
+ personal nummer [3] := ...
+ (* das gleiche wie *)
+ CONCR (personal nummer) [3] := ...
+
+____________________________________________________________________________
+
+
+2.7.3 Denoter für abstrakte
+ Datentypen (Konstruktor)
+
+
+Denoter für neudefinierte Datentypen werden mit Hilfe des Konstruktors gebildet:
+
+Form:
+
+Datentyp #on("i")##on("b")#:#off("i")##off("b")# #on("i")##on("b")#(#off("i")##off("b")# Wertliste #on("i")##on("b")#)#off("i")##off("b")#
+
+In der Wertliste wird für jede Komponente des Datentyps, durch Kommata getrennt,
+ein Wert aufgeführt. Besteht eine der Komponenten wiederum aus einem Datenver­
+bund, muß innerhalb des Konstruktors wiederum ein Konstruktor eingesetzt werden.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ TYPE GEHALT = INT;
+
+ GEHALT VAR meins :: GEHALT : (10000);
+
+____________________________________________________________________________
+
+
+Besteht die Feinstruktur aus einem Datenverbund, muß der Konstruktor u.U. mehrfach
+geschachtelt angewandt werden:
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ TYPE KOMPLEX = ROW 2 REAL;
+
+ KOMPLEX CONST x :: KOMPLEX : ( ROW 2 REAL : ( 1.0, 2.0));
+
+____________________________________________________________________________
+
+
+Auf die Feinstruktur über den Konkretisierer eines neudefinierten Datentyps darf nur in
+dem PACKET zugegriffen werden, in dem der Datentyp definiert wurde. Der Konstruk­
+tor kann ebenfalls nur in dem typdefinierenden PACKET verwandt werden.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ 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:
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ 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).
+____________________________________________________________________________
+#page#
+
+2.8 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 Massenspeichern
+aufbewahrt wird. Dateien sind in bestimmten Informationsmengen, den Sätzen ("re­
+cords") organisiert.
+
+
+
+2.8.1 Datentypen FILE und DIRFILE
+
+In ELAN gibt es zwei Arten von Dateien. Sie werden durch die Datentypen FILE
+und DIRFILE realisiert:
+
+
+
+FILE:
+sequentielle Dateien. Die Sätze können nur sequentiell gelesen bzw. geschrieben
+werden. Eine Positionierung ist nur zum nächsten Satz möglich.
+
+
+DIRFILE:
+indexsequentielle Dateien. Die Positionierung erfolgt direkt mit Hilfe eines Schlüssels
+("key") oder Index, kann aber auch sequentiell vorgenommen werden.
+
+#on("b")#Wichtig: #off("b")#
+DIRFILEs sind auf dem EUMEL-System standardmäßig nicht implementiert! Deswe­
+gen wird auf diesen Dateityp hier nicht weiter eingegangen.
+#page#
+
+2.8.2 Deklaration und Assoziierung
+
+Dateien müssen in einem ELAN-Programm - wie alle anderen Objekte auch -
+deklariert werden.
+
+Form:
+
+#on("i")##on("b")#FILE#off("i")##off("b")# #on("i")##on("b")#VAR#off("i")##off("b")# interner Dateibezeichner
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ FILE VAR f
+
+____________________________________________________________________________
+
+
+Dabei ist zu beachten, daß im EUMEL-System alle FILEs als VAR deklariert werden
+müssen, denn jede Lese/Schreib-Operation verändert einen FILE.
+
+Dateien werden normalerweise vom Betriebsystem 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 Betriebssystem notwendig. Dies erfolgt durch die sogenannte Assozi­
+ierungsprozedur. Die Assoziierungsprozedur 'sequential file' hat die Aufgabe, eine in
+einem Programm deklarierte FILE VAR mit einer bereits vorhandenen oder noch
+einzurichtenden Datei des EUMEL-Systems zu koppeln.
+
+Form:
+
+#on("i")##on("b")#sequential file#off("i")##off("b")# #on("i")##on("b")#(#off("i")##off("b")# Betriebsrichtung, Dateiname #on("i")##on("b")#)#off("i")##off("b")#
+
+Es gibt folgende Betriebsrichtungen (TRANSPUTDIRECTIONs):
+
+
+input:
+Die Datei kann vom Programm nur gelesen werden. Durch 'input' wird bei der Asso­
+ziierung automatisch auf den ersten Satz der Datei positioniert. Ist die zu lesende
+Datei nicht vorhanden, wird ein Fehler gemeldet.
+
+
+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 vor­
+handen, wird sie automatisch eingerichtet.
+
+
+modify:
+Im EUMEL-System gibt es noch die Betriebsrichtung '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.
+
+Nach erfolgter Assoziiierung ist auf den zuletzt bearbeiteten Satz positioniert. Die
+Datei wird automatisch eingerichtet, wenn sie vor der Assoziierung nicht vorhanden
+war.
+
+Der zweite Parameter der Assoziierungsprozedur gibt an, unter welchem Namen die
+Datei in der Task existiert oder eingerichtet werden soll.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ FILE VAR meine datei :: sequential file (output, "xyz");
+
+____________________________________________________________________________
+
+
+Folgendes Beispiel zeigt ein Programm, welches eine Datei liest und auf dem Ausga­
+bemedium ausgibt:
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ FILE VAR f :: sequential file (input, "datei1");
+ TEXT VAR satz;
+ WHILE NOT eof (f) REP
+ getline (f, satz);
+ putline (satz);
+ END REP.
+
+____________________________________________________________________________
+
+
+Eine genau Übersicht der für Dateien existierende Operatoren und Prozeduren finden
+Sie im Teil 5.3.
+#page#
+
+2.9 Abstrakte Datentypen
+ im EUMEL-System
+
+
+
+2.9.1 Datentyp TASK
+
+Tasks müssen im Rechnersystem eindeutig identifiziert werden; sogar im EUMEL-
+Rechner-Netz sind Tasks eindeutig identifizierbar. Dazu wird der spezielle Datentyp
+'TASK' benutzt, denn die Identifizierung einer Task über den Namen ist nicht eindeu­
+tig. Der Benutzer kann ja einen Tasknamen ändern, eine Task löschen und eine
+neue Task mit gleichem Namen einrichten, die jedoch nicht gleich reagiert. Somit
+werden Tasks eindeutig über Variablen vom Datentyp TASK identifiziert.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ TASK VAR plotter := task ("PLOTTER 1")
+
+____________________________________________________________________________
+
+
+Die Taskvariable 'plotter' bezeichnet jetzt die Task im System, die augenblicklich den
+Namen "PLOTTER 1" hat. Die Prozedur 'task' liefert den systeminternen Taskbe­
+zeichner.
+
+Nun sind Taskvariablen auch unter Berücksichtigung der Zeit und nicht nur im aktuel­
+len Systemzustand eindeutig. Der Programmierer braucht sich also keine Sorgen
+darüber zu machen, daß seine Taskvariable irgendwann einmal eine "falsche" Task
+(nach Löschen von "PLOTTER 1" neu eingerichtete gleichen oder anderen Namens)
+identifiziert. Wenn die Task "PLOTTER 1" gelöscht worden ist, bezeichnet 'plotter'
+keine gültige Task mehr.
+
+Unbenannte Tasks haben alle den Pseudonamen "-". Sie können nur über Taskvari­
+ablen angesprochen werden.
+
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ PROC generate shutup manager:
+ TASK VAR son;
+ begin ("shutup", PROC shutup manager, son)
+ END PROC generate shutup manager;
+
+ PROC shutup manager:
+ disable stop;
+ command dialogue (TRUE);
+ REP
+ break;
+ line;
+ IF yes ("shutup")
+ THEN clear error;
+ shutup
+ FI
+ PER
+ END PROC shutup manager
+
+____________________________________________________________________________
+
+
+Ein Taskvariable wird zum Beispiel als Parameter für die Prozedur 'begin' benötigt.
+
+begin
+ #on("b")#PROC begin (TEXT CONST son name, PROC start,
+ TASK VAR new task)#off("b")#
+ Die Prozedur richtet eine Sohntask mit Namen 'son name' (im Beispiel: shutup)
+ ein, die mit der Prozedur 'start' (im Beispiel: shutup manager) gestartet wird. 'new
+ task' (im Beispiel: son) identifiziert den Sohn, falls die Sohntask korrekt eingerich­
+ tet wurde.
+#page#
+
+2.9.2 Datentyp THESAURUS
+
+Ein Thesaurus ist ein Namensverzeichnis, das bis zu 200 Namen beinhalten kann.
+Dabei muß jeder Name mindestens ein Zeichen und höchstens 100 Zeichen lang sein.
+Steuerzeichen (code < 32) werden im Namen folgendermaßen umgesetzt:
+
+#on("i")##on("b")#steuerzeichen#off("b")##off("i")# wird umgesetzt in #on("i")##on("b")#"""" + code(steuerzeichen) + """"#off("b")##off("i")#
+
+Ein Thesaurus ordnet jedem eingetragenen Namen einen Index zwischen 1 und 200
+(einschließlich) zu. Diese Indizes bieten dem Anwender die Möglichkeit, Thesauri zur
+Verwaltung benannter Objekte zu verwenden. (Der Zugriff erfolgt dann über den Index
+eines Namens in einem Thesaurus). So werden Thesauri u.a. von der Dateiverwaltung
+benutzt. Sie bilden die Grundlage der ALL- und SOME-Operatoren.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ initialisiere;
+ arbeite thesaurus ab.
+
+ initialisiere:
+ THESAURUS VAR eine auswahl :: SOME (myself);
+ TEXT VAR thesaurus element;
+ INT VAR index :: 0.
+
+ arbeite thesaurus ab:
+ REPEAT
+ get (eine auswahl, thesaurus element, index);
+ IF thesaurus element = ""
+ THEN LEAVE arbeite thesaurus ab
+ FI;
+ fuehre aktionen durch
+ PER.
+
+ fuehre aktionen durch:
+ edit (thesaurus element);
+ lineform (thesaurus element);
+ pageform (thesaurus element);
+ print (thesaurus element).
+
+____________________________________________________________________________
+
+
+Dieses Beispiel führt für eine Auswahl der in der Task befindlichen Dateien nachein­
+ander die Kommandos 'edit', 'lineform', 'pageform' und 'print' aus.
+
+Die benutzten Operatoren und Prozeduren leisten folgendes:
+
+#ix("SOME")#
+ #on("b")#THESAURUS OP SOME (TASK CONST task) #off("b")#
+ Der Operator bietet das Verzeichnis der in der angegeben Task befindlichen
+ Dateien zum Editieren an. Namen, die nicht gewünscht sind, müssen aus dem
+ Verzeichnis gelöscht werden.
+
+
+#ix("get")#
+ #on("b")#PROC get (THESAURUS CONST t, TEXT VAR name, INT VAR index)
+ #off("b")# Die Prozedur liefert den nächsten Eintrag aus dem angegebenen Thesaurus 't'.
+ 'Nächster' heißt hier, der kleinste vorhandene mit einem Index größer als 'index'.
+ Dabei wird in 'name'der Name und in 'index'der Index des Eintrags geliefert.
+#page#
+
+2.9.3 Datenräume
+
+Datenräume sind die Grundlage von Dateien im EUMEL-System. Einen Datenraum
+kann man sich als eine Sammlung von Daten vorstellen (u.U. leer). Man kann einem
+Datenraum durch ein Programm einen Datentyp "aufprägen". Nach einem solchen
+"Aufpräge"-Vorgang kann der Datenraum wie ein "normaler" Datentyp behandelt
+werden.
+
+Standarddateien (FILEs) sind eine besondere Form von Datenräumen. Sie 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. Hier­
+für stehen Standardprozeduren 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. Zu diesem Zweck werden im
+EUMEL-System Datenräume eingesetzt, 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
+dem Datenraum gespeicherten Objektes nicht kennen.
+
+
+
+2.9.3.1 Datentyp DATASPACE
+
+Datenräume können als eigener Datentyp (DATASPACE) in einem Programm behan­
+delt werden. Somit können Datenräume (als Ganzes) ohne Kenntnis eines eventuell
+(vorher oder später) aufgeprägten Typs benutzt werden.
+
+Als Operationen auf DATASPACE-Objekte sind nur Transporte, Löschen und Zuwei­
+sung zugelassen.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ DATASPACE VAR ds
+
+____________________________________________________________________________
+
+
+Für Datenräume ist die Zuweisung definiert. Der Zuweisungsoperator (':=') bewirkt
+eine Kopie des Datenraums vom rechten auf den linken Operanden.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ DATASPACE VAR datenraum :: nilspace;
+
+____________________________________________________________________________
+
+
+Die Prozedur 'nilspace' liefert einen leeren Datenraum. Der Datenraum 'datenraum' ist
+also eine Kopie des leeren Datenraums.
+
+Die Prozeduren und Operatoren für Datenräume werden im Teil 5.4.7 beschrieben.
+#page#
+
+2.9.3.2 BOUND-Objekte
+
+Wie bereits erwähnt, kann man einem Datenraum einen Datentyp aufprägen. Dazu
+werden #ib#BOUND#ie#-Objekte benutzt. Mit dem Schlüsselwort #on("i")##on("b")#BOUND#off("i")##off("b")#, welches in der
+Deklaration vor den Datentyp gestellt wird, teilt man dem ELAN-Compiler mit, daß
+die Werte eines Datentyps in einem Datenraum gespeichert sind bzw. gespeichert
+werden sollen.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ BOUND ROW 1000 REAL VAR liste
+
+____________________________________________________________________________
+
+
+Die Ankopplung des BOUND-Objekts an eine Datei erfolgt mit dem Operator #on("i")##on("b")#:=#off("i")##off("b")#.
+
+Form:
+
+BOUND-Objekt #on("i")##on("b")#:=#off("i")##off("b")# Datenraum
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ BOUND ROW 1000 REAL VAR gehaltsliste := new ("Gehälter")
+
+____________________________________________________________________________
+
+
+Die Prozedur 'new' kreiert dabei einen leeren Datenraum (hier mit dem Namen 'Ge­
+hälter'), der mit Hilfe der Zuweisung (hier: Initialisierung) an die Variable 'gehaltsliste'
+gekoppelt wird.
+
+Nun kann man mit der 'gehaltsliste' arbeiten wie mit allen anderen Feldern auch. Die
+Daten, die in 'gehaltsliste' gespeichert, werden eigentlich im Datenraum 'Gehälter'
+abgelegt.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ gehaltsliste [5] := 10 000.0; (* Traumgehalt *)
+ gehaltsliste [index] INCR 200.0; (* usw. *)
+
+____________________________________________________________________________
+
+
+Man kann auch Prozeduren schreiben, die auf der Gehaltsliste arbeiten.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ PROC sort (ROW 1000 REAL VAR liste):
+ ...
+ END PROC sort;
+ ...
+ sort (CONCR (gehaltsliste));
+ ...
+
+____________________________________________________________________________
+
+
+Man beachte, daß der formale Parameter der Prozedur 'sort' nicht mit BOUND spezi­
+fiziert werden darf (BOUND wird nur bei der Deklaration des Objekts angegeben). Das
+ist übrigens ein weiterer wichtiger Vorteil von BOUND-Objekten: man kann alle
+Prozeduren des EUMEL-Systems auch für BOUND-Objekte verwenden, nur die
+Datentypen müssen natürlich übereinstimmen.
+
+
+Häufige Fehler bei der Benutzung von Datenräumen
+
+- Wenn man an ein DATASPACE-Objekt zuweist (z.B.: DATASPACE VAR ds :=
+ new ("mein datenraum")), so erhält man, wie bereits 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.
+ Für Änderungen in der Quelle, also in der vom Datei-Manager verwalteten Datei,
+ ist stets direkt anzukoppeln.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ BOUND ROW 10 INT VAR reihe;
+ INT VAR i;
+
+ PROC zeige dsinhalt (TEXT CONST datenraum):
+ BOUND ROW 10 INT VAR inhalt := old (datenraum);
+ INT VAR j;
+ line;
+ putline ("Inhalt:" + datenraum);
+ FOR j FROM 1 UPTO 10 REP
+ put (inhalt (j))
+ PER
+ END PROC zeige dsinhalt;
+
+ (* falsch: es wird auf der Kopie gearbeitet: *)
+ DATASPACE VAR ds := new ("Gegenbeispiel: Zahlen 1 bis 10");
+ reihe := ds;
+ besetze reihe;
+ zeige dsinhalt ("Gegenbeispiel: Zahlen 1 bis 10");
+
+ (* richtig: es wird auf dem Datenraum gearbeitet: *)
+ reihe := new ("Beispiel: Zahlen 1 bis 10");
+ besetze reihe;
+ zeige dsinhalt ("Beispiel: Zahlen 1 bis 10").
+
+ besetze reihe:
+ FOR i FROM 1 UPTO 10 REP
+ reihe (i) := i
+ PER.
+
+____________________________________________________________________________
+
+
+ Der Datenraum 'Gegenbeispiel: Zahlen 1 bis 10' wird nicht mit Werten besetzt,
+ sondern die Kopie dieses Datenraums, der unbenannte Datenraum 'ds'. Auf dem
+ direkt angekoppelten Datenraum 'Beispiel: Zahlen 1 bis 10' werden die Werte
+ gespeichert.
+
+
+- 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'. Ein automatisches Löschen von DATASPACE-Objekten erfolgt nicht bei
+ Programmende (sonst könnten sie ihre Funktion als Datei nicht erfüllen). Nur
+ durch 'forget' oder beim Löschen einer Task werden alle ihr gehörenden
+ DATASPACE-Objekte gelöscht und der belegte Speicherplatz freigegeben.
+
+
+- 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) (* Datenraum löschen,
+ damit der Platz wieder verwendet wird *)
+
+____________________________________________________________________________
+
+
+- Will man auf die Feinstruktur eines BOUND-Objekts zugreifen, so muß man
+ strenggenommen den Konkretisierer benutzen:
+
+ Form:
+
+ #on("i")##on("b")#CONCR#off("i")##off("b")# #on("i")##on("b")#(#off("i")##off("b")# Ausdruck #on("i")##on("b")#)#off("i")##off("b")#
+
+ Der Konkretisierer ermöglicht eine typmäßige Umbetrachtung vom BOUND-Objekt
+ zum Datentyp der Feinstruktur. Ist der Zugriff jedoch eindeutig, so wird 'CONCR'
+ automatisch vom Compiler ergänzt.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ BOUND INT VAR i := old ("i-Wert");
+ INT VAR x;
+ x := wert.
+
+ wert:
+ IF x < 0
+ THEN 0
+ ELSE CONCR (i)
+ FI.
+
+____________________________________________________________________________
+
+
+In diesem Beispiel muß der Konkretisierer benutzt werden, da sonst der Resultattyp
+des Refinements nicht eindeutig ist (BOUND oder INT?).
+
+
+
+2.9.3.3 Definition neuer Dateitypen
+
+Durch die Datenräume und die Datentyp-Definition von ELAN ist es für Programmie­
+rer 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 soll an dem Beispiel DIRFILE (welcher zwar im ELAN-Standard
+definiert, aber nicht im EUMEL-System realisiert ist) gezeigt werden, wie ein neuer
+Datei-Datentyp definiert wird:
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ 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 vorhandenen Datenraum oder
+richtet einen neuen ein. Um eine Initialisierung mit der 'dirfile'-Prozedur vorneh­
+men zu können, braucht man auch einen Zuweisungsoperator, 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 benut­
+zen.
+
+____________________________________________________________________________
+ ........................... 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;
+ ...
+
+____________________________________________________________________________
+#page#
+
+2.9.4 Datentyp INITFLAG
+
+Im Multi-User-System ist es oft notwendig, Pakete beim Einrichten einer neuen
+Task in dieser neu zu initialisieren. Das muß z.B. bei der Dateiverwaltung gemacht
+werden, da die neue Task ja nicht die Dateien des Vaters erbt. Mit Hilfe von
+INITFLAG-Objekten kann man zu diesem Zweck feststellen, ob ein Paket in dieser
+Task schon initialisiert wurde.
+
+
+INITFLAG
+ #on("b")#TYPE INITFLAG #off("b")#
+ Erlaubt die Deklaration entsprechender Flaggen.
+
+:=
+ #on("b")#OP := (INITFLAG VAR flag, BOOL CONST flagtrue) #off("b")#
+ Erlaubt die Initialisierung von INITFLAGs
+
+initialized
+ #on("b")#BOOL PROC initialized (INITFLAG VAR flag) #off("b")#
+ Wenn die Flagge in der Task A auf TRUE oder FALSE gesetzt wurde, dann liefert
+ sie beim ersten Aufruf den entsprechenden Wert, danach immer TRUE (in der
+ Task A!).
+
+ Beim Einrichten von Söhnen wird die Flagge in den Sohntasks automatisch auf
+ FALSE gesetzt. So wird erreicht, daß diese Prozedur in den neu eingerichteten
+ Söhnen und Enkeltasks genau beim ersten Aufruf FALSE liefert.
+
+____________________________________________________________________________
+ ........................... Beispiel: .........................
+ PACKET stack DEFINES push, pop:
+
+ INITFLAG VAR in this task := FALSE ;
+ INT VAR stack pointer ;
+ ROW 1000 INT VAR stack ;
+
+ PROC push (INT CONST value) :
+
+ initialize stack if necessary ;
+ ....
+
+ END PROC push ;
+
+ PROC pop (INT VAR value) :
+
+ initialize stack if necessary ;
+ ....
+
+ END PROC pop ;.
+
+ initialize stack if necessary :
+ IF NOT initialized (in this task)
+ THEN stack pointer := 0
+
+ FI .
+
+ END PACKET stack
+____________________________________________________________________________
+
diff --git a/doc/programmer-manual/1.8.7/doc/programmierhandbuch.3 b/doc/programmer-manual/1.8.7/doc/programmierhandbuch.3
new file mode 100644
index 0000000..eade335
--- /dev/null
+++ b/doc/programmer-manual/1.8.7/doc/programmierhandbuch.3
@@ -0,0 +1,728 @@
+#headandbottom("1","EUMEL-Benutzerhandbuch","TEIL 3 : Editor","3")#
+#pagenr("%",1)##setcount##block##pageblock#
+#headeven#
+#center#EUMEL-Benutzerhandbuch
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#TEIL 3 : Editor
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+3 - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#3 - %
+#end#
+
+TEIL 3: Der Editor
+
+Mit dem #ib#EUMEL-Editor#ie# steht für den Teil der Programmierung, der aus der Eingabe
+von Programmtext besteht, dasselbe komfortable Werkzeug zur Verfügung, wie für die
+Textverarbeitung. Merkmale des EUMEL-Editors sind die einfache Fenstertechnik
+und die übersichtliche Bedienung durch wenige Funktionstasten.
+
+Eine mit dem Editor erzeugte Textdatei ist maximal 4075 Zeilen lang, die maximale
+Breite einer Zeile beträgt 16000 Zeichen.
+
+
+
+3.1 Ein- und Ausschalten des Editors
+
+Der Editor wird eingeschaltet durch Eingabe von:
+
+____________________________________________________________________________
+ gib kommando :
+ #ib#edit#ie# ("dateiname")
+
+____________________________________________________________________________
+
+
+Falls eine Datei unter dem eingegebenen Namen existiert, wird ein Fenster auf dieser
+Datei an der Stelle geöffnet, an der zuletzt ein Zugriff auf diese Datei stattfand.
+
+Existiert noch keine Datei unter dem angegebenen Namen in der Task, folgt eine
+Anfrage, ob eine Datei unter dem eingegebenen Namen neu eingerichtet werden soll:
+
+____________________________________________________________________________
+ gib kommando :
+ edit("dateiname")
+ "dateiname" neu einrichten (j/n) ?
+
+____________________________________________________________________________
+
+
+Die Abfrage dient der Kontrolle der Schreibweise. Man kann ggf. das Einrichten der
+Datei ablehnen, den Dateinamen verbessern und das Kommando erneut geben.
+
+Bei korrekter Schreibweise bejahen Sie die Kontrollfrage#u# 1)#e#mit
+
+#center#<j> <J> <y> oder <Y>
+
+
+Es erscheint ein leerer Editorbildschirm. Die oberste Zeile des Bildschirms ist die
+#ib#Titelzeile#ie#. In ihr kann nicht geschrieben werden. Sie zeigt jedoch verschiedene nütz­
+liche Dinge an: den Namen der Datei, die Nummer der aktuellen Zeile, in der gerade
+geschrieben wird, Tabulatormarken, Einfügemodus, Lernmodus usw.
+
+____________________________________________________________________________
+ #mark on# ............... dateiname ....................#mark off# Zeile 1 #mark on# #mark off#
+ _
+
+____________________________________________________________________________
+
+
+
+Wollen Sie die #ib#Schreibarbeit beenden#ie# und den #ib#Editor ausschalten#ie#, so drücken Sie die
+beiden Tasten
+
+<ESC> <q>
+
+nacheinander. Sie haben damit den #ib#Editor verlassen#ie# und befinden sich wieder auf
+Monitor-Ebene.
+#page#
+
+3.2 Die Funktionstasten
+
+Die Funktionstasten realisieren diejenigen Fähigkeiten des Editor, die über die reine
+Zeicheneingabe hinausgehen. Wo die Tasten auf Ihrem Gerät liegen, hängt von dem
+jeweiligen Gerätetyp ab. Die Wirkung der Tasten ist im Weiteren erläutert.
+
+#l pos (0.0)##l pos(4.0)#
+#table#
+#free(0.5)#
+#taste1(" SHIFT ")# Umschalttaste
+#tableend#
+#free(0.5)#
+<v> <^> <>> <<> Positionierungstasten
+#table#
+#free(0.5)#
+<CR> Eingabe-/ Absatztaste
+#free(0.5)#
+<ESC> Kommandotaste
+#free(0.5)#
+<HOP> Verstärkertaste
+#free(0.5)#
+<TAB> Tabulatortaste
+#free(0.5)#
+<MARK> Markiertaste
+#free(0.5)#
+<RUBOUT> Löschtaste
+#free(0.5)#
+<RUBIN> Einfügetaste
+#free(0.5)#
+<SV> Supervisortaste
+#free(0.5)#
+<STOP> Stoptaste
+#free(0.5)#
+<WEITER> Weitertaste
+#tableend##clear pos#
+#free(0.5)#
+Es kann sein, daß Tasten nicht richtig beschriftet sind. Die Installations-anleitung
+muß dann die Entsprechungen beschreiben. Natürlich können sich weitere Funktions­
+tasten außer den im folgenden beschriebenen auf Ihrer Tastatur befinden. Diese
+haben standardmäßig jedoch keine besondere Bedeutung für den Editor.
+
+#page#
+
+3.3 Die Wirkung der Funktionstasten
+
+<SHIFT>
+
+#ib#Umschalttaste#ie#
+
+Wird diese Taste gleichzeitig mit einer anderen betätigt, so wird ein Buchstabe in
+Großschreibung, bei den übrigen Tasten das obere Zeichen, ausgegeben. So wird z.B.
+anstelle der "9" das Zeichen ")" ausgegeben.
+#free(0.5)#
+<>> <<>
+
+<v> <^>
+
+Positionierungstasten
+
+#ib#Positionierung des Cursors#ie# um eine Spalten-/Zeilenposition in die jeweilige Richtung.
+#free(0.5)#
+<CR>
+
+#ib#Eingabetaste / Absatztaste#ie#, Carriage Return, kurz: 'CR'
+
+Diese Taste schließt die aktuelle Zeile explizit ab und es wird an den Beginn der
+nächsten Zeile positioniert. Einrückungen werden beibehalten.
+
+Der EUMEL-Editor ist auf automatischen Wortumbruch voreingestellt, d.h. ein Wort,
+das über das 77. Zeichen der aktuellen Zeile herausreichen würde, wird automatisch
+in die nächste Zeile gerückt (siehe 'word wrap' 4.2.5). Die Absatztaste wird also
+benötigt, um explizite Zeilenwechsel und Einrückungen bei der Textformatierung zu
+erhalten. Eine Absatzmarke wird durch ein 'blank' hinter dem letzten Zeichen der
+Zeile erzeugt und ist im Editor an der Inversmarkierung am rechten Bildschirmrand zu
+erkennen.
+
+Im EUMEL-System werden Kommandos auf einer Kommandozeile, auf der alle
+Editorfunktionen zur Verfügung stehen, eingegeben. Auf dieser Ebene beendet die
+Taste also ausdrücklich die Kommandoeingabe, das gegebene Kommando wird an­
+schließend analysiert und ausgeführt.
+
+<HOP>
+
+"#ib#Verstärkertaste#ie#"; wird als Vorschalttaste bedient.
+
+In Kombination mit anderen Funktionstasten wird deren Wirkung verstärkt.
+
+
+<HOP> <v>
+
+Steht der Cursor nicht am unteren Bildrand, so wird er dorthin positioniert. Steht er
+am unteren Bildrand, so wird um einen Bildschirminhalt "weitergeblättert".
+
+Entsprechend werden auch die Tasten : <^> <>> <<> mit der HOP-Taste verstärkt.
+
+#page#
+<HOP> <RUBIN>
+
+#ib#Einfügen von Textpassagen#ie#. Die HOP-Taste in Verbindung mit RUBIN und RUBOUT
+wird zum 'verstärkten' Löschen und Einfügen verwendet.
+
+Ab der aktuellen Position des Cursors 'verschwindet' der restliche Text. Es kann wie
+bei der anfänglichen Texteingabe fortgefahren werden. Die Anzeige '#ib#REST#ie#' 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).
+
+____________________________________________________________________________
+ ................ dateiname ..................... Zeile 4
+ In diesem Text soll vor dem zweiten Satz 
+ etwas eingefügt werden. Hierzu wird der
+ Cursor an die Position geführt, an der 
+ ein beliebiger Text eingefügt werden soll.#absatz#
+
+____________________________________________________________________________
+
+
+Nach Betätigen der Taste #on("i")##on("b")#HOP#off("i")##off("b")# und #on("i")##on("b")#RUBIN#off("i")##off("b")#sieht der Bildschirm wie folgt aus:
+
+____________________________________________________________________________
+ .............. dateiname ........REST.......... Zeile 4
+ In diesem Text soll vor dem zweiten Satz 
+ etwas eingefügt werden.
+
+
+____________________________________________________________________________
+
+
+
+Nun kann beliebig viel Text eingefügt werden. Nochmaliges Betätigen von HOP und
+RUBIN führt den Text-Rest wieder bündig heran.
+
+#page#
+<HOP> <RUBOUT>
+
+Löscht die Zeile ab Cursor-Position bis Zeilenende.
+
+____________________________________________________________________________
+ ................ dateiname ..................... Zeile 4
+ Soll eine ganze Zeile oder ein Textrest 
+ gelöscht werden, so positioniert man an die 
+ Stelle, ab der gelöscht werden soll. Rest löschen....
+ Nach HOP RUBOUT ist der Zeilenrest gelöscht.#absatz#
+
+____________________________________________________________________________
+
+
+
+Nach Betätigen der Tasten #on("i")##on("b")#HOP#off("i")##off("b")# und #on("i")##on("b")#RUBOUT#off("i")##off("b")# sieht der Bildschirm wie folgt aus.
+
+____________________________________________________________________________
+ ............... dateiname .................... Zeile 4
+ Soll eine ganze Zeile oder ein Textrest 
+ gelöscht werden, so positioniert man an die 
+ Stelle, ab der gelöscht werden soll.
+ Nach HOP RUBOUT ist der Zeilenrest gelöscht.#absatz#
+
+____________________________________________________________________________
+
+
+
+Steht der Cursor am Zeilenanfang, wird nach HOP RUBOUT dementsprechend die
+ganze Zeile gelöscht und die Lücke durch Nachrücken der Folgezeilen geschlossen
+(HOP RUBOUT betätigen).
+#page#
+<TAB>
+
+#ib#Tabulatortaste#ie#
+
+Mit der Tabulatortaste werden die eingestellten Tabulatorpositionen angesprungen.
+Jeder Tastendruck läßt den Cursor auf die nächste eingestellte Tabulatorposition
+springen.
+
+#on("i")#Voreingestellte#off("i")# Tabulatorpositionen sind die beiden Schreibgrenzen, Textanfang in der
+Zeile und Ende der Zeile.
+
+Weitere Tabulatorpositionen können durch Positionierung auf die gewünschte Spalte
+und #on("i")##on("b")#HOP#off("i")##off("b")# #on("i")##on("b")#TAB#off("i")##off("b")# gesetzt werden. Sie können gelöscht werden, indem sie mit #on("i")##on("b")#TAB#off("i")##off("b")#
+angesprungen und mit #on("i")##on("b")#HOP#off("i")##off("b")# #on("i")##on("b")#TAB#off("i")##off("b")#
+ausgeschaltet werden.
+
+Die gesamte eingestellte Tabulalation kann durch #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#TAB#off("i")##off("b")# ein-/ und ausge­
+schaltet werden.
+
+Die eingestellten Tabulatorpositionen erkennen Sie an den Tabulatorzeichen (Dachzei­
+chen) in der obersten Bildschirmzeile.
+#page#
+<MARK>
+
+#ib#Ein- bzw. Ausschalten der Markierung#ie#.
+
+Bei Betätigung dieser Taste wird in einen speziellen #ib#Markierzustand#ie# geschaltet. Alles,
+was Sie jetzt schreiben bzw. durch Bewegen des Cursors in Richtung Dateiende
+kennzeichnen, steht als #on("i")#markierter#off("i")# Bereich für die Bearbeitung zur Verfügung. Zur
+besseren Sichtbarkeit wird der markierte Bereich invers zum übrigen Text dargestellt.
+
+Wird der Cursor in eine Richtung bewegt, wird das gesamte Textstück zwischen
+Einschaltpunkt der Markierung und aktueller Cursorposition markiert. Rückwärtsbewe­
+gungen des Cursors verkürzen den markierten Bereich wieder.
+
+Durch erneutes Betätigen der MARK-Taste schalten Sie den Markier-Zustand
+wieder aus.
+
+Mit weiteren Kommandos kann der Bereich nun bearbeitet werden:
+
+<ESC> <d> Markierten Abschnitt in 'Scratch'-Datei kopieren.
+
+<ESC> <p> Markierten Abschnitt herauskopieren.
+
+<ESC> <RUBOUT> Markierten Abschnitt löschen.
+
+
+Der mit #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#p#off("i")##off("b")# oder#on("i")##on("b")#d#off("i")##off("b")# kopierte Bereich kann beliebig oft in derselben oder einer
+anderen Datei ein/angefügt werden.
+
+Der mit #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#RUBOUT#off("i")##off("b")# gelöschte Abschnitt kann genau einmal durch #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#RUBOUT#off("i")##off("b")#
+an anderer Stelle derselben Datei eingefügt werden.
+
+(vgl. ESC-Taste, Operationen auf Markierungen, 3-#topage("ESC")#)
+#page#
+<RUBIN>
+
+#ib#Ein- bzw. Ausschalten des Einfügemodus.#ie#
+
+Das Betätigen der Taste schaltet in den Einfügemodus. Der Zustand wird durch das
+Wort "RUBIN" im linken Drittel der Titelzeile der Datei angezeigt. Vor dem Zeichen,
+auf dem der Cursor steht, wird eingefügt. Nochmaliges Betätigen der Taste schaltet
+den Einfügemodus aus.
+#free(1.0)#
+<RUBOUT>
+
+#ib#Löschtaste#ie#
+
+Das Zeichen, auf dem der Cursor steht, wird gelöscht. Wenn der Cursor, wie bei
+fortlaufender Eingabe üblich, hinter dem letzten Zeichen einer Zeile steht, wird das
+letzte Zeichen gelöscht.
+
+#page#
+
+3.4 ESC Kommandos
+
+<ESC>
+
+#ib#Kommandotaste#ie#
+
+Mit der ESC-Taste in Kombination mit einer Folgetaste werden vordefinierte Aktionen
+ausgelöst. Es gibt Aktionen, die vorprogrammiert zur Verfügung stehen, und Sie selbst
+können weitere hinzufügen.
+
+Der Kommandodialog wird eingeschaltet durch:
+
+<ESC> <ESC>
+
+
+____________________________________________________________________________
+ ............... Beispiel ..................... Zeile 4
+
+ gib kommando:                                             
+
+____________________________________________________________________________
+
+
+Der Kommandodialog ermöglicht die Eingabe von beliebigen Kommandos ohne den
+Editor verlassen zu müssen. Insbesondere Such- und Kopieroperationen stellen auch
+für den Programmierer nützliches Werkzeug dar (siehe 3.5).
+
+Auf der Kommandozeile kann jedes Kommando gegeben werden. Die Kommandozeile
+kann wie eine normale Textzeile editiert werden. Nach #on("i")##on("b")#CR#off("i")##off("b")# verschwindet die Kom­
+mandozeile und das Kommando wird ausgeführt.
+
+Falls ein Fehler auftritt erfolgt eine entsprechende Fehlermeldung in der Kopfzeile und
+die Kommandozeile erscheint erneut.
+
+Um ein weiteres Editor-Fenster zu 'öffnen', betätigt man im Editor
+
+<ESC>  <e>
+
+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. Zunächst wird der Dateiname erfragt. Nach dessen Eingabe
+und #on("i")##on("b")#CR#off("i")##off("b")# wird ein Fenster auf eröffnet. 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' kann man dann genauso arbeiten wie im 'normalen' Editor.
+
+Mit der Tastenfolge
+
+<ESC>  <w>
+
+wechselt man von einem Fenster (zyklisch) in das benachbarte. Es gibt eine Hier­
+archie zwischen den Fenstern in der Reihenfolge, in der eines im anderen einge­
+richtet worden ist. Gibt man
+
+<ESC>  <q>
+
+in einem Fenster, so verschwindet dieses und alle darin eingeschachtelten Fenster,
+und man befindet sich im übergeordneten Fenster.
+
+Durch
+
+<ESC>  <p> oder <ESC>  <d>
+
+schreibt man einen markierten Teil in eine 'Scratch'-Datei (nicht editierbarer
+Zwischenspeicher); durch ESC p wird ein markierter Text aus der Ursprungsdatei
+entfernt und in die 'Scratch'-Datei geschrieben. Im Gegensatz dazu wird er durch
+ESC d kopiert. Durch
+
+<ESC>  <g>
+
+fügt man ihn in eine andere (oder dieselbe) Datei ein. Im Unterschied zu ESC RUBIN
+wird die temporäre Datei dadurch nicht entleert.
+
+Die für ESC p, bzw. ESC d benutzte #ib#'Scratch'-Datei#ie#, die nicht editierbar ist, ist nicht
+mit dem sogenannten Notizbuch zu verwechseln. Das Notizbuch ist eine Datei, in der
+alle Editorfunktionen benutzt werden können, auf die jedoch ohne Angabe eines
+Dateinamens durch
+
+<ESC> <n>
+
+ab der aktuellen Cursorposition ein Fenster eröffnet wird. Das Notizbuch nimmt
+insbesondere Fehlermeldungen und Meldungen bei der Übersetzung von Programmen
+auf.
+
+<ESC> <v>
+
+erlaubt vom äußeren Fenster aus alle eingeschachtelten Fenster zu verlassen.
+#page#
+
+Vorbelegte Tasten
+
+#ib#ESC q#ie# Verlassen des Editors bzw. der eingeschachtelten Fenster.
+
+#ib#ESC e#ie# Weiteres Editorfenster einschalten.
+
+#ib#ESC n#ie# Notizbuch 'anzeigen'.
+
+#ib#ESC v#ie# Dateifenster auf ganzen Bildschirm vergrößern
+ bzw. Bildschirm rekonstruieren (eingeschachteltes Fenster verlas­
+ sen).
+
+#ib#ESC w#ie# Dateiwechsel beim Fenstereditor.
+
+#ib#ESC f#ie# Nochmalige Ausführung des letzten Kommandos.
+
+#ib#ESC b#ie# Das Fenster wird auf den linken Rand der aktuellen (ggf. verscho­
+ benen) Zeile gesetzt.
+
+ESC > Zum nächsten Wortanfang.
+
+ESC < Zum vorherigen Wortanfang.
+
+#ib#ESC 1#ie# Zum Anfang der Datei.
+
+#ib#ESC 9#ie# Zum Ende der Datei.
+#page#
+
+Operationen auf Markierungen
+
+
+#goalpage("ESC")#
+#ib#ESC RUBOUT#ie# Markiertes "vorsichtig" löschen.
+
+#ib#ESC RUBIN#ie# Mit ESC RUBOUT vorsichtig Gelöschtes einfügen.
+
+#ib#ESC p#ie# Markiertes löschen und in die Notiz-Datei schreiben. Kann mit ESC
+ g an anderer Stelle reproduziert werden.
+
+#ib#ESC d#ie# Duplizieren:
+ Markiertes in die Notiz-Datei kopieren, anschließend die
+ Markierung abschalten. Kann mit ESC g beliebig oft reproduziert
+ werden.
+
+#ib#ESC g#ie# Mit ESC p gelöschten oder mit ESC d duplizierten Text an aktuelle
+ Cursor-Stelle schreiben, d.h. Notiz-Datei an aktueller Stelle einfü­
+ gen.
+#page#
+
+Zeichen schreiben
+Diese Tasten sind standardmäßig so vorbelegt wie hier aufgeführt, sie können aber
+von Benutzern und in Anwenderprogrammen geändert werden.
+
+#ib#ESC a#ie# Schreibt ein ä.
+#ib#ESC A#ie# Schreibt ein Ä.
+#ib#ESC o#ie# Schreibt ein ö.
+#ib#ESC O#ie# Schreibt ein Ö.
+#ib#ESC u#ie# Schreibt ein ü.
+#ib#ESC U#ie# Schreibt ein Ü.
+#ib#ESC s#ie# Schreibt ein ß.
+#ib#ESC (#ie# Schreibt eine [.
+#ib#ESC )#ie# Schreibt eine ].
+#ib#ESC <#ie# Schreibt eine {.
+#ib#ESC >#ie# Schreibt eine }.
+#ib#ESC \##ie# Schreibt ein \#, das auch gedruckt werden kann.
+#ib#ESC ­#ie# Schreibt einen (geschützten) Trennstrich, siehe Textverarbeitung.
+#ib#ESC k#ie# Schreibt ein (geschütztes) "k", siehe Textverarbeitung.
+#ib#ESC blank#ie# Schreibt ein (geschütztes) Leerzeichen, siehe Textverarbeitung.
+#free(0.7)#
+
+Kommando auf Taste legen
+
+#ib#ESC ESC#ie# Kommandodialog einschalten
+
+#ib#ESC ! taste#ie# Im Kommandodialog:
+ Geschriebenes Kommando auf Taste legen.
+
+#ib#ESC ? taste#ie# Im Kommandodialog:
+ Auf 'taste' gelegtes Kommando zum Editieren anzeigen.
+
+#ib#ESC k#ie# Im Kommandodialog:
+ Das zuletzt editierte Kommando (einzeilige ELAN-Programm)
+ anzeigen.
+
+
+Der Lernmodus
+Der Lernmodus ermöglicht beliebige Tastensequenzen zu speichern und auf eine
+Taste 't' zu legen. Durch #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#t#off("i")##off("b")# wird die gesamte Sequenz ausgeführt.
+
+Nicht belegt werden können die vom System vorbelegten Tasten (3-14).
+
+Beispielsweise könnte es für einen Programmierer sinnvoll sein die Tastenfolge
+'THEN' 'CR' '>' '>' '>' '>' auf die Taste #on("i")##on("b")#T#off("i")##off("b")# zu legen. Durch #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#T#off("i")##off("b")# wird 'THEN' in
+die aktuelle Zeile geschrieben und der Cursor mit passender Einrückung in die
+Einrückung in die Folgezeile gesetzt.
+
+
+#ib#ESC HOP#ie# #ib#Lernen einschalten#ie#.
+
+#ib#ESC HOP taste#ie# #ib#Lernen ausschalten#ie# und Lernsequenz auf 'taste'legen.
+
+#ib#ESC HOP HOP#ie# #ib#Gelerntes vergessen#ie#. Bedingung ist, daß man die Lernsequenz in
+ der Task löscht, in der man sie hat lernen lassen.
+
+
+#on("b")#
+#center#A C H T U N G :
+Der Lernmodus bleibt eingeschaltet, auch wenn der Editor beendet wird. Dann werden
+die folgenden Monitor-Kommandos usw. usf. 'gelernt'. Durch unsinniges 'Lernen'
+lassen sich schlimmstenfalls beliebige Verwüstungen anrichten.
+
+Der Lernmodus wird in der Editor-Kopfzeile angezeigt. Falls der Editor beendet wird,
+ohne den Lernmodus auszuschalten, erfolgt eine Warnung auf Monitor-Ebene.
+
+Um den Lernmodus zu beenden drücken Sie:
+
+<ESC> <HOP> <HOP>
+
+Dadurch wird der Lernmodus ausgeschaltet und nichts gelernt, die Gefahr ist gebannt.#off("b")#
+
+#page#
+<SV>
+
+#ib#SUPERVISOR-Taste#ie#
+
+Betätigen Sie diese Taste im Editor, dann unterbrechen Sie Ihre Editierarbeit und
+erhalten die Meldung
+
+____________________________________________________________________________
+
+ Terminal 2
+
+
+ EUMEL Version 1.8/M
+
+
+ gib supervisor kommando:
+
+
+
+
+ ESC ? --> help
+ ESC b --> begin("") ESC h --> halt
+ ESC c --> continue("") ESC s --> storage info
+ ESC q --> break ESC t --> task info
+
+____________________________________________________________________________
+
+
+
+Wollen Sie nun im Editor fortfahren bzw. haben Sie irrtümlich die SV-Taste betätigt,
+dann geben Sie das Kommando
+
+____________________________________________________________________________
+
+ gib supervisor kommmando :
+ continue ("meine task")
+
+____________________________________________________________________________
+
+
+
+(falls Ihre Task, in der Sie arbeiteten, wirklich "meine task" hieß!)
+
+Um Ihren in Bearbeitung befindlichen Text wieder vollständig auf dem Bildschirm zu
+sehen, betätigen die die Tasten
+
+<ESC> <b>
+
+Sie sind wieder an der Stelle, an der Sie den Text mit der SV-Taste verlassen ha­
+ben, und können normal weiterarbeiten.
+
+#on("u")#Achtung:#off("u")# Die SV-Taste kann, je nach Terminal, durch das Betätigen von zwei
+Tasten gleichzeitig realisiert sein (oft 'CTRL b'). Beachten Sie die Beschreibung Ihrer
+Tastatur!
+
+
+
+#on("b")#
+Für die Programmierung ist die Tastenfolge <SV> <ESC> <h> von Bedeutung, da hier­
+durch der Fehler 'halt vom Terminal' erzeugt wird. Dadurch können unerwünscht
+laufende Programme abgebrochen werden.
+#off("b")#
+#page#
+<STOP>
+
+#ib#Unterbrechen einer Ausgabe#ie# (oft auch als CTRL a realisiert).
+
+Haben Sie diese Taste aus Versehen betätigt, erkennen Sie dies daran, daß der
+Editor nicht "reagiert". Betätigen Sie die WEITER-Taste (oft auch CTRL c).
+#free(1.0)#
+<WEITER>
+
+Unterbrochene Ausgabe fortsetzen.
+
+Ein mit der STOP-Taste angehaltene Ausgabe können Sie durch Betätigen der
+#ib#WEITER-Taste#ie# fortsetzen.
+
+
+#on("u")#VORSICHT:#off("u")# Die STOP-Taste unterbricht nur die Ausgabe auf den Bildschirm. Zei­
+ chen, die während des STOP eingegeben werden, werden gespeichert
+ und nach 'WEITER' ausgegeben!
+
+
+#page#
+
+3.5 Positionieren, Suchen, Ersetzen
+ im Kommandodialog
+
+
+Um das Editorfenster auf eine bestimmte Zeile zu positionieren wird einfach diese
+Zeilennummer angegeben.
+
+____________________________________________________________________________
+ ............... Beispiel ..................... Zeile 4
+
+ gib kommando: 123                                          
+
+____________________________________________________________________________
+
+
+
+Falls die Zeilenzahl der Datei geringer als die angegebene Zeilennummer ist, wird auf
+die letzte Zeile positioniert.
+
+
+Um das Editorfenster auf ein bestimmtes Textstück zu positionieren, wird der gesuch­
+te Text, ggf. mit Suchrichtung angegeben.
+
+____________________________________________________________________________
+ ............... Beispiel ..................... Zeile 4
+
+ gib kommando: "END PROC"                                  
+
+____________________________________________________________________________
+
+
+Die Suchrichtung kann durch 'D' (down) oder 'U' (up) zusätzlich spezifiziert werden.
+
+____________________________________________________________________________
+ ............... Beispiel ..................... Zeile 4
+
+ gib kommando: U "INT VAR schleifenzaehler"                 
+
+____________________________________________________________________________
+
+
+
+Um beliebige Texte durch andere zu ersetzen, dienen die Operatoren 'C' (change)
+bzw. 'CA' (change all).
+
+Bei Ausführung dieses Kommandos wird zunächst nach #on("u")#unten#off("u")# in der editierten Datei
+nach dem zu ersetzenden Text gesucht. Wenn der Text gefunden wird, wird er durch
+den hinter dem Operator stehenden Text ersetzt.
+
+____________________________________________________________________________
+ ............... Beispiel ..................... Zeile 4
+
+ gib kommando: "lb" C "lange bezeichnung"                   
+
+____________________________________________________________________________
+
+
+
+Bei Anwendung von 'CA' wird jedes Auftreten des gesuchten Textes ab der
+Cursorposition durch den Ersatztext ersetzt, bis das Dateiende errreicht ist.
+
+Weitere Erklärungen zum Suchen und Ersetzen in 5.5.
+#page#
+
+Weitere Hilfen
+
+
+Textabschnitt an anderer Stelle der Datei einsetzen:
+
+- Abschnitt markieren und mit #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#d#off("i")##off("b")# zwischenspeichern.
+
+- Zweites Editorfenster auf die Datei mit #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#e#off("i")##off("b")# öffnen.
+
+- Nach #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#ESC#off("i")##off("b")# Zeilennummer oder Suchbegriff angeben und mit #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#g#off("i")##off("b")# Abschnitt an der gewünschte Stelle einsetzen.
+
+
+
+Textabschnitt schnell herauskopieren und sichern:
+
+- Gewünschten Abschnitt markieren
+
+- #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#ESC#off("i")##off("b")# PUT("dateiname") #on("i")##on("b")#CR#off("i")##off("b")#
+ Der Abschnitt wird in die Datei 'dateiname' geschrieben. Falls die Frage 'dateina­
+ me' löschen (j/n) verneint wird, wird der Abschnitt, an das Ende der Datei angefügt.
+ Dadurch können Textabschnitte schnell gesammelt werden.
+
+
+Komplette Datei in die editierte Datei einfügen:
+
+- #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#ESC#off("i")##off("b")# GET("dateiname") #on("i")##on("b")#CR#off("i")##off("b")#
+ Der komplette Inhalt von 'dateiname' wird an die aktuelle Position geschrieben.
+
+
+Breitere Zeile erzeugen:
+
+- #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#ESC#off("i")##off("b")# limit(123) #on("i")##on("b")#CR#off("i")##off("b")#
+ Die Zeilenbreite wird auf 123 Zeichen geändert. Der maximal zulässige Wert ist
+ 16000. Dieser Wert bezieht sich auf den Zeilenumbruch. Bei Zeilenbreite > 77 wird
+ nur die aktuelle Zeile verschoben. Um für den ganzen Bildschirm die rechte Seite
+ der Datei zu sehen, kann die linken Spalte des Bildschirmfenster neu gesetzt wer­
+ den:
+
+ #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#ESC#off("i")##off("b")# margin(60) #on("i")##on("b")#CR#off("i")##off("b")#
+
+ Die Normaleinstellung wird durch 'limit(77)' und 'margin(1)' wiederhergestellt.
+
diff --git a/doc/programmer-manual/1.8.7/doc/programmierhandbuch.4 b/doc/programmer-manual/1.8.7/doc/programmierhandbuch.4
new file mode 100644
index 0000000..650d945
--- /dev/null
+++ b/doc/programmer-manual/1.8.7/doc/programmierhandbuch.4
@@ -0,0 +1,1692 @@
+#headandbottom("1","EUMEL-Benutzerhandbuch","TEIL 4 : Kommandosprache","4")#
+#pagenr("%",1)##setcount(1)##block##pageblock#
+#headeven#
+#center#EUMEL-Benutzerhandbuch
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#TEIL 4 : Kommandosprache
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+4 - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#4 - %
+#end#
+TEIL 4: Kommandosprache
+
+In Teil 4 sind diejenigen Kommandos beschrieben, die erfahrungsgemäß eher der
+Handhabung der Arbeitsumgebung zuzurechnen sind. Es ist den Verfassern bewußt,
+daß Auswahl und Zusammenstellung recht willkürlich sind, weil eine klare Abgrenzung
+zum Teil 5, welcher die Kommandos, die dem Thema: 'Programmierung' zugeordnet
+werden, nicht möglich ist.
+
+Der Teil 4 ist in die Themen:
+
+- 4.1. Supervisor-Kommandos
+
+- 4.2.1 Hilfs- und Informationsprozeduren
+
+- 4.2.2 Thesaurus
+
+- 4.2.3 Tasks
+
+- 4.2.4 Handhabung von Dateien
+
+- 4.2.5 Editor
+
+- 4.2.6 Dateitransfer
+
+- 4.2.7 Passwortschutz
+
+- 4.2.8 Archiv
+
+gegliedert. Insbesondere zu 4.2.4 ist anzumerken, daß nur Kommandos, die ganze
+Dateien betreffen hier erläutert sind. Kommandos, die Dateiinhalte betreffen (Suchen,
+Ersetzen etc.) sind in 3.5, bzw. 5.3 beschrieben.
+#page#
+
+4.1 Supervisor
+
+Es gibt genau sieben vom Supervisor akzeptierte Kommandos. Diese Kommandos
+können gegeben werden wenn nach dem Einschalten des Geräts oder dem Abkoppeln
+einer Task die SV-Taste gedrückt wurde und die sogenannte EUMEL-Tapete
+erscheint.
+
+____________________________________________________________________________
+
+ Terminal 2
+
+
+ EUMEL Version 1.8.1/M
+
+
+ gib supervisor kommando:
+
+
+
+
+ ESC ? --> help
+ ESC b --> begin("") ESC h --> halt
+ ESC c --> continue("") ESC s --> storage info
+ ESC q --> break ESC t --> task info
+
+____________________________________________________________________________
+
+
+
+
+Desweiteren kann <SV> in einer Task gedrückt werden, um durch <ESC> <h> einen
+Programmabbruch einzuleiten.
+
+Im Gegensatz zu den im weiteren beschriebenen, durch ELAN Prozeduren realisierten
+Kommandos, sind diese Supervisor-Kommandos nicht als Prozeduren im System und
+mithin nicht durch 'help (...)' anzeigbar.
+#page#
+'begin'
+ #on("b")#PROC begin (TEXT CONST taskname) #off("b")#
+ Richtet eine neue Task als Sohn von PUBLIC ein.
+
+
+ #on("b")#PROC begin (TEXT CONST taskname, vatertask) #off("b")#
+ Richtet eine neue Task als Sohn der Task 'vatertask' ein, falls die Vater-Task
+ eine Manager-Task ist. Falls diese Task keinen Managerstatus besitzt, passiert
+ nichts! In diesem Falle muß das Kommando durch <SV> abgebrochen werden.
+
+
+ FEHLER : "taskname" existiert bereits
+ "vatertask" gibt es nicht
+
+
+
+
+'continue'
+ #on("b")#PROC continue (TEXT CONST taskname) #off("b")#
+ Eine existierende Task wird an das Terminal des Benutzers angekoppelt.
+
+ FEHLER : "taskname" gibt es nicht
+
+
+ Falls 'begin' oder 'continue' trotz korrekter Voraussetzungen kein Resultat zeigen,
+ 'hängt' die betroffene Task. Beim 'begin' Kommando kann das der Fall sein, falls
+ die Vater-Task nicht durch 'break' abgekoppelt wurde, sondern mit < SV > verlas­
+ sen wurde. In diesem Fall muß das Kommando durch <SV> abgebrochen werden,
+ die Vater-Task angekoppelt und mit <ESC> <q> korrekt abgekoppelt werden.
+#page#
+'break'
+ #on("b")#PROC break #off("b")#
+ Das Terminal wird vom Rechner abgekoppelt.
+
+
+
+'halt'
+ #on("b")#PROC halt #off("b")#
+ Das laufende Programm der dem Terminal aktuell zugeordneten Task wird abge­
+ brochen.
+
+ Falls in der an das Terminal gekoppelten Task ein laufendes Programm abgebro­
+ chen werden soll, muß zunächst durch <SV> der Supervisor aufgerufen werden.
+ Durch das Supervisor-Kommando 'halt' wird der Fehler 'halt from terminal'
+ induziert. Das Programm wird wie durch jeden anderen Fehler abgebrochen, falls
+ nicht 'disable stop' gesetzt wurde!
+
+
+
+#page#
+'storage info'
+ #on("b")#PROC storage info #off("b")#
+ Informationsprozedur über den belegten und den verfügbaren Hintergrund-Spei­
+ cher des gesamten Systems in KByte#u#1)#e#.
+
+#foot#
+
+ 1) Bei der derzeit aktuellen '+' Version EUMEL 1.8.1/M+ sind die beiden Anga­
+ ben mit 4 zu multiplizieren !
+#end#
+ Das Terminal wird unmittelbar abgekoppelt!
+
+
+
+'task info'
+ #on("b")#PROC task info #off("b")#
+ Informiert über alle Tasknamen im System unter gleichzeitiger Angabe der Vater/
+ Sohn-Beziehungen durch Einrückungen.
+
+
+
+
+'help'
+ #on("b")#PROC help #off("b")#
+ Kurzbeschreibung der SV-Kommandos.
+#page#
+
+4.2 Monitor
+
+Unter dem Stichwort Monitor-Kommandos sind an dieser Stelle Kommandos be­
+schrieben, die ständig zur Handhabung der Arbeitsumgebung benutzt werden.
+Gleichwohl sei sofort darauf hingewiesen, daß jedes ELAN Programm dem Monitor zur
+Ausführung übergeben werden kann. Es gibt also keine speziellen Monitor-
+Kommandos, sondern nur eine Reihe von Prozeduren (=Kommandos), die in dieser
+Umgebung erfahrungsgemäß besonders häufig benutzt werden.
+
+
+#on("u")#4.2.1 Hilfs- und Informationsprozeduren#off("u")#
+
+- Pakete, Prozeduren : packets, bulletin , help
+ Parameter
+
+- Tasksystem zeigen : task info , task status
+
+- Speicherplatz zeigen : storage , storage info
+
+
+#on("u")#4.2.2 Thesaurus #off("u")#
+
+- besondere Thesauri : ALL , all , SOME , remainder
+
+- Verknüpfung : + , - , /
+
+
+#on("u")#4.2.3 Taskoperationen#off("u")#
+
+- besondere Tasknamen : archive , brother , father , myself
+ printer , public , son , supervisor
+- Terminal abkoppeln : break
+- Task löschen : end
+- Manager-Task : global manager , free global manager
+- Umbenennen der Task : rename myself
+
+#page#
+#on("u")#4.2.4 Handhabung von Dateien #off("u")#
+
+ : copy , edit , forget , list , rename , show
+
+
+#on("u")#4.2.5 Editor #off("u")#
+
+- Editieren : edit , editget , show
+- Tastenbelegung : kommando auf taste (legen) ,
+ lernsequenz auf taste (legen) ,
+ std tastenbelegung ,
+ taste enthält kommando ,
+ word wrap
+
+
+#on("u")#4.2.6 Transfer #off("u")#
+
+- Datei holen : fetch , fetchall
+- Datei senden : save , saveall
+- Drucken : print
+- Datei löschen : erase
+
+
+#on("u")#4.2.7 Passwortschutz #off("u")#
+
+- 'begin' absichern : begin password
+- 'continue' absichern : task password
+- Dateien absichern : enter password
+- Systemzweig sichern : family password
+
+
+#on("u")#4.2.8 Das Archiv #off("u")#
+
+- Reservieren/freigeben : archive , release
+- Formatieren : format
+- Löschen : clear
+- Kontrollesen : check
+
+
+#page#
+
+4.2.1 Hilfsprozeduren
+
+Die drei Prozeduren listen ihre Ausgabe jeweils in eine temporäre Datei, die mit
+'show' (s. 4.2.5) gezeigt wird.
+
+
+'packets'
+ #on("b")#PROC packets #off("b")#
+ Auflisten der Namen aller insertierten Pakete in der Task.
+
+
+
+
+
+
+'bulletin'
+ #on("b")#PROC bulletin (TEXT CONST paket name) #off("b")#
+ Listen aller in der DEFINES-Liste des Pakets mit dem Namen "paket name"
+ enthaltenen Prozeduren.
+
+ FEHLER : ... ist kein Paketname
+
+
+ #on("b")#PROC bulletin #off("b")#
+ Es wird eine Liste aller bisher insertierten Objekte erstellt. Diese Liste ist paket­
+ weise sortiert. 'bulletin' zeigt also eine Liste #on("u")#aller#off("u")# Prozeduren an, die in der Task
+ benutzt werden können.
+#page#
+'help'
+ #on("b")#PROC help (TEXT CONST name) #off("b")#
+ Listen aller Prozeduren / Operatoren mit dem Namen "name". Der Name des
+ Packets in dessen Schnittstelle die Prozedur steht wird mit ausgegeben.
+
+ Falls es kein Objekt des erfragten Namens gibt, erfolgt die Ausgabe:
+
+ unbekannt "name".
+
+ Beispiel:
+____________________________________________________________________________
+
+ gib kommando :
+ help("save")
+
+____________________________________________________________________________
+
+
+ liefert:
+
+____________________________________________________________________________
+
+PACKET nameset:
+
+ save........... (THESAURUS CONST, TASK CONST)
+ save........... (THESAURUS CONST)
+
+PACKET globalmanager:
+
+ save........... (DATASPACE CONST, TEXT CONST, TASK CONST)
+ save........... (TEXT CONST, TASK CONST)
+ save........... (TEXT CONST)
+ save...........
+
+____________________________________________________________________________
+
+
+
+ Desweiteren kann auch nach Prozedurnamen gesucht werden, die nur annähernd
+ bekannt sind, indem ein Suchmuster spezifiziert wird. Das Suchmuster besteht aus
+ dem bekannten Teil des Namens und dem Operator '*', der vor und/oder nach
+ dem Suchbegriff gesetzt werden kann. '*' bezeichnet eine beliebige (auch leere)
+ Zeichenkette.
+
+ Beispiel: Gesucht werden die verschiedenen 'info' Prozeduren:
+
+____________________________________________________________________________
+ gib kommando :
+ help("*info*")
+
+____________________________________________________________________________
+
+
+
+____________________________________________________________________________
+
+ taskinfo....... (INT CONST, INT CONST)
+ taskinfo....... (INT CONST, FILE VAR)
+ taskinfo....... (INT CONST)
+ taskinfo.......
+ editinfo....... (FILE VAR, INT CONST)
+ editinfo....... (FILE CONST) --> INT
+ storageinfo....
+
+____________________________________________________________________________
+
+
+
+ Dieser Stern darf nicht mit dem 'joker' des 'Pattern Matching' verwechselt werden.
+ In der 'help' Prozedur darf '*' #on("u")#nicht#off("u")# in den Suchbegriff eingesetzt werden, sondern
+ nur an Wortanfang und -Ende gesetzt werden.
+
+
+#page#
+
+Informationsprozeduren
+
+'storage'
+ #on("b")#INT PROC storage (TASK CONST task) #off("b")#
+ Informationsprozedur über den logisch belegten Hintergrund-Speicher der Task.
+ (Angabe in KByte, bzw. 4KB Einheiten bei der '+'-Version)
+
+
+____________________________________________________________________________
+
+ gib kommando :
+ put(storage(myself))
+ 1234
+
+ gib kommando :
+
+____________________________________________________________________________
+
+
+'storage info'
+ #on("b")#PROC storage info #off("b")#
+ Informationsprozedur über den belegten und den verfügbaren Hintergrund-Spei­
+ cher des gesamten Systems. Die Ausgabe erfolgt in KByte, bei der aktuellen
+ '+'-Version in 4 KByte Einheiten.
+
+
+____________________________________________________________________________
+
+ gib kommando :
+ storage info
+ 1234K von 12000K
+
+ gib kommando :
+____________________________________________________________________________
+#page#
+
+'task info'
+ #on("b")#PROC task info #off("b")#
+ Informiert über alle Tasknamen im System unter gleichzeitiger Angabe der Vater/
+ Sohn-Beziehungen (Angabe durch Einrückungen).
+
+
+ #on("b")#PROC task info (INT CONST art) #off("b")#
+ Informiert über alle Tasks im System. Mit 'art' kann man die Art der Zusatz-
+ Information auswählen.
+
+ art=1: entspricht 'task info' ohne Parameter, d.h. es gibt nur die Tasknamen
+ unter Angabe der Vater/Sohn-Beziehungen aus.
+
+ art=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#u#1)#e#.
+ 5 i/o -blocked Task wartet auf I/O, ist aber blockiert.
+ 6 wait-blocked Task wartet auf Sendung, ist aber blockiert. Ach­
+ tung: Die Task wird beim Eintreffen einer Sendung
+ automatisch entblockiert.
+ > 6 dead
+
+ art=3: wie 2, aber zusätzlich wird der belegte Speicher angezeigt. (Achtung:
+ Prozedur ist zeitaufwendig!).
+
+#foot#
+
+1) Eine Blockierung kann von 'Scheduler' veranlaßt werden
+ (siehe Systemhandbuch)
+#end#
+
+#page#
+____________________________________________________________________________
+
+ gib kommando :
+ task info(2)
+
+____________________________________________________________________________
+
+
+
+ liefert:
+
+____________________________________________________________________________
+
+ ............................ ...............................
+ 15.05.87 10:39 CPU PRIO CHAN STATUS
+ SUPERVISOR.......................... 0000:19:47 0 - wait
+ -................................ 0000:07:54 0 - wait
+ SYSUR............................ 0000:34:02 0 - wait
+ shutup dialog................ 0000:05:26 0 - i/o
+ configurator................. 0000:04:17 0 - wait
+ OPERATOR..................... 0000:00:14 0 - i/o
+ ARCHIVE...................... 0000:10:33 0 31 wait
+ net.......................... 0006:41:56 0 - wait
+ net timer................ 0000:02:48 2 - i/o
+ net port................. 0000:40:23 0 7 wait
+ PRINTER...................... 0000:05:59 0 - wait
+ -........................ 0000:00:11 0 - wait
+ UR.................................. 0000:02:11 0 - wait
+ PUBLIC........................... 0002:02:03 0 - wait
+ task1........................ 0000:41:50 0 - -busy-
+ task2........................ 0000:03:10 0 - i/o
+ task3........................ 0000:57:28 0 1 -busy-
+
+____________________________________________________________________________
+
+
+#page#
+
+
+ #on("b")#PROC task info (INT CONST art, FILE VAR infodatei) #off("b")#
+ Wie oben, die Ausgabe wird jedoch in die Datei 'infodatei' geschrieben.
+
+____________________________________________________________________________
+
+ FILE VAR info := sequential file(output,"infodatei") ;
+ taskinfo(3, info);
+
+____________________________________________________________________________
+
+
+ #on("b")#PROC task info ( INT CONST art, stationsnr) #off("b")#
+ Ermöglicht im Netzbetrieb 'task info' über die Station mit der Nummer 'stationsnr'.
+
+____________________________________________________________________________
+
+ gib kommando :
+ taskinfo(1,12) ;
+
+____________________________________________________________________________
+#page#
+'task status'
+
+ #on("b")#PROC task status #off("b")#
+ Informationsprozedur über den Zustand der eigenen Task. Informiert ü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.
+
+ #on("b")#PROC task status (TASK CONST t) #off("b")#
+ Wie obige Prozedur, aber über die Task mit dem internen Tasknamen 't'.
+
+
+____________________________________________________________________________
+
+ gib kommando :
+ task status (public)
+
+ 15.05.87 10:30 TASK: PUBLIC
+
+ Speicher: 1234K
+ CPU Zeit: 0011.12:23
+ Zustand : wait, (Prio 0), Kanal -
+
+____________________________________________________________________________
+#page#
+
+4.2.2 Thesaurus
+
+Ein #ib#Thesaurus#ie# ist ein #ib#Namensverzeichnis#ie#, das bis zu 200 Namen beinhalten kann.
+Dabei muß jeder Namen mindestens ein Zeichen und darf höchstens 100 Zeichen
+lang sein. Steuerzeichen (code < 32) in Namen werden umgesetzt (siehe 2.9.2).
+
+Thesauri werden unter anderem von der Dateiverwaltung benutzt, um das Dateiver­
+zeichnis einer Task zu führen.
+
+Man kann einen Thesaurus selbst erstellen, indem eine Datei z.B. mit Namen von
+Dateien gefüllt wird. Diese Datei kann dann als Thesaurus für weitere Aktionen die­
+nen.
+
+
+
+- Thesaurus liefern : ALL , all , SOME , remainder
+- Auswählen : LIKE
+- Verknüpfen : + , - , /
+
+
+
+#on("b")#ACHTUNG#off("b")# : Bei der Verwendung von Thesaurus Operationen in Verbindung mit
+'fetch', 'save' etc. ist zu beachten, daß mit 'SOME', 'ALL' und 'all' zunächst nur eine
+Auswahl aus einer Liste getroffen wird. Zusätzlich muß das Ziel oder die Quelle des
+Dateitransfers vereinbart werden.
+
+Ein beliebter Fehler ist z.B.: 'fetch (ALL archive)'.
+
+Hier ist nicht weiter spezifiziert, von wo Dateien geholt werden sollen - also werden
+sie von 'father' geholt! (s. 4.2.5)
+
+Falls die Dateien vom Archiv geholt werden sollen, ist das Archiv als Quelle zu be­
+nennen:
+
+Also : 'fetch (ALL archive, archive)' = Hole alle Dateien, die in dem Thesaurus von
+ 'archive' sind von der Task 'archive'.
+#page#
+'ALL'
+ THESAURUS OP ALL (TASK CONST task)
+ Liefert einen Thesaurus, der alle Dateinamen der angegebenen Task enthält.
+
+
+
+ #on("b")#THESAURUS OP ALL (TEXT CONST dateiname) #off("b")#
+ Liefert einen Thesaurus, der die in der angegebenen Datei vorhandenen Namen
+ (jede Zeile ein Name) enthält.
+
+
+
+
+'all'
+ #on("b")#THESAURUS PROC all #off("b")#
+ Liefert einen Thesaurus, der alle Dateinamen der eigenen Task enthält. Entspricht
+ 'ALL myself'.
+
+
+
+
+'SOME'
+ #on("b")#THESAURUS OP SOME (THESAURUS CONST thesaurus) #off("b")#
+ Bietet den angegebenen Thesaurus zum editieren an. Dort können nicht erwünsch­
+ te Namen gestrichen werden.
+
+
+
+ #on("b")#THESAURUS OP SOME (TASK CONST task) #off("b")#
+ Aufruf von: SOME ALL task.
+
+
+ #on("b")#THESAURUS OP SOME (TEXT CONST dateiname) #off("b")#
+ Aufruf von: SOME ALL dateiname.
+
+#page#
+'remainder'
+ #on("b")#PROC remainder #off("b")#
+ Liefert nach einem 'errorstop' die noch nicht bearbeiteten Dateien.
+
+____________________________________________________________________________
+
+ gib kommando :
+ save all (archive)
+
+ '"....." kann nicht geschrieben werden (Archiv voll)'
+
+____________________________________________________________________________
+
+
+
+ Nachdem man eine neue Floppy ins Archivlaufwerk gelegt hat, kann man mit
+
+
+____________________________________________________________________________
+ gib kommando :
+ save (remainder, archive)
+
+____________________________________________________________________________
+
+ den Rest der Dateien auf die nächste Floppy sichern.
+#page#
+'LIKE'
+ #on("b")#THESAURUS OP LIKE (THESAURUS CONST thesaurus, TEXT CONST muster) #off("b")#
+ Alle im Thesaurus enthaltenen Dateien, die dem 'muster' entsprechen sind im
+ Ergebnisthesaurus enthalten.
+
+ (Die Syntax von 'muster' ist bei der Beschreibung des Pattern-Matching (5.4)
+ beschrieben)
+
+
+____________________________________________________________________________
+
+ gib kommando :
+ print (all LIKE "*.p")
+
+____________________________________________________________________________
+
+
+ Alle Dateien, deren Name mit '.p' endet, werden gedruckt.
+
+#page#
+'+'
+ #on("b")#THESAURUS OP + (THESAURUS CONST links, rechts) #off("b")#
+ Liefert die Vereinigungsmenge von 'links' und 'rechts'.
+ Achtung: Die Vereinigungsmenge enthält keine Namen mehrfach.
+
+ #on("b")#THESAURUS OP + (THESAURUS CONST links, TEXT CONST rechts)#off("b")#
+ Fügt dem Thesaurus 'rechts' zu, wenn 'rechts' noch nicht im Thesaurus enthal­
+ ten ist.
+
+
+
+
+'-'
+ #on("b")#THESAURUS OP - (THESAURUS CONST links, rechts) #off("b")#
+ Liefert die Differenzmenge. Achtung: Die Differenzmenge enthält keine Namen
+ mehrfach.
+
+ #on("b")#THESAURUS OP - (THESAURUS CONST links, TEXT CONST rechts)#off("b")#
+ Nimmt den Namen 'rechts' aus dem Thesaurus.
+
+____________________________________________________________________________
+
+ gib kommando :
+ fetch(ALL father - ALL myself)
+
+____________________________________________________________________________
+
+
+'/'
+ #on("b")#THESAURUS OP / (THESAURUS CONST links, rechts) #off("b")#
+ Liefert die Schnittmenge
+ Achtung: Die Schnittmenge enthält keine Namen mehrfach.
+
+
+#page#
+
+4.2.3 Tasks
+
+Zur Identifizierung von Tasks dienen sogenannte 'interne Taskbezeichner'. Ein solcher
+Taskbezeichner wird beim Einrichten einer neuen Task vergeben. Interne Taskbe­
+zeichner sind auch unter Berücksichtigung der Zeit eindeutig.
+
+Der Zugriff auf interne Taskbezeichner erfolgt über Prozeduren und Operatoren, die
+auf Objekte des Datentyps TASK (siehe 2.9.1) angewandt werden.
+
+Zusätzlich zum internen Tasknamen, der nicht auszugeben ist, haben Tasks meistens
+einen Namen#u#1) #e#.
+#foot#
+
+1) Unbenannte Tasks haben den Pseudonamen "-".
+#end#
+
+Aus Benutzersicht können benannte Tasks innerhalb eines Rechners vollständig und
+eindeutig über ihren Namen identifiziert werden.
+
+
+- Task liefern : / , task , niltask
+
+- Verwandtschaften : brother , father , myself , son
+
+- Ausgezeichnete Tasks : archive , printer , public , supervisor
+
+- Namen liefern : name
+
+- Tasknamen ändern : rename myself
+
+- Reservieren bes. Tasks : reserve
+
+#page#
+'/'
+ #on("b")#TASK OP / (TEXT CONST taskname) #off("b")#
+ Liefert die Task des angegebenen Namens, falls sie existiert. Der eigene Katal­
+ og wird automatisch aktualisiert
+
+ (identisch mit der PROC task (TEXT CONST taskname).
+
+ FEHLER : "taskname" gibt es nicht
+
+
+ #on("b")#TASK OP / (INT CONST station number, TEXT CONST name) #off("b")#
+ Liefert im Netzbetrieb die Task des angegebenen Namen von der Station mit der
+ angegebenen Nummer.
+
+
+
+'niltask'
+ #on("b")#TASK CONST niltask #off("b")#
+ Bezeichner für "keine Task". So liefern die Prozeduren 'son', 'brother' und 'father'
+ als Resultat 'niltask', wenn keine Sohn-, Bruder- oder Vatertask existiert.
+
+
+
+'task'
+ #on("b")#TASK PROC task (TEXT CONST taskname) #off("b")#
+ Liefert die Task des angegebenen Namens, falls sie existiert. Der eigene Katal­
+ og wird automatisch aktualisiert.
+
+ FEHLER : "taskname" gibt es nicht
+
+
+ #on("b")#TASK PROC task (INT CONST channel number) #off("b")#
+ Liefert den Namen der Task, die an dem angegebenen Kanal hängt.
+#page#
+'brother'
+ #on("b")#TASK PROC brother (TASK CONST task) #off("b")#
+ Liefert den nächsten Bruder von 'task'. Falls kein Bruder existiert, wird 'niltask'
+ geliefert. Aktualisiert den eigenen Katalog nicht automatisch!
+
+
+
+'father'
+ #on("b")#TASK PROC father #off("b")#
+ Liefert die eigene Vatertask.
+
+
+ #on("b")#TASK PROC father (TASK CONST task) #off("b")#
+ Liefert den Vater von 'task'. Existiert kein Vater (z.B. bei UR), wird niltask gelie­
+ fert. Aktualisiert den eigenen Katalog nicht automatisch!
+
+
+
+'myself'
+ #on("b")#TASK PROC myself #off("b")#
+ Liefert eigenen Task-Bezeichner.
+
+
+
+'son'
+ #on("b")#TASK PROC son (TASK CONST task) #off("b")#
+ Liefert den ersten Sohn von 'task'. Falls keiner im Katalog vermerkt ist, wird
+ 'niltask' geliefert. Aktualisiert den eigenen Katalog nicht automatisch!
+
+
+#page#
+'archive'
+ #on("b")#TASK PROC archive #off("b")#
+ Liefert den internen Taskbezeichner der aktuellen Task mit Namen ARCHIVE.
+ Diese Prozedur dient zum schnellen und bequemen Ansprechen der Archivtask.
+
+
+
+'printer'
+ #on("b")#TASK PROC printer #off("b")#
+ Liefert den internen Taskbezeichner der aktuellen Task mit Namen #ib#PRINTER#ie#.
+ Diese Prozedur dient zum schnellen und bequemen Ansprechen des Druckspoo­
+ lers.
+
+
+'public'
+ #on("b")#TASK PROC public #off("b")#
+ Liefert den internen Taskbezeichner der Task #ib#PUBLIC#ie#.
+
+
+
+
+'supervisor'
+ #on("b")#TASK PROC supervisor #off("b")#
+ Liefert den internen Taskbezeichner des Supervisors.
+
+
+#page#
+'name'
+ #on("b")#TEXT PROC name (TASK CONST task) #off("b")#
+ Liefert den Namen von 'task'. Die Task muß noch im System existieren, sonst ist
+ der Name nicht mehr bekannt. Falls die 'task' noch nicht im eigenen Katalog
+ enthalten ist, wird er aktualisiert.
+
+
+
+'rename myself'
+ #on("b")#PROC rename myself (TEXT CONST neuer name) #off("b")#
+ Name der eigenen Task wird in 'neuer name' geändert. Wirkt wie Löschung und
+ Wiedereinrichten der Task in Bezug auf alle TASK VAR's die sich auf diese Task
+ beziehen.
+
+ FEHLER : Task existiert bereits
+ Name unzulässig
+ => anderen Namen wählen
+
+
+
+'reserve'
+ #on("b")#PROC reserve (TASK CONST task) #off("b")#
+ Reservieren einer Task für den ausschließlichen Dialog mit der Task, in der das
+ Kommando gegeben wurde.
+
+ #on("b")#PROC reserve (TEXT CONST message, TASK CONST task) #off("b")#
+ Wie 'reserve (TASK CONST task)' mit Übergabe einer 'message'.
+
+
+ Die reservierte Task muß ein spezieller Manager, (z.B. /"DOS" aus dem Werkzeug
+ MS-DOS-DAT) sein !
+#page#
+
+4.2.4 Handhabung von Dateien
+
+'copy'
+ #on("b")#PROC copy (TEXT CONST quelle, ziel) #off("b")#
+ Kopiert die Datei 'quelle' in eine neue Datei mit dem Namen 'ziel' in der Benut­
+ zer-Task.
+
+ FEHLER : "ziel" existiert bereits
+ "quelle" gibt es nicht
+ zu viele Dateien
+
+
+
+'forget'
+ #on("b")#PROC forget (TEXT CONST dateiname) #off("b")#
+ Löschen einer Datei mit dem Namen 'dateiname' in der Benutzer-Task.
+
+ FEHLER : "datei" gibt es nicht
+
+
+ #on("b")#PROC forget (THESAURUS CONST thesaurus) #off("b")#
+ Löscht die im 'thesaurus' enthaltenen Dateien in der Benutzer-Task.
+
+ Im Dialog erfolgt vor dem Löschen einer Datei standardmäßig die Abfrage:
+
+
+____________________________________________________________________________
+
+ gib kommando :
+ forget("einedatei")
+ "einedatei" löschen(j/n) ?
+
+____________________________________________________________________________
+
+#page#
+'list'
+ #on("b")#PROC list #off("b")#
+ Listet alle Dateien der Benutzer-Task mit Namen und Datum des letzten Zugriffs
+ auf dem Terminal auf.
+
+
+ #on("b")#PROC list (TASK CONST task) #off("b")#
+ Listet alle Dateien der angegebenen 'task' mit Namen und Datum der letzten
+ Änderung auf dem Terminal auf. Die Task muß Manager sein.
+
+
+ #on("b")#PROC list (FILE VAR liste) #off("b")#
+ Listet alle Dateinamen in die Datei 'liste', die mit 'output'(s. 5.3.5) assoziiert sein
+ muß.
+
+
+ #on("b")#PROC list (FILE VAR liste, TASK CONST manager) #off("b")#
+ Listet alle Dateien der Task 'manager' mit Namen und Datum der letzten Ände­
+ rung in die Datei 'liste'.
+
+
+____________________________________________________________________________
+
+ gib kommando :
+ FILE VAR f:= sequential file (output,"list");list(f,archive)
+
+____________________________________________________________________________
+
+#page#
+'rename'
+ #on("b")#PROC rename (TEXT CONST altername, neuername) #off("b")#
+ Umbenennen einer Datei von 'altername' in 'neuername'.
+
+
+
+ FEHLER : "neuername" gibt es bereits
+ "altername" gibt es nicht
+#page#
+
+4.2.5 Editor-Prozeduren
+
+'edit'
+ #on("b")#PROC edit (TEXT CONST dateiname) #off("b")#
+ Ruft den Editor mit 'dateiname' auf.
+
+
+ #on("b")#PROC edit #off("b")#
+ 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 'edit' zum ersten Mal aufgerufen, nimmt das Fenster den gesamten Bild­
+ schirm ein. Bei erneutem 'edit'-Aufruf wird ein Fenster nach rechts unten ab der
+ aktuellen Cursor-Position eröffnet.
+
+
+ #on("b")#PROC edit (THESAURUS CONST t) #off("b")#
+ Editieren aller in dem Thesaurus 't' enthaltenen Dateien nacheinander.
+
+
+ Weitere 'edit-Prozeduren', die z.B. Variation der Fenstergröße etc. zulassen, sind
+ in 5.4.6 beschrieben.
+
+#page#
+'editget'
+ #on("b")#PROC editget (TEXT VAR editsatz) #off("b")#
+ Ausgabe einer (Kommando)zeile, in der Editorfunktionen zur Verfügung
+ stehen siehe Teil 5.5.1.4.
+
+
+
+'show'
+ #on("b")#PROC show (TEXT CONST dateiname) #off("b")#
+ Die Datei wird am Bildschirm gezeigt. Positionierung und Suchen funktionieren wie
+ in 'edit', Aktionen die Änderungen in der Datei bewirken würden, werden nicht
+ angenommen.
+
+
+
+ #on("b")#PROC show #off("b")#
+ 'show' auf der zuletzt bearbeiteten Datei.
+
+#page#
+'kommando auf taste legen'
+ #on("b")#PROC kommando auf taste legen (TEXT CONST taste, elan programm)#off("b")#
+ Die Taste 'taste' wird mit dem angegebenen ELAN-Programm belegt. Durch <ESC>
+ <taste> wird das Programm direkt ausgeführt.
+
+____________________________________________________________________________
+
+ gib kommando :
+ kommando auf taste legen ("a","fetch (SOME archive,archive)")
+
+____________________________________________________________________________
+
+
+
+'kommando auf taste'
+ #on("b")#TEXT PROC kommando auf taste (TEXT CONST taste)#off("b")#
+ Falls 'taste' mit einem ELAN-Programm belegt ist, liefert die Prozedur den
+ Programmtext, andernfalls den leeren Text niltext.
+
+____________________________________________________________________________
+
+ gib kommando :
+ put (kommando auf taste("f"))
+
+____________________________________________________________________________
+
+
+
+'taste enthaelt kommando'
+ #on("b")#BOOL PROC taste enthaelt kommando (TEXT CONST taste)#off("b")#
+ Liefert TRUE falls 'taste' mit einem ELAN-Programm belegt ist.
+
+
+'lernsequenz auf taste legen'
+ #on("b")#PROC lernsequenz auf taste legen (TEXT CONST taste, sequenz)#off("b")#
+ 'taste' wird mit der Zeichenfolge 'sequenz' belegt. Durch <ESC> <taste> wird die
+ Zeichenfolge an der aktuellen Position ausgegeben.
+
+ Als Zeichenfolge sind natürlich auch einzelne Zeichen und EUMEL-Codes zuläs­
+ sig.
+
+ Die vom System vorbelegten Tasten sind in 3.4 'Zeichen schreiben' aufgelistet.
+
+____________________________________________________________________________
+
+ gib kommando :
+ lernsequenz auf taste legen ("x","gib kommando :"13""2""2"")
+
+____________________________________________________________________________
+
+
+
+'lernsequenz auf taste'
+ #on("b")#TEXT PROC lernsequenz auf taste (TEXT CONST taste) #off("b")#
+ Liefert die auf 'taste' gelegte Zeichenfolge.
+
+
+'std tastenbelegung'
+ #on("b")#PROC std tastenbelegung #off("b")#
+ Die Standard-Tastenbelegung (s.3.4) wird (wieder) hergestellt.
+
+
+'word wrap'
+ #on("b")#PROC word wrap (BOOL CONST b) #off("b")#
+ Der automatische Zeilenumbruch wird durch 'word wrap (FALSE)' aus- und durch
+ 'word wrap (TRUE)' eingeschaltet. Wird diese Prozedur während des Editierens
+ aufgerufen, gilt die Einstellung für die aktuelle Textdatei. Wird die Prozedur als
+ Monitor-Kommando gegeben, so gilt die Eingabe als Voreinstellung für neue
+ Dateien.
+#page#
+
+4.2.6 Dateitransfer
+
+Unter diesem Abschnitt sind diejenigen Prozeduren beschrieben, die der simplen
+Kommunikation mit Manager-Tasks dienen: Holen oder Senden einer Dateikopie,
+Löschen in der Manager-Task.
+
+#on("b")#ACHTUNG : Für alle Prozeduren gilt: falls die Manager-Task nicht existiert, wird eine
+Fehlermeldung erzeugt, existiert eine Task des angegebenen Namens, die aber nicht
+Managertask ist, so terminieren die Prozeduren nicht!
+#off("b")#
+
+
+'fetch'
+ #on("b")#PROC fetch (TEXT CONST dateiname, TASK CONST manager) #off("b")#
+ Kopiert die Datei 'dateiname' aus der Task 'manager'
+
+
+ #on("b")#PROC fetch (THESAURUS CONST th, TASK CONST manager) #off("b")#
+ Kopiert alle Dateien, deren Namen im Thesaurus th enthalten sind, aus der Task
+ 'manager'.
+
+
+____________________________________________________________________________
+
+ gib kommando :
+ fetch(ALL(12/"PUBLIC"), 12/"PUBLIC")
+
+____________________________________________________________________________
+
+
+
+ Mit diesem Kommando werden (in einem EUMEL Netz) alle Dateien der Task
+ 'PUBLIC' des Rechners mit der Stationsnummer 12 in diesem Netz kopiert.
+
+#page#
+____________________________________________________________________________
+
+ gib kommando :
+ fetch(SOME archive , archive)
+
+____________________________________________________________________________
+
+
+
+ Bietet den Thesaurus von 'ARCHIVE' an, nach Auswahl werden alle Dateien deren
+ Namen nicht gelöscht wurden, von der Diskette kopiert.
+
+
+ #on("b")#PROC fetch (TEXT CONST dateiname) #off("b")#
+ Kopiert die Datei 'dateiname' aus der Task 'father'
+
+
+ #on("b")#PROC fetch (THESAURUS CONST th) #off("b")#
+ Kopiert alle Dateien, deren Namen in 'th' sind aus der Task 'father'.
+
+
+
+'fetchall'
+
+ #on("b")#PROC fetchall #off("b")#
+ entspricht: fetch (ALL father, father)
+
+
+ #on("b")#PROC fetchall (TASK CONST manager)#off("b")#
+ entspricht: fetch(ALL manager, manager)
+
+#page#
+'save'
+ #on("b")#PROC save (TEXT CONST dateiname, TASK CONST manager) #off("b")#
+ Kopiert die Datei 'dateiname' in die Task 'manager'
+
+
+ #on("b")#PROC save (THESAURUS CONST th, TASK CONST manager) #off("b")#
+ Kopiert alle Dateien, deren Namen im Thesaurus th enthalten sind, in die Task
+ 'manager'.
+
+____________________________________________________________________________
+
+ gib kommando :
+ save(all, (12/"PUBLIC"))
+
+____________________________________________________________________________
+
+
+ Mit diesem Kommando werden (in einem EUMEL Netz) alle Dateien der eigenen
+ Task in die Task 'PUBLIC' des Rechners mit der Stationsnummer 12 in diesem
+ Netz kopiert.
+
+____________________________________________________________________________
+
+ gib kommando :
+ save(SOME myself, manager)
+
+____________________________________________________________________________
+
+
+ Bietet den eigenen Thesaurus an, nach Auswahl werden alle Dateien deren
+ Namen nicht gelöscht wurden, zur Task 'manager' kopiert.
+
+
+ #on("b")#PROC save (TEXT CONST dateiname) #off("b")#
+ Kopiert die Datei 'dateiname' in die Task 'father'
+
+
+ #on("b")#PROC save (THESAURUS CONST th) #off("b")#
+ Kopiert alle Dateien, deren Namen in 'th' enthalten sind, in die Task 'father'.
+
+
+ #on("b")#PROC save #off("b")#
+ Kopiert die zuletzt bearbeitete Datei in die Task 'father'
+
+
+
+
+'saveall'
+ #on("b")#PROC saveall #off("b")#
+ entspricht: save (all, father)
+
+
+ #on("b")#PROC saveall (TASK CONST manager) #off("b")#
+ entspricht: save (ALL myself, manager)
+
+#page#
+'erase'
+ #on("b")#PROC erase (TEXT CONST dateiname, TASK CONST manager) #off("b")#
+ Löscht die Datei 'dateiname' aus der Task 'manager'
+
+
+ #on("b")#PROC erase (THESAURUS CONST th, TASK CONST manager) #off("b")#
+ Löscht alle Dateien, deren Namen im Thesaurus th enthalten sind, aus der Task
+ 'manager'.
+
+
+ #on("b")#PROC erase (TEXT CONST dateiname) #off("b")#
+ Löscht die Datei 'dateiname' aus der Task 'father'
+
+
+ #on("b")#PROC erase (THESAURUS CONST th) #off("b")#
+ Löscht alle Dateien, deren Namen in 'th' sind, aus der Task 'father'
+
+
+ #on("b")#PROC erase #off("b")#
+ Löscht die zuletzt bearbeitete Datei aus der Task 'father'
+
+
+#page#
+'print'
+ Das Kommando 'print' beinhaltet den Auftrag an die Task 'PRINTER' die enthal­
+ tene(n) Datei(en) auszudrucken.
+
+ Voraussetzung ist natürlich, daß die Druckersoftware ordnungsgemäß benutzt
+ wurde, um 'PRINTER' einzurichten. Siehe dazu Systemhandbuch Teil 6.
+
+
+ #on("b")#PROC print (TEXT CONST dateiname) #off("b")#
+ Kopiert die Datei 'dateiname' in die Task 'PRINTER'.
+
+
+ #on("b")#PROC print (THESAURUS CONST th) #off("b")#
+ Kopiert alle Dateien, deren Namen im Thesaurus 'th' enthalten sind, in die Task
+ 'PRINTER'.
+
+
+ #on("b")#PROC print #off("b")#
+ Kopiert die zuletzt bearbeitete Datei in die Task 'PRINTER'.
+
+
+#page#
+
+4.2.7 Passwortschutz
+
+Der Passwortschutz im EUMEL-System ist in verschiedener Ausprägung möglich.
+Einfachste Möglichkeit ist der Schutz einer Task durch ein Passwort. Falls diese Task
+nicht Manager ist, können alle Daten und Programme, die nur in dieser Task zur
+Verfügung stehen, auch nur vom Besitzer der Task benutzt werden.
+
+Ähnlich kann auch von einer Manager-Task aus der gesamte Zweig unterhalb dieser
+Task mit einem Passwort geschützt werden: beispielsweise kann es empfehlenswert
+sein, den Systemzweig komplett zu schützen, indem in SYSUR ein entsprechendes
+Passwort vereinbart wird.
+
+Ein Umgehen des Passwortschutzes bei Manager-Tasks (durch Einrichten einer
+Sohn-Task und 'fetchall') wird durch ein 'begin password' verhindert.
+
+Auch einzelne Dateien lassen sich schützen, indem Lese/Schreibpasswörter für den
+Dateitransfer vereinbart werden.
+
+Generell gilt für die Verwendung von Passworten:
+
+- Passworte, die zu naheliegend gewählt sind (Vorname des Lebenspartners o.ä.)
+ sind meistens sinnlos, falls wirklich Datenschutz bezweckt ist.
+
+- Passworte, die so raffiniert sind, daß sogar ihr Schöpfer sie vergißt, führen zu
+ 100%igem Datenverlust, da die betroffene Task oder Datei nur noch gelöscht
+ werden kann.
+
+- Die Vereinbarung von "-" als Passwort bewirkt, daß die entsprechende Aktion
+ nicht mehr durchgeführt werden kann. Wird z.B. '-' als 'task password'
+ eingegeben, so kann die Task nie wieder an ein Terminal gekoppelt werden.
+
+- Passwörter können geändert werden, indem das entsprechende Kommando noch
+ einmal mit dem neuen Passwort gegeben wird.
+
+#page#
+'begin password'
+
+ #on("b")#PROC begin password (TEXT CONST passwort) #off("b")#
+
+ Auf Supervisor-Ebene wird vor Einrichten einer neuen Task als Sohn der Task in
+ der das 'begin password' gegeben wurde, dieses erfragt.
+
+ Das Password vererbt sich auf die hinzukommenden Sohn-Tasks.
+
+____________________________________________________________________________
+
+ #on("b")#SYSUR#off("b")#
+ maintenance :
+ begin password ("alles dicht")
+
+____________________________________________________________________________
+
+
+bewirkt:
+
+____________________________________________________________________________
+
+ Terminal 2
+
+
+ EUMEL Version 1.8.1/M
+
+
+ gib supervisor kommando:
+ begin ("sabotage","SYSUR")
+ Passwort:
+
+
+ ESC ? --> help
+ ESC b --> begin("") ESC h --> halt
+ ESC c --> continue("") ESC s --> storage info
+ ESC q --> break ESC t --> task info
+
+
+____________________________________________________________________________
+
+
+#page#
+'enter password'
+ #on("b")#PROC enter password (TEXT CONST datei, schreibpass, lesepass)
+ #off("b")#
+ Hiermit können ausgewählte Dateien einer Manager-Task geschützt werden. Die
+ angegebene Datei wird mit Schreib- und Lesepassword versehen. Die Pass­
+ wörter werden in der eigenen Task nicht berücksichtigt.
+
+ Bei einem lesenden Zugriff (fetch) von irgendeiner Task aus auf die entsprechende
+ Datei in der Manager-Task muß das Lesepasswort, bei schreibendem Zugriff
+ (save/erase) das Schreibpasswort vereinbart sein.
+
+
+____________________________________________________________________________
+
+ maintenance :
+ enter password ("wichtige datei","sicher","heit")
+
+____________________________________________________________________________
+
+
+
+
+ #on("b")#PROC enter password (TEXT CONST password) #off("b")#
+ Passwort für den Dateitransfer einstellen. Falls zwei verschiedene Passwörter für
+ Lesen und Schreiben vereinbart werden sollen, so sind sie als ein Text durch "/"
+ getrennt einzugeben.
+
+____________________________________________________________________________
+
+ gib kommando :
+ enter password ("sicher/heit")
+
+ gib kommando :
+ save(SOME all)
+
+____________________________________________________________________________
+#page#
+'family password'
+ #on("b")#PROC family password (TEXT CONST geheim) #off("b")#
+ Einstellen eines Passworts für den Zweig des Systems , der unterhalb der (Mana­
+ ger) Task liegt, in der das 'family password' eingegeben wurde. Dabei erhalten
+ alle Tasks, die kein Password oder dasselbe wie diese Manager-Task haben, das
+ 'family password'. Tasks in dem Zweig, die ein eigenes anderes besitzen, behal­
+ ten dieses.
+
+____________________________________________________________________________
+
+ PUBLIC
+
+ Task1 ""
+
+ Task2 family password("fingerweg")
+ Task21 geheim
+ Task22 ""
+
+ Task3 ""
+ Task31 ""
+
+____________________________________________________________________________
+
+
+
+
+bewirkt:
+
+____________________________________________________________________________
+ PUBLIC
+
+ Task1 ""
+
+ Task2 fingerweg
+ Task21 geheim
+ Task22 fingerweg
+
+ Task3 ""
+ Task31 ""
+
+____________________________________________________________________________
+
+
+#page#
+
+'task password'
+
+ #on("b")#PROC task password (TEXT CONST geheim) #off("b")#
+ Einstellen eines Passworts für die Task in der es gegeben wird. Ist eine Task mit
+ einem Passwort geschützt, so wird durch den Supervisor nach dem 'continue'-
+ Kommando das Passwort angefragt (Entsprechend dem 'begin password'). Nur
+ nach Eingabe des richtigen Passworts gelangt man in die gewünschte Task. Das
+ Passwort kann durch nochmaligen Aufruf von 'task password' geändert werden,
+ z.B. wenn es in regelmäßigen Abständen geändert werden muß, um personenbe­
+ zogene Daten zu schützen.
+
+#page#
+
+4.2.8 Das Archiv
+
+Mit dem Terminus 'Archiv' wird beim EUMEL-System ein Diskettenlaufwerk bezeich­
+net, das nur Datensicherungsaufgaben dient. Falls ein Rechner eins von zwei vorhan­
+denen Diskettenlaufwerk als Arbeitsspeicher benutzt, so wird dieses als Hintergrund
+bezeichnet. Falls Sie einen derartigen Rechner benutzen, können Sie der Installa­
+tionsanleitung entnehmen, welches Laufwerk welcher Aufgabe zugeordnet ist.
+
+Das #ib#Archiv#ie# übernimmt im EUMEL-System die Verwaltung der langfristigen Daten­
+haltung. Das Archiv sollen Sie benutzen, um:
+
+- Sicherungskopien wichtiger Dateien außerhalb des Rechners zu besitzen;
+
+- nicht benötigte Dateien außerhalb einer Task zu halten (Speicherplatzersparnis!);
+
+- Dateien auf andere Rechner zu übertragen.
+
+Das Archiv wird im EUMEL-System durch die Task 'ARCHIVE', die das Disketten­
+laufwerk des Rechners verwaltet, realisiert.
+
+- reservieren : archive
+
+- freigeben : release
+
+- löschen : clear , format
+
+- prüfen : check
+
+#page#
+'archive'
+ #on("b")#PROC archive (TEXT CONST archivname) #off("b")#
+ Reservierung der Task ARCHIVE für den exklusiven Dialog mit der aufrufenden
+ Task. 'archivname' wird bei allen folgenden Archivoperationen mit dem der Disket­
+ te zugewiesenen (und hoffentlich auf dem Aufkleber vermerkten) Namen abgegli­
+ chen.
+
+
+
+'release'
+ #on("b")#PROC release (TASK CONST archive) #off("b")#
+ Nach diesem Kommando kann die Task 'ARCHIVE' mit ihren Leistungen von einer
+ anderen Task in Anspruch genommen werden. Falls dieses Kommando nicht
+ gegeben wird, aber seit 5 Minuten kein Dialog mit 'archive' stattfand, kann eine
+ andere Task durch die Anforderung 'archive("diskettenname")' das Archiv reser­
+ vieren. Durch diese Maßnahme wird verhindert, daß ein vergeßlicher Benutzer bei
+ einem System mit mehreren Benutzern das Archiv blockiert.
+
+#page#
+
+'clear'
+ #on("b")#PROC clear (TASK CONST archive) #off("b")#
+ Löschen des Disketten-Inhaltsverzeichnisses und Zuweisung des in der Reservie­
+ rung eingegebenen Namens.
+
+____________________________________________________________________________
+
+ gib kommando :
+ archive("name"); #ib#clear#ie# (archive)
+
+____________________________________________________________________________
+
+
+ Durch die Ausführung des Kommandos erhält die eingelegte Diskette den in der
+ Reservierung angegebenen Namen. #on("b")#Das Inhaltsverzeichnis, das sich auf der
+ Diskette befindet, wird gelöscht. Damit sind die Daten, die sich eventuell auf
+ dieser Diskette befanden, nicht mehr auffindbar#off("b")#. Die Diskette entspricht einer neu
+ formatierten Diskette#u#1)#e#.
+
+ Man kann also eine beschriebene Diskette nicht umbenennen, ohne die darauf
+ befindlichen Daten zu löschen.
+
+ #foot#
+
+ #u#1)#e# Das Kommando 'format' enthält implizit 'clear'.
+#end#
+
+ Eine Neuformatierung ist demnach bei Wiederverwendung der Diskette nicht
+ notwendig.
+
+#page#
+'format'
+ #on("b")#PROC format (TASK CONST archive) #off("b")#
+ Formatieren einer Diskette. Vor der erstmaligen Benutzung einer Archivdiskette
+ muß diese formatiert, d.h. in Spuren und Sektoren für die Positionierung des
+ Schreib-/Lesekopfes des Diskettenlaufwerks eingeteilt werden, um überhaupt ein
+ Beschreiben der Diskette zu ermöglichen. Die Einteilung ist geräteabhängig, häufi­
+ ge Formate sind:
+
+ 40 Spuren zu je 9 Sektoren (360 K)
+ 80 Spuren zu je 9 Sektoren (720 K).
+
+ Die #on("b")#Erst#off("b")#benutzung einer #ib#Archivdiskette#ie# erfordert nach der Reservierung des Ar­
+ chivs das Kommando:
+
+____________________________________________________________________________
+
+ gib kommando :
+ archive("diskname");
+
+ gib kommando :
+ format (archive);
+
+____________________________________________________________________________
+
+
+Erst nach einer Kontrollabfrage:
+
+____________________________________________________________________________
+
+ gib kommando:
+ format (archive)
+
+ Archiv "diskname" formatieren ? (j/n)
+
+____________________________________________________________________________
+
+
+
+ wird tatsächlich formatiert und die Diskette steht mit dem Namen "diskname" für
+ Archivoperationen zur Verfügung.
+
+#page#
+
+ #on("b")#PROC format (INT CONST code, TASK CONST archive) #off("b")#
+ Bei einigen Rechnern ist es möglich, die Formatierung zu variieren. Falls beim
+ Formatieren auf einem solchen Rechner ein anderes als das Standardformat
+ erzeugt werden soll, so ist die Codierung des gewünschten Formats mitanzuge­
+ ben.
+
+
+ Beispiel: Für ein Gerät mit 5,25 Zoll Disketten wäre z.B. einstellbar:
+ code 0 : Standardformat
+ code 1 : 2D , 40 Spuren , 9 Sektoren
+ code 2 : 2D , 80 Spuren , 9 Sektoren
+ code 3 : HD , 80 Spuren ,15 Sektoren
+
+ 'format (archive)' erzeugt ebenso wie 'format (0,archive)' eine
+ standardformatierte Diskette, 'format (3,archive)' erzeugt eine High
+ Density Formatierung (HD Floppy benutzen!).
+
+#on("b")#
+ ACHTUNG: Wird eine bereits beschriebene Diskette noch einmal formatiert, so
+ sind alle Daten, die auf der Diskette waren, verloren.
+
+ Die Umformatierung einer Diskette (z.B. von 720K auf 360K) auf
+ unterschiedlichen Laufwerken kann zu Problemen führen.
+#off("b")#
+#page#
+'check'
+ #on("b")#PROC check (TEXT CONST dateiname, TASK CONST task) #off("b")#
+ Überprüft, ob die Datei 'dateiname' auf dem Archiv lesbar ist.
+
+
+ #on("b")#PROC check (THESAURUS CONST t, TASK CONST task) #off("b")#
+ Überprüft, ob die in dem Thesaurus 't' enthaltenen Dateien auf dem Archiv lesbar
+ sind.
+
+
+ Mit diesem Kommando kann nach dem Beschreiben einer Diskette überprüft wer­
+ den, ob die Datei(en) lesbar sind. Hierdurch können also verschmutzte oder
+ beschädigte Disketten erkannt werden.
+
+
+____________________________________________________________________________
+
+ gib kommando :
+ save (all , archive)
+
+ gib kommando :
+ check (ALL archive, archive)
+
+____________________________________________________________________________
+
+#page#
+
+Beispiel:
+
+
+____________________________________________________________________________
+
+ gib kommando :
+ archive ("neu")
+
+ gib kommando :
+ format (archive)
+
+____________________________________________________________________________
+
+
+liefert zunächst die Kontollfrage:
+
+____________________________________________________________________________
+
+ gib kommando :
+ format (archive)
+
+ Archiv "neu" formatieren ? (j/n)
+
+____________________________________________________________________________
+
+
+Nach Eingabe 'j'
+
+____________________________________________________________________________
+
+ gib kommando :
+ saveall (archive)
+
+ gib kommando :
+ archive("alt") (* nächste Diskette *)
+
+ gib kommando :
+ fetch(SOME archive ,archive)
+
+____________________________________________________________________________
+
+
+Der Thesaurus des Archivs wird angezeigt:
+#page#
+____________________________________________________________________________
+
+ .................alt (100 K belegt von 720 K)...............
+
+ 01.02.87 25 K "handbuch teil 1"
+ 01.03.87 23 K "handbuch teil 2"
+ 01.04.87 20 K "handbuch teil 3"
+ 01.05.87 32 K "handbuch teil 4"
+
+____________________________________________________________________________
+
+
+
+
+
+Zum Abschluß Archiv freigeben!
+____________________________________________________________________________
+
+ gib kommando :
+ release(archive)
+
+____________________________________________________________________________
+#page#
+
+Fehlermeldungen des Archivs
+Versucht man, eine Datei vom Archiv zu holen, kann es vorkommen, daß das Ar­
+chiv-System
+
+____________________________________________________________________________
+
+ gib kommando :
+ fetch ("datei", archive)
+ #ib#Lese-Fehler (Archiv)#ie#
+
+____________________________________________________________________________
+
+
+
+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 Disket­
+ten-Geräte). In einem solchen Fall vermerkt das Archiv-System intern, daß die Datei
+nicht korrekt gelesen werden kann. Das sieht man z.B. bei 'list (archive)'. Dort ist der
+betreffende Datei-Name mit dem Zusatz 'mit Lese-Fehler' gekennzeichnet. Um
+diese Datei trotzdem zu lesen, muß man sie unter ihrem Dateinamen mit dem Zusatz
+'mit Lese-Fehler' lesen.
+
+____________________________________________________________________________
+
+ gib kommando:
+ fetch ("datei mit Lese-Fehler", archive)
+
+____________________________________________________________________________
+
+
+
+Die Datei wird in diesem Fall trotz Lese-Fehler (Informationsverlust!) vom Archiv
+gelesen.
+#page#
+
+Weitere Fehlermeldungen des Archivs:
+
+
+FEHLER : Lesen unmöglich (Archiv)
+ Die Archiv-Diskette ist nicht eingelegt oder die Tür des Laufwerks ist nicht
+ geschlossen.
+ => Diskette einlegen bzw. Tür schließen.
+
+FEHLER : Schreiben unmöglich (Archiv)
+ Die Diskette ist schreibgeschützt.
+ => falls wirklich gewünscht, Schreibschutz entfernen.
+
+FEHLER : Archiv nicht angemeldet
+ Das Archiv wurde nicht angemeldet
+ => 'archive ("name")' geben.
+
+FEHLER : Lese-Fehler (Archiv)
+ Siehe Lesen unmöglich
+
+FEHLER : Schreibfehler (Archiv)
+ Die Diskette kann nicht (mehr) beschrieben werden.
+ => Andere Diskette verwenden.
+
+FEHLER : Speicherengpass
+ Im System ist nicht mehr genügend Platz, um eine Datei vom Archiv zu
+ laden.
+ => ggf. Dateien löschen.
+
+FEHLER : RERUN bei Archiv-Zugriff Das System wurde bei einer Archiv-Operation
+ durch Ausschalten bzw. Reset unterbrochen.
+
+FEHLER : "dateiname" gibt es nicht
+ Die Datei "dateiname" gibt es nicht auf dem Archiv.
+ => mit 'list(archive)' Archiv prüfen.
+
+FEHLER : Archiv heißt ...
+ Die eingelegte Diskette hat einen anderen als den eingegebenen Archivna­
+ men.
+ => Kommando 'archive' mit korrektem Namen geben.
+
+FEHLER : Archiv wird von Task ... benutzt
+ Das Archiv wurde von einem anderen Benutzer reserviert.
+ => Abwarten.
+
+FEHLER : "dateiname" kann nicht geschrieben werden (Archiv voll)
+ Die Datei ist zu groß für die eingelegte Diskette.
+ => Andere Diskette für diese Datei nehmen.
+
+FEHLER : Archiv inkonsistent
+ Die eingelegte Diskette hat nicht die Struktur einer Archiv-Diskette.
+ => 'format (archive)' vergessen.
+
+FEHLER : save/erase wegen Lese-Fehler verboten
+ Bei Archiven mit Lese-Fehler sind Schreiboperationen verboten, weil ein
+ Erfolg nicht garantiert werden kann.
+
diff --git a/doc/programmer-manual/1.8.7/doc/programmierhandbuch.5 b/doc/programmer-manual/1.8.7/doc/programmierhandbuch.5
new file mode 100644
index 0000000..a921572
--- /dev/null
+++ b/doc/programmer-manual/1.8.7/doc/programmierhandbuch.5
@@ -0,0 +1,1329 @@
+#pagenr("%",1)##setcount(1)##block##pageblock#
+#headeven#
+#center#EUMEL-Benutzerhandbuch
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#TEIL 5 : Programmierung
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+5 - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#5 - %
+#end#
+
+TEIL 5: Programmierung
+
+
+5.1 Der ELAN-Compiler
+
+Der ELAN-Compiler des EUMEL-Systems dient zweierlei Aufgaben: zum einen der
+Übersetzung von ELAN-Programmen, zum anderen der Verwaltung der taskeigenen
+Modulbibliothek.
+
+Diese Moduln, in ELAN Pakete (siehe 2.4.3.4ff.) genannt, stellen als vorübersetzte,
+und damit abrufbereite#u#1)#e# Prozeduren den Kommandovorrat einer Task dar.
+
+Der Codebereich einer Task liegt in ihrem Standarddatenraum (ds4). Die Größe dieses
+Codebereiches beträgt 256K. Der Inhalt besteht zunächst aus den von der Vatertask
+ererbten (durch Kopie des ds4 dieser Task) Moduln, im weiteren allen in dieser Task
+neu hinzu insertierten Packeten.
+#on("b")#
+
+
+ACHTUNG: Durch ständiges Neuinsertieren eines Packets kann der
+ Codebereich der betroffenen Task zum Überlaufen
+ gebracht werden!
+
+
+#foot#
+
+1) Die von anderen Systemen her gewohnten Phasen 'Binden' und 'Laden' sind
+ durch das EUMEL-ELAN-Compiler-Konzept unnötig.
+#end#
+Jedes Kommando im EUMEL-System ist der Aufruf einer, in der Schnittstelle eines
+bereits insertierten Packetes stehenden, Prozedur.
+
+Kommandos für den ELAN-Compiler:
+
+- Übersetzen : do , insert , run , runagain
+
+- Protokollieren : check , checkon/off ,
+ prot , protoff , warnings on/off
+
+
+#page#
+'do'
+ #on("b")#PROC do (TEXT CONST program)#off("b")#
+ Übersetzen und Ausführen von 'program' von einem Programm aus. 'program'
+ muß ein ausführbares ELAN Programm sein.
+
+
+____________________________________________________________________________
+
+ ........................... Beispiel ..........................
+ PACKET reo DEFINES reorganize all:
+
+ PROC reorganize all(THESAURUS CONST thes):
+ do (PROC (TEXT CONST) reorganize ,thes)
+ (* Die Prozedur 'reorganize' (siehe 5-52), die einen*)
+ (* Dateinamen als Parameter verlangt, wird auf alle *)
+ (* Dateien des Thesaurus 'thes' angewandt. *)
+ END PROC reorganize all;
+ END PACKET reo;
+
+____________________________________________________________________________
+
+
+'insert'
+ #on("b")#PROC insert (TEXT CONST dateiname) #off("b")#
+ Insertieren eines oder mehrerer PACKETs aus der Datei 'dateiname'. Der Pro­
+ grammtext muß sich in #on("u")#einer#off("u")# Datei befinden.
+
+
+ #on("b")#PROC insert #off("b")#
+ Insertieren eines oder mehrerer PACKETs. Der Dateiname ist der zuletzt benutzte
+ Dateiname.
+
+
+ #on("b")#PROC insert (THESAURUS CONST t) #off("b")#
+ Insertieren aller PACKETs, die in den Dateien des Thesaurus 't' enthalten sind.
+
+
+#page#
+'run'
+ #on("b")#PROC run #off("b")#
+ Übersetzen und Ausführen eines ELAN-Programms. Der Programmtext muß sich
+ in einer Datei befinden. Der Dateiname ist der zuletzt benutzte Dateiname.
+
+
+ #on("b")#PROC run (TEXT CONST dateiname) #off("b")#
+ Wie oben. Der Programmtext wird aus der Datei mit dem Namen 'dateiname'
+ geholt.
+
+
+
+'runagain'
+ #on("b")#PROC runagain #off("b")#
+ Nochmaliges Ausführen des zuletzt mit 'run' übersetzten ELAN-Programms.
+ Wurde in der letzten Übersetzung ein Fehler gefunden, erfolgt die Meldung:
+
+ FEHLER : "run again nicht möglich"
+
+#page#
+'check'
+ #on("b")#BOOL PROC check #off("b")#
+ Informationsprozedur, die TRUE liefert, wenn 'check' eingeschaltet ist.
+
+ #on("b")#PROC check on #off("b")#
+ Einschalten der Generierung von Zeilennummern durch den ELAN-Compiler. Der
+ bei der Übersetzung erzeugte Code wird ca. 25% umfangreicher!
+ Voreinstellung im 'PUBLIC'- Zweig: 'check on'.
+
+ #on("b")#PROC check off #off("b")#
+ Ausschalten der Generierung von Zeilennummern durch den ELAN-Compiler.
+ Voreinstellung im 'SYSUR' - Zweig: 'check off.
+
+
+'prot'
+ #on("b")#BOOL PROC prot #off("b")#
+ Informationsprozedur, die TRUE liefert, gdw. 'prot' eingeschaltet ist.
+
+ #on("b")#PROC prot (TEXT CONST dateiname) #off("b")#
+ Einschalten des Compilerlistings auf dem Bildschirm. Das Listing wird gleichzeitig
+ in die Datei 'dateiname' geschrieben.
+
+ #on("b")#PROC prot off #off("b")#
+ Ausschalten des Listings.
+
+
+'warnings'
+ #on("b")#BOOL PROC warnings #off("b")#
+ Informationsprozedur, die TRUE liefert gdw. 'warnings' eingeschaltet ist.
+
+ #on("b")#PROC warnings on #off("b")#
+ Warnungen werden wie Fehlermeldungen ins Notizbuch ausgegeben.
+
+ #on("b")#PROC warnings off#off("b")#
+ Warnungen werden nicht mit in das Notizbuch ausgegeben.
+#page#
+
+5.1.1 Fehlermeldungen des ELAN-Compilers
+erfolgen stets in der Form:
+
+#ib#COMPILER ERROR#ie#: <zahl>
+
+wobei <zahl> folgende Werte annehmen kann:
+
+#on("bold")#<zahl> Bedeutung und eventuelle Abhilfe#off ("bold")#:
+
+ 101 Überlauf der Namenstabelle
+ Die Anzahl der Namen aller sichtbaren Pakete ist zu groß oder es wurden
+ die Anführungstriche eines TEXT-Denoters vergessen.
+ => Keine Abhilfe.
+
+ 102 Überlauf der Symboltabelle
+ Die Anzahl der deklarierten Objekte ist zu groß.
+ => Programm in Pakete unterteilen.
+
+ 103 Überlauf des Zwischencodebereiches
+ => Programm in Pakete unterteilen.
+
+ 104 Überlauf der Permanenttabelle
+ Zu viele Pakete insertiert.
+ => Keine (neue Task beginnen).
+
+ 106 Paketdatenadresse zu groß
+ Im Paket wird zuviel Platz ( > 64K ) von globalen Datenobjekten und
+ Denotern eingenommen.
+ => Keine Abhilfe.
+
+ 107 Lokale Datenadresse zu groß
+ Im Paket wird zuviel Platz ( > 32K ) von lokalen Datenobjekten belegt.
+ => Keine Abhilfe.
+ #page#
+ 204 Überlauf des Compilerstack
+ => Keine Abhilfe.
+
+ 301 Modulnummern-Überlauf
+ Zu viele sichtbare Pakete, Prozeduren und Operatoren ( > 2048 ).
+ => Keine Abhilfe.
+
+ 303
+ siehe 304
+
+ 304 Zu viele Ansprungadressen
+ In dem gerade übersetzten Modul (Prozedur, Operator oder Paketrumpf)
+ werden vom Compiler zu viele Marken benötigt (mehr als 2000). Marken
+ werden z.B. für die Codegenerierung von Auswahl (IF ...) und Wieder­
+ holung (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 ge­
+ spannte SELECT-Anweisungen zurückzuführen.
+ => SELECT-Anweisungen über mehrere Prozeduren verteilen oder
+ Spannweiten verringern.
+
+ 305 Codeüberlauf
+ Der insgesamt erzeugte sichtbare Code ist zu umfangreich ( > 256K ).
+ => Keine Abhilfe.
+
+ 306 Paketdatenadresse zu groß
+ Insgesamt zu viele Datenobjekte in den Paketen ( > 128K ).
+ => Keine Abhilfe.
+
+ 307 Temporäre Datenadresse zu groß
+ Zu viele (lokale) Datenobjekte in einer Prozedur ( > 32K ).
+ => Prozedur in mehrere unterteilen, so daß die Datenobjekte sich über
+ mehrere Prozeduren verteilen.
+
+ 308 Modulcode-Überlauf
+ Ein Modul (Prozedur, Operator oder Paket-Initialisierungsteil) ist zu groß
+ ( > 7.5 KB Code).
+ => In mehrere Prozeduren oder Pakete zerlegen.
+
+ 309 Zuviele Paketdaten
+ (Insgesamt mehr als 128K Paketdaten)
+ => Keine Abhilfe
+
+
+#page#
+
+5.2 Standardtypen
+
+
+5.2.1 Bool
+
+Der Wertebereich für Datenobjekte vom Typ BOOL besteht aus den Werten TRUE
+und FALSE.
+
+'AND'
+ #on("b")#BOOL OP AND (BOOL CONST a, b) #off("b")#
+ Logisches UND, liefert TRUE gdw. a und b TRUE sind.
+
+
+'CAND'
+ #on("b")#BOOL OP CAND #off("b")#
+ Bedingtes logisches UND, entspricht: 'IF a THEN b ELSE false FI'. Der zweite
+ Operand wird nicht ausgewertet, falls er für das Ergebnis nicht relevant ist.
+
+
+'COR'
+ #on("b")#BOOL OP COR #off("b")#
+ Bedingtes logisches ODER, entspricht: 'IF a THEN true ELSE b FI'. Der zweite
+ Operand wird nicht ausgewertet, falls er für das Ergebnis nicht relevant ist.
+
+
+'false'
+ #on("b")#BOOL CONST false #off("b")#
+
+
+'NOT'
+ #on("b")#BOOL OP NOT (BOOL CONST a) #off("b")#
+ Logische Negation.
+
+
+'OR'
+ #on("b")#BOOL OP OR (BOOL CONST a, b) #off("b")#
+ Logisches ODER, liefert TRUE gdw. a und/oder b TRUE ist.
+
+
+'true'
+ #on("b")#BOOL CONST true #off("b")#
+
+
+'XOR'
+ #on("b")#BOOL OP XOR (BOOL CONST a, b) #off("b")#
+ Exklusives ODER, liefert TRUE gdw. entweder a oder b TRUE ist.
+
+#page#
+
+5.2.2 Integer-Arithmetik
+
+Ein Datenobjekt vom Typ INT belegt im Speicher 2 Bytes. Zulässige INT - Werte
+sind die ganzen Zahlen von -32768 bis +32767 einschließlich.
+
+Falls größere ganze Zahlen benötigt werden, muß das Packet 'LONGINT', welches
+sich auf dem Archive 'std.zusatz' befindet, nachinsertiert werden (siehe 6.1.2).
+
+Operationen für Integers:
+
+- Vergleich : = , <> , < , <= , > , >=
+
+- Verknüpfung : + , - , * , ** , DECR , DIV , INCR
+
+- Sonstiges : abs , ABS , initialize random , max , maxint , min ,
+ minint , MOD , random , sign , SIGN , text
+#page#
+':='
+ #on("b")#INT OP := (INT VAR a, INT CONST b) #off("b")#
+ Zuweisung.
+
+
+'='
+ #on("b")#BOOL OP = (INT CONST a, b) #off("b")#
+ Vergleich.
+
+
+'<>'
+ #on("b")#BOOL OP <> (INT CONST a, b) #off("b")#
+ Vergleich auf Ungleichheit.
+
+
+'<'
+ #on("b")#BOOL OP < (INT CONST a, b) #off("b")#
+ Vergleich auf kleiner.
+
+
+'<='
+ #on("b")#BOOL OP <= (INT CONST a, b) #off("b")#
+ Vergleich auf kleiner gleich.
+
+
+'>'
+ #on("b")#BOOL OP > (INT CONST a, b) #off("b")#
+ Vergleich auf größer.
+
+
+'>='
+ #on("b")#BOOL OP >= (INT CONST a, b) #off("b")#
+ Vergleich auf größer gleich.
+
+#page#
+'+'
+ #on("b")#INT OP + (INT CONST a) #off("b")#
+ Monadischer Operator (Vorzeichen, ohne Wirkung).
+
+ #on("b")#INT OP + (INT CONST a, b) #off("b")#
+ Addition.
+
+
+'-'
+ #on("b")#INT OP - (INT CONST a) #off("b")#
+ Vorzeichen-Umkehrung.
+
+
+ #on("b")#INT OP - (INT CONST a, b) #off("b")#
+ Subtraktion.
+
+
+'*'
+ #on("b")#INT OP * (INT CONST a, b) #off("b")#
+ Multiplikation.
+
+
+'**'
+ #on("b")#INT OP ** (INT CONST arg, exp) #off("b")#
+ Exponentiation mit 'exp' >= 0
+
+
+'DECR'
+ #on("b")#OP DECR (INT VAR links, INT CONST rechts) #off("b")#
+ Wirkt wie links := links - rechts
+
+
+'DIV'
+ #on("b")#INT OP DIV (INT CONST a, b) #off("b")#
+ INT-Division.
+
+ FEHLER :
+ - DIV durch 0
+
+
+'INCR'
+ #on("b")#OP INCR (INT VAR links, INT CONST rechts) #off("b")#
+ Wirkt wie links := links + rechts
+
+#page#
+'abs'
+ #on("b")#INT PROC abs (INT CONST argument) #off("b")#
+ Absolutbetrag eines INT-Wertes.
+
+
+ #on("b")#INT OP ABS (INT CONST argument) #off("b")#
+ Absolutbetrag eines INT-Wertes.
+
+
+'initialize random'
+ #on("b")#PROC initialize random (INT CONST wert) #off("b")#
+ Initialisieren der 'random'-Prozedur, um nicht reproduzierbare Zufallszahlen zu
+ bekommen. Diese 'initialize random'-Prozedur gilt für den "INT-Random Gene­
+ rator".
+
+
+'max'
+ #on("b")#INT PROC max (INT CONST links, rechts) #off("b")#
+ Liefert den Größten der beiden INT-Werte.
+
+
+'maxint'
+ #on("b")#INT CONST maxint #off("b")#
+ Größter INT-Wert im EUMEL-System (32 767).
+
+
+'min'
+ #on("b")#INT PROC min (INT CONST links, rechts) #off("b")#
+ Liefert den Kleinsten der beiden INT-Werte.
+
+
+ min ( 3.0, 2.0) ==> 2.0
+ min (-2.0, 3.0) ==> -2.0
+
+
+
+'minint'
+ #on("b")#INT CONST minint #off("b")#
+ Kleinster INT-Wert im EUMEL-System (-32768).
+
+
+'MOD'
+ #on("b")#INT OP MOD (INT CONST links, rechts) #off("b")#
+ Liefert den Rest einer INT-Division.
+
+
+ 3 MOD 2 ==> 1
+ -3 MOD 2 ==> 1
+
+
+ FEHLER :
+ - DIV durch 0
+
+
+'random'
+ #on("b")#INT PROC random (INT CONST lower bound, upper bound) #off("b")#
+ Pseudo-Zufallszahlen-Generator im Intervall 'upper bound' und 'lower bound'
+ einschließlich. Es handelt sich hier um den "INT Random Generator".
+
+
+'real'
+ #on("b")#REAL PROC real (INT CONST a) #off("b")#
+ Konvertierungsprozedur.
+
+#page#
+'sign'
+ #on("b")#INT PROC sign (INT CONST argument) #off("b")#
+ Feststellen des Vorzeichens eines INT-Wertes. Folgende Werte werden geliefert:
+
+
+ argument > 0 ==> 1
+ argument = 0 ==> 0
+ argument < 0 ==> -1
+
+
+
+ #on("b")#INT OP SIGN (INT CONST argument) #off("b")#
+ Feststellen des Vorzeichens eines INT-Wertes.
+
+
+'text'
+ #on("b")#TEXT PROC text (INT CONST zahl) #off("b")#
+ Konvertierung des INT Wertes 'zahl' in den kürzest möglichen Text. Das Vorzei­
+ chen bleibt erhalten.
+
+ #on("b")#TEXT PROC text (INT CONST zahl, länge) #off("b")#
+ Konvertierung des INT Wertes 'zahl' in einen Text der Länge 'länge'. Das
+ Vorzeichen bleibt erhalten. Falls der Text kürzer als 'länge' ist, wird er links
+ (vorne) mit Leerzeichen aufgefüllt, falls er länder ist wird 'länge' mal "*"
+ ausgegeben.
+
+____________________________________________________________________________
+
+ out ("X:"); out(text(12345,7)) ; line;
+ out ("Y:"); out(text(12345,3)) ;
+ (* ergibt *)
+ X: 12345
+ Y:***
+
+____________________________________________________________________________
+#page#
+
+5.2.3 Real-Arithmetik
+
+Für den Datentyp REAL gibt es außer den üblichen Verknüpfungs- und Vergleichs­
+operationen noch eine Anzahl mathematischer Prozeduren und Operationen. Teilweise
+stehen diese in mehr als einer Version zur Verfügung.
+
+Jedes Datenobjekt vom Typ REAL belegt im Speicher 8 Byte.
+
+REALs haben eine 13-stellige #ib#Mantisse#ie#, die im Rechner dezimal geführt wird. (Das
+heißt, bei Konversionen zwischen interner und TEXT-Darstellung treten keine Run­
+dungsfehler auf.) Der Wertebereich wird durch folgende Eckwerte abgegrenzt:
+#dpos(0.5,".")##lpos(4.5)#
+
+#table#
+ 9.999999999999e+126 größter REAL-Wert
+ 0.000000000001 kleinster positiver REAL-Wert mit x + 1.0 > 1.0
+ 9.999999999999e-126 kleinster positiver REAL-Wert > 0.0
+ -9.999999999999e-126 größter negativer REAL-Wert
+ -9.999999999999e+126 kleinster REAL-Wert
+
+#clearpos#
+#tableend#
+
+- Vergleiche : = , <> , < , <= , > , >=
+
+- Verknüpfungen : + , - , * , / , ** , DECR , INCR
+
+- Diverse : abs , arctan , arctand , cos , cosd , decimal
+ exponent , e , exp , floor , frac , initialize
+ random , int , ln , log2 , log10 , max ,
+ maxreal , min , MOD , pi , random , round ,
+ sign , SIGN , sin , sind , smallreal , sqrt ,
+ tan , tand , text
+
+#page#
+':='
+ #on("b")#REAL OP := (REAL VAR a, REAL CONST b) #off("b")#
+ Zuweisung.
+
+
+'='
+ #on("b")#BOOL OP = (REAL CONST a, b) #off("b")#
+ Vergleich.
+
+
+'<>'
+ #on("b")#BOOL OP <> (REAL CONST a, b) #off("b")#
+ Vergleich auf Ungleichheit.
+
+
+'<'
+ #on("b")#BOOL OP < (REAL CONST a, b) #off("b")#
+ Vergleich auf kleiner.
+
+
+'<='
+ #on("b")#BOOL OP <= (REAL CONST a, b) #off("b")#
+ Vergleich auf kleiner gleich.
+
+
+'>'
+ #on("b")#BOOL OP > (REAL CONST a, b) #off("b")#
+ Vergleich auf größer.
+
+
+'>='
+ #on("b")#BOOL OP >= (REAL CONST a, b) #off("b")#
+ Vergleich auf größer gleich.
+
+#page#
+'+'
+ #on("b")#REAL OP + (REAL CONST a) #off("b")#
+ Monadischer Operator (Vorzeichen, ohne Wirkung).
+
+
+ #on("b")#REAL OP + (REAL CONST a, b) #off("b")#
+ Addition.
+
+
+'-'
+ #on("b")#REAL OP - (REAL CONST a) #off("b")#
+ Vorzeichen-Umkehrung.
+
+
+ #on("b")#REAL OP - (REAL CONST a, b) #off("b")#
+ Subtraktion.
+
+
+'*'
+ #on("b")#REAL OP * (REAL CONST a, b) #off("b")#
+ Multiplikation.
+
+
+'/'
+ #on("b")#REAL OP / (REAL CONST a, b) #off("b")#
+ Division.
+
+ FEHLER :
+ - Division durch 0
+
+
+'**'
+ #on("b")#REAL OP ** (REAL CONST arg, exp) #off("b")#
+ Exponentiation.
+
+ #on("b")#REAL OP ** (REAL CONST arg, INT CONST exp) #off("b")#
+ Exponentiation.
+
+
+'DECR'
+ #on("b")#OP DECR (REAL VAR links, REAL CONST rechts) #off("b")#
+ Wirkt wie links := links - rechts
+
+
+'INCR'
+ #on("b")#OP INCR (REAL VAR links, REAL CONST rechts) #off("b")#
+ Wirkt wie links := links + rechts
+
+#page#
+'abs'
+ #on("b")#REAL PROC abs (REAL CONST wert) #off("b")#
+ Absolutbetrag eines REAL-Wertes.
+
+ #on("b")#REAL OP ABS (REAL CONST wert) #off("b")#
+ Absolutbetrag eines REAL-Wertes.
+
+
+'arctan'
+ #on("b")#REAL PROC arctan (REAL CONST x) #off("b")#
+ Arcus Tangens-Funktion. Liefert einen Wert in Radiant.
+
+
+'arctand'
+ #on("b")#REAL PROC arctand (REAL CONST x) #off("b")#
+ Arcus Tangens-Funktion. Liefert einen Wert in Grad.
+
+
+'cos'
+ #on("b")#REAL PROC cos (REAL CONST x) #off("b")#
+ Cosinus-Funktion. 'x' muß in Radiant angegeben werden.
+
+
+'cosd'
+ #on("b")#REAL PROC cosd (REAL CONST x) #off("b")#
+ Cosinus-Funktion. 'x' muß in Winkelgrad angegeben werden.
+
+
+'decimal exponent'
+ #on("b")#INT PROC decimal exponent (REAL CONST mantisse) #off("b")#
+ Liefert aus einem REAL-Wert den dezimalen Exponenten als INT-Wert.
+
+
+'e'
+ #on("b")#REAL PROC e #off("b")#
+ Eulersche Zahl (2.718282).
+
+
+'exp'
+ #on("b")#REAL PROC exp (REAL CONST z) #off("b")#
+ Exponentialfunktion.
+
+
+'floor'
+ #on("b")#REAL PROC floor (REAL CONST real) #off("b")#
+ Schneidet die Nachkommastellen des REAL-Wertes 'real' ab.
+
+
+'frac'
+ #on("b")#REAL PROC frac (REAL CONST z) #off("b")#
+ Liefert die Stellen eines REAL-Wertes hinter dem Dezimalpunkt.
+
+
+'initialize random'
+ #on("b")#PROC initialize random (REAL CONST z) #off("b")#
+ 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'.
+
+
+'int'
+ #on("b")#INT PROC int (REAL CONST a) #off("b")#
+ Konvertierungsprozedur. Die Nachkommastellen werden abgeschnitten.
+ Bsp: int (3.9) => 3
+
+
+'ln'
+ #on("b")#REAL PROC ln (REAL CONST x) #off("b")#
+ Natürlicher Logarithmus.
+
+ FEHLER :
+ - ln mit negativer Zahl
+ Nur echt positive Argumente sind zulässig.
+
+
+'log2'
+ #on("b")#REAL PROC log2 (REAL CONST z) #off("b")#
+ Logarithmus zur Basis 2.
+
+ FEHLER :
+ - log2 mit negativer zahl
+ Nur echt positive Argumente sind zulässig.
+
+
+'log10'
+ #on("b")#REAL PROC log10 (REAL CONST x) #off("b")#
+ Logarithmus zur Basis 10.
+
+ FEHLER :
+ - log10 mit negativer zahl
+ Nur echt positive Argumente sind zulässig.
+
+
+'max'
+ #on("b")#REAL PROC max (REAL CONST links, rechts) #off("b")#
+ Liefert den Größten der beiden REAL-Werte.
+
+
+'maxreal'
+ #on("b")#REAL CONST maxreal #off("b")#
+ Größter REAL-Wert im EUMEL-System (9.999999999999e126).
+
+
+'min'
+ #on("b")#REAL PROC min (REAL CONST links, rechts) #off("b")#
+ Liefert den Kleinsten der beiden REAL-Werte.
+
+
+'MOD'
+ #on("b")#REAL OP MOD (REAL CONST links, rechts) #off("b")#
+ Modulo-Funktion für REALs (liefert den Rest). Beispiele:
+
+
+ 5.0 MOD 2.0 ==> 1.0
+ 4.5 MOD 4.0 ==> 0.5
+
+
+
+'pi'
+ #on("b")#REAL CONST pi #off("b")#
+ Die Zahl pi (3.141593).
+
+
+'random'
+ #on("b")#REAL PROC random #off("b")#
+ Pseudo-Zufallszahlen-Generator im Intervall 0 und 1. Es handelt sich hier um
+ den "REAL Random Generator".
+
+
+'round'
+ #on("b")#REAL PROC round (REAL CONST real, INT CONST digits) #off("b")#
+ 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 Vorkommastellen gerundet.
+
+
+ round (123.456, -2)
+
+
+ liefert '100.0'. Abweichung vom Standard: Es wird mit 'digits'-Ziffern gerundet.
+
+
+'sign'
+ #on("b")#INT PROC sign (REAL CONST argument) #off("b")#
+ Feststellen des Vorzeichens eines REAL-Wertes.
+
+ #on("b")#INT OP SIGN (REAL CONST argument) #off("b")#
+ Feststellen des Vorzeichens eines REAL-Wertes.
+
+
+'sin'
+ #on("b")#REAL PROC sin (REAL CONST x) #off("b")#
+ Sinus-Funktion. 'x' muß in Radiant (Bogenmaß) angegeben werden.
+
+
+'sind'
+ #on("b")#REAL PROC sind (REAL CONST x) #off("b")#
+ Sinus-Funktion. 'x' muß im Winkelgrad angegeben werden.
+
+
+'smallreal'
+ #on("b")#REAL PROC smallreal #off("b")#
+ 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'
+ #on("b")#REAL PROC sqrt (REAL CONST z) #off("b")#
+ Wurzel-Funktion.
+
+ FEHLER :
+ - sqrt von negativer Zahl
+ Das Argument muß größer gleich 0.0 sein.
+
+
+'tan'
+ #on("b")#REAL PROC tan (REAL CONST x) #off("b")#
+ Tangens-Funktion. 'x' muß in Radiant angegeben werden.
+
+
+'tand'
+ #on("b")#REAL PROC tand (REAL CONST x) #off("b")#
+ Tangens-Funktion. 'x' muß in Winkelgrad angegeben werden.
+
+
+'text'
+ #on("b")#TEXT PROC text (REAL CONST real) #off("b")#
+ Konvertierung eines REAL-Wertes in einen TEXT. Ggf. wird der TEXT in Expo­
+ nenten-Darstellung geliefert.
+
+ #on("b")#TEXT PROC text (REAL CONST real, laenge) #off("b")#
+ Konvertierung eines REAL-Wertes in einen TEXT. Der TEXT wird in Exponen­
+ ten-Darstellung geliefert. Um diese Darstellung zu ermöglichen ist der Wert
+ 'laenge' größer oder gleich 8 anzugeben.
+
+ #on("b")#TEXT PROC text (REAL CONST real, INT CONST laenge, fracs)#off("b")#
+ Konvertierung eines REAL-Wertes in einen TEXT. Dabei gibt 'laenge' die Länge
+ des Resultats einschließlich des Dezimalpunktes und 'fracs' die Anzahl der Dezi­
+ malstellen an. Kann der REAL-Wert nicht wie gewünscht dargestellt werden, wird
+
+
+ laenge * "*"
+
+
+ geliefert.
+
+#page#
+
+5.2.4 Text
+
+Jedes Datenobjekt vom Typ TEXT besteht aus einem festen Teil von 16 Bytes und
+möglicherweise aus einem flexiblen Teil auf dem #on("i")##on("b")#Heap#off("i")##off("b")#. Im festen Teil werden Texte
+bis zur Länge von 13 Zeichen untergebracht. Wenn eine TEXT-Variable einen Wert
+mit mehr als 13 Zeichen Länge annimmt, werden alle Zeichen auf dem Heap unterge­
+bracht. Genauer ergibt sich folgendes Bild:
+
+ kurzer Text (Länge <= 13):
+
+ Heap-Link 2 Bytes
+ Textlänge 1 Byte
+ Text 13 Bytes
+
+ langer Text (Länge > 13):
+
+ Heap-Link 2 Bytes
+ 255 1 Byte
+ Länge 2 Bytes
+ ungenutzt 11 Bytes
+
+Wenn eine Variable einmal Platz auf dem Heap bekommen hat, behält sie diesen
+vorbeugend auch dann, wenn sie wieder einen kurzen Text als Wert erhält. So muß
+wahrscheinlich kein neuer Platz auf dem Heap zugewiesen werden, wenn sie wieder
+länger wird. Das gilt allerdings nur bis zur nächsten #ib#Garbage Collection#ie# auf den
+TEXT-Heap, denn dabei werden alle Heap-Container minimal gemacht bzw. ge­
+löscht, wenn sie nicht mehr benötigt werden. Der Platz auf dem Heap wird in Vielfa­
+chen von 16 Bytes vergeben. In Fremddatenräumen wird in jedem #ib#Container#ie# neben
+dem eigentlichen Text auch die Containerlänge untergebracht.
+#page#
+Beispiele: TEXT-Länge Speicherbedarf (Byte)
+
+ 0 16
+ 13 16
+ 14 32
+ 15 48
+ 30 48
+ 31 64
+ 46 64
+ 47 80
+ 62 80
+
+
+Die Heapgröße eines Fremddatenraums berechnet sich als:
+
+ 1024 * 1024 = 1048056 - stat Bytes
+
+'stat' ist dabei die statische Größe der Datenstruktur, die dem Datenraum aufgeprägt
+wurde. Bei einem BOUND ROW 1000 TEXT ergibt sich also eine Heapgröße von
+
+ 1048056 - (1000 * 16) = 1032056 Bytes.
+
+
+
+'heap size'
+ #on("b")#INT PROC heap size #off("b")#
+ Informationsprozedur für die Größe (in KB) des TEXT-Heaps.
+
+#page#
+
+TEXT- Operationen:
+
+- Vergleich : = , <> , < , <= , > , >=
+ LEXEQUAL , LEXGREATER ,
+ LEXGREATEREQUAL
+
+- Verkettung : + , * , CAT
+
+- Veränderung : change , change all , code , compress , delete
+ char , insert char , length , LENGTH , max
+ text length , pos , real , replace , SUB ,
+ subtext , text
+#page#
+
+Der EUMEL-Zeichensatz
+#goalpage("codetab")#
+Das EUMEL System definiert einen Zeichensatz, der gewährleistet, daß gleiche Text­
+zeichen auf allen Maschinen gleich codiert werden.
+ Die interne Darstellung wird durch die folgende EUMEL-Codetabelle
+beschrieben. Der Zeichensatz beruht auf dem ASCII-Zeichensatz mit Erweiterungen.
+Der in der Tabelle freie Bereich (z.B code(127) bis code(213)) ist nicht einheitlich
+verfügbar und wird deshalb nicht beschrieben. Die Codierung bildet mithin auch
+Grundlage für Vergleiche und Sortierungen.
+
+Die Korrekte Darstellung dieser Zeichen auf Bildschirm, Drucker etc. setzt natürlich
+eine korrekte Konfiguration der Geräte voraus. Die Anpassung eines Geräts an diesen
+Zeichensatz ist im EUMEL-Systemhandbuch in Teil 2 beschrieben.
+
+
+ I 0 1 2 3 4 5 6 7 8 9
+---+--------------------------------------
+3 I SP ! " \# $ % & '
+ I
+4 I ( ) * + , - . / 0 1
+ I
+5 I 2 3 4 5 6 7 8 9 : ;
+ I
+6 I < = > ? § A B C D E
+ I
+7 I F G H I J K L M N O
+ I
+8 I P Q R S T U V W X Y
+ I
+9 I Z [ \ ] ^ _ ` a b c
+ I
+10 I d e f g h i j k l m
+ I
+11 I n o p q r s t u v w
+ I
+12 I x y z { | } ~
+ I
+13 I
+. I
+. I
+. I
+20 I
+ I
+21 I Ä Ö Ü ä ö ü
+ I
+22 I k ­ \# SP
+ I
+23 I
+ I
+24 I
+ I
+25 I ß
+#page#
+':='
+ #on("b")#TEXT OP := (TEXT VAR a, TEXT CONST b) #off("b")#
+ Zuweisung.
+
+
+'='
+ #on("b")#BOOL OP = (TEXT CONST links, rechts) #off("b")#
+ Vergleich von zwei Texten auf Gleichheit (Texte mit ungleichen Längen sind
+ immer ungleich).
+
+
+'<>'
+ #on("b")#BOOL OP <> (TEXT CONST links, rechts) #off("b")#
+ Vergleich von zwei Texten auf Ungleichheit (Texte mit ungleichen Längen sind
+ stets ungleich).
+
+
+'<'
+ #on("b")#BOOL OP < (TEXT CONST links, rechts) #off("b")#
+ Vergleich zweier Texte auf kleiner ('links' kommt lexikographisch vor 'rechts').
+
+
+'<='
+ #on("b")#BOOL OP <= (TEXT CONST links, rechts) #off("b")#
+ Vergleich von zwei Texten auf kleiner gleich ('links' kommt lexikographisch vor
+ oder ist gleich 'rechts').
+
+
+'>'
+ #on("b")#BOOL OP > (TEXT CONST links, rechts) #off("b")#
+ Vergleich zweier Texte auf größer ('links' kommt lexikographisch nach 'rechts').
+
+
+'>='
+ #on("b")#BOOL OP >= (TEXT CONST links, rechts) #off("b")#
+ Vergleich zweier Texte auf größer gleich ('links' kommt lexikographisch nach oder
+ ist gleich 'rechts').
+
+#page#
+'LEXEQUAL'
+ #on("b")#BOOL OP LEXEQUAL (TEXT CONST links, rechts) #off("b")#
+ Prüfung auf lexikalische Gleichheit.
+
+
+'LEXGREATER'
+ #on("b")#BOOL OP LEXGREATER (TEXT CONST links, rechts) #off("b")#
+ Prüfung ob der Text 'links' lexikalisch größer als 'rechts' ist.
+
+
+'LEXGREATEREQUAL'
+ #on("b")#BOOL OP LEXGREATEREQUAL (TEXT CONST links, rechts) #off("b")#
+ Prüfung ob der Text 'links' lexikalisch größer oder gleich dem Text 'rechts' ist.
+
+
+
+ Die drei Operatoren prüfen nach folgenden Regeln:
+
+ - Buchstaben haben die aufsteigende Reihenfolge 'A' bis 'Z'. Dabei werden kleine
+ und große Buchstaben gleich behandelt.
+
+ - Umlaute werden wie üblich ausgeschrieben. (Ä = Ae usw.)
+ (ß = ss)
+
+ - Alle Sonderzeichen (auch Ziffern) außer ' '(Leerzeichen) und '-' werden igno­
+ riert, diese beiden Zeichen werden gleich behandelt.
+
+#page#
+'+'
+ #on("b")#TEXT OP + (TEXT CONST links, rechts) #off("b")#
+ Verkettung der Texte 'links' und 'rechts' in dieser Reihenfolge. Die Länge des
+ Resultats ergibt sich aus der Addition der Längen der Operanden.
+
+
+'*'
+ #on("b")#TEXT OP * (INT CONST faktor, TEXT CONST quelle) #off("b")#
+ 'faktor' fache Erstellung von 'quelle' und Verkettung. Dabei muß
+
+
+ times >= 0
+
+
+ sein, sonst wird 'niltext' geliefert.
+
+
+'CAT'
+ #on("b")#OP CAT (TEXT VAR links, TEXT CONST rechts) #off("b")#
+ hat die gleiche Wirkung wie
+
+
+ links := links + rechts
+
+
+ Hinweis: Der Operator 'CAT' hat eine geringere Heap-Belastung als die Opera­
+ tion mit expliziter Zuweisung.
+
+#page#
+'change'
+ #on("b")#PROC change (TEXT VAR senke, TEXT CONST alt, neu) #off("b")#
+ Ersetzung des (Teil-) TEXTes 'alt' in 'senke' durch 'neu' bei dem erstmaligen
+ Auftreten. Ist 'alt' nicht in 'senke' vorhanden, so wird keine Meldung abgesetzt
+ (Abweichung vom Standard). Die Länge von 'senke' kann sich dabei verändern.
+ Beispiel:
+
+
+ TEXT VAR mein text :: "EUMEL-Benutzerhandbuch";
+ change (mein text, "Ben", "N");
+ (* EUMEL-Nutzerhandbuch *)
+
+
+ #on("b")#PROC change (TEXT VAR senke, INT CONST von, bis, TEXT CONST neu) #off("b")#
+ Der TEXT 'neu' wird in den TEXT 'senke' anstatt des TEXTes, der zwischen 'von'
+ und 'bis' steht, eingesetzt. Die Länge von 'senke' kann sich dabei verändern.
+ Beispiel:
+
+
+ TEXT VAR mein text :: "EUMEL-Benutzerhandbuch";
+ change (mein text, 7, 9, "N"); (* wie oben *)
+
+
+
+'change all'
+ #on("b")#PROC change all (TEXT VAR senke, TEXT CONST alt, neu) #off("b")#
+ Der Teiltext 'alt' wird durch 'neu' in 'senke' ersetzt. Im Unterschied zur 'chan­
+ ge'-Prozedur findet die Ersetzung nicht nur bei dem erstmaligen Auftreten von
+ 'alt' statt, sondern so oft, wie 'alt' in 'senke' vorhanden ist. Beispiel:
+
+
+ TEXT VAR x :: "Das ist ein Satz";
+ change all (x, " ", ""); (* DasisteinSatz *)
+
+#page#
+'code'
+ #on("b")#TEXT PROC code (INT CONST code) #off("b")#
+ Wandelt einen INT-Wert 'code' in ein Zeichen um. 'code' muß
+
+
+ 0 <= code <= 255
+
+
+ sein.
+
+ #on("b")#INT PROC code (TEXT CONST text) #off("b")#
+ 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).
+ (Codetabelle auf Seite 5- #topage("codetab")#)
+
+
+'compress'
+ #on("b")#TEXT PROC compress (TEXT CONST text) #off("b")#
+ Liefert den TEXT 'text' ohne führende und nachfolgende Leerzeichen.
+
+
+'delete char'
+ #on("b")#PROC delete char (TEXT VAR string, INT CONST delete pos)#off("b")#
+ 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.
+
+#page#
+'insert char'
+ #on("b")#PROC insert char (TEXT VAR string, TEXT CONST char,INT CONST insert pos)#off("b")#
+ 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.
+
+
+'length'
+ #on("b")#INT PROC length (TEXT CONST text) #off("b")#
+ Anzahl von Zeichen ("Länge") von 'text' einschließlich Leerzeichen.
+
+
+'LENGTH'
+ #on("b")#INT OP LENGTH (TEXT CONST text) #off("b")#
+ Anzahl von Zeichen ("Länge") von 'text' einschließlich Leerzeichen.
+
+
+'max text length'
+ #on("b")#INT CONST max text length #off("b")#
+ Maximale Anzahl von Zeichen in einem TEXT (32 000).
+
+#page#
+'pos'
+ #on("b")#INT PROC pos (TEXT CONST quelle, pattern) #off("b")#
+ Liefert die erste Position des ersten Zeichens von 'pattern' in 'quelle', falls 'pat­
+ tern' gefunden wird. Wird 'pattern' nicht gefunden oder ist 'pattern' niltext, so wird
+ der Wert '0' geliefert. Beispiel:
+
+
+ TEXT VAR t1 :: "abcdefghijk...xyz",
+ t2 :: "cd";
+ ... pos (t1, t2) ... (* liefert 3 *)
+ ... pos (t2, t1) ... (* liefert 0 *)
+
+
+
+ #on("b")#INT PROC pos (TEXT CONST quelle, pattern, INT CONST von)#off("b")#
+ Wie obige Prozedur, jedoch wird erst ab der Position 'von' ab gesucht. Dabei gilt
+ folgende Einschränkung:
+
+
+ length (pattern) < 255
+
+
+
+ #on("b")#INT PROC pos (TEXT CONST quelle, low char, high char, INT CONST von#off("b")#
+ Liefert die Position des ersten Zeichens 'x' in 'quelle' ab der Position 'von', so daß
+
+
+ low char <= x <= high char
+
+
+ 'low char' und 'high char' müssen TEXTe der Länge 1 sein. Wird kein Zeichen in
+ 'quelle' 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);
+
+____________________________________________________________________________
+
+#page#
+'real'
+ #on("b")#REAL PROC real (TEXT CONST text) #off("b")#
+ 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'
+ #on("b")#PROC replace (TEXT VAR senke, INT CONST position, TEXT CONST quelle)#off("b")#
+ Ersetzung eines Teiltextes in 'senke' durch 'quelle' an der Position 'position' in
+ 'senke'. Es muß gelten
+
+
+ 1 <= position <= LENGTH senke
+
+
+ d.h. 'position' muß innerhalb von 'senke' liegen und 'quelle' muß von der Posi­
+ tion 'position' ab in 'senke' einsetzbar sein. Dabei bleibt die Länge von 'senke'
+ unverändert.
+
+
+'SUB'
+ #on("b")#TEXT OP SUB (TEXT CONST text, INT CONST pos) #off("b")#
+ 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.
+
+#page#
+'subtext'
+ #on("b")#TEXT PROC subtext (TEXT CONST quelle, INT CONST von) #off("b")#
+ Teiltext von 'quelle', der bei der Position 'von' anfängt. Die Länge des Resultats
+ ergibt sich also zu
+
+
+ LENGTH quelle - von + 1
+
+
+ d.h. von der Position 'von' bis zum Ende von 'quelle'. 'von' muß innerhalb von
+ 'quelle' liegen. Ist von < 1, dann wird 'quelle' geliefert. Falls von > LENGTH
+ quelle ist, wird niltext geliefert.
+
+
+ #on("b")#TEXT PROC subtext (TEXT CONST quelle, INT CONST von, bis)#off("b")#
+ Teiltext von 'quelle' von der Position 'von' bis einschließlich der Position 'bis'. Die
+ Länge des Resultats ist also
+
+
+ bis - von + 1
+
+
+ Dabei muß gelten
+
+
+ 1 <= von <= bis <= LENGTH quelle
+
+
+ d.h. die Positionen 'von' und 'bis' müssen in dieser Reihenfolge innerhalb von
+ 'quelle' liegen. Ist
+
+
+ bis >= LENGTH quelle
+
+
+ wird 'subtext (quelle, von)' ausgeführt. Für die Bedingungen für 'von' siehe vor­
+ stehende Beschreibung von 'subtext'.
+
+
+'text'
+ #on("b")#TEXT PROC text (TEXT CONST quelle, INT CONST laenge) #off("b")#
+ Teiltext aus 'quelle' mit der Länge 'laenge', beginnend bei der Position 1 von
+ 'quelle'. Es muß gelten
+
+
+ 1 <= laenge <= LENGTH quelle
+
+
+ d.h. der gewünschte Teiltext muß aus 'quelle' ausblendbar sein.
+ Wenn gilt:
+
+ laenge > LENGTH quelle
+
+
+ wird der zu liefernde TEXT mit der an 'laenge' fehlenden Zeichen mit Leerzeichen
+ aufgefüllt.
+
+ #on("b")#TEXT PROC text (TEXT CONST quelle, INT CONST laenge, von)#off("b")#
+ Teiltext aus 'quelle' mit der Länge 'laenge', beginnend an der Position 'von' in
+ dem TEXT 'quelle'. Entspricht
+
+
+ text (subtext (quelle, von, LENGTH quelle),laenge)
+
+
+ Es muß
+
+
+ laenge >= 0
+ 1 <= von <= LENGTH quelle
+
+
+ gelten, d.h. 'von' muß eine Position angeben, die innerhalb von 'quelle' liegt. Für
+
+
+ laenge > LENGTH quelle - von + 1
+
+
+ also wenn die angegebene Länge 'laenge' größer ist als der auszublendende Text,
+ wird das Resultat rechts mit Leerzeichen aufgefüllt. Wenn
+
+
+ laenge < LENGTH quelle - von + 1
+
+
+ d.h. wenn die angegebene Länge kleiner ist als der Teiltext von 'von' bis zum
+ letzten Zeichen von 'quelle', wird das Resultat mit der Länge
+
+
+ LENGTH quelle - von + 1
+
+
+ geliefert.
+
diff --git a/doc/programmer-manual/1.8.7/doc/programmierhandbuch.5b b/doc/programmer-manual/1.8.7/doc/programmierhandbuch.5b
new file mode 100644
index 0000000..d91bcc9
--- /dev/null
+++ b/doc/programmer-manual/1.8.7/doc/programmierhandbuch.5b
@@ -0,0 +1,1481 @@
+#pagenr("%",40)##setcount(1)##block##pageblock#
+#headeven#
+#center#EUMEL-Benutzerhandbuch
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#TEIL 5 : Programmierung
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+5 - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#5 - %
+#end#
+
+5.3 Der Datentyp FILE (Textdateien)
+
+Der Datentyp FILE definiert Dateien von sequentieller Struktur, die Texte enthalten.
+Ein Objekt vom Datentyp FILE ist charakterisiert durch:
+
+1) seine Betriebsrichtung : input = nur lesender Zugriff
+ (TRANSPUTDIRECTION) output= nur schreibender Zugriff
+ modify= lesender und schreibender Zugriff.
+2) seinen Namen.
+
+Betriebsrichtung und Name werden in der Assoziierungsprozedur 'sequential file'
+(siehe Kap 2.8.2) festgelegt.
+
+
+____________________________________________________________________________
+
+ ........................... Beispiel ..........................
+ TEXT VAR name := ausgabe ;
+
+ FILE VAR f := sequential file(output,name) ;
+
+
+____________________________________________________________________________
+
+
+
+Das Festlegen einer Betriebsrichtung impliziert eine Kontrolle der Benutzung der
+betreffenden Datei, hilft somit Programmierfehler zu vermeiden.
+
+ACHTUNG : #on("b")##on("u")#Alle#off("b")##off("u")# Prozeduren, die auf FILEs zugreifen, verlangen Objekte vom Typ
+ FILE VAR, da die Lese/Schreiboperationen als ändernd betrachtet wer­
+ den (müssen).
+
+#page#
+
+5.3.1 Assoziierung
+
+'sequential file'
+ #on("b")#FILE PROC sequential file (TRANSPUTDIRECTION CONST mode, DATASPACE VAR ds) #off("b")#
+ Assoziierung einer sequentiellen Datei mit dem Dataspace 'ds' und der Betriebs­
+ richtung 'mode' (vergl. 'modify', 'input' bzw. 'output'). Diese Prozedur dient zur
+ Assoziierung eines temporä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.
+
+
+ #on("b")#FILE PROC sequential file (TRANSPUTDIRECTION CONST mode,TEXT CONST name)#off("b")#
+ Assoziierung einer sequentiellen Datei mit dem Namen 'name' und der Betriebs­
+ richtung 'mode' (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 dagagen der FILE noch nicht und ist die
+ TRANSPUTDIRECTION 'output' oder 'modify', wird ein neuer FILE eingerich­
+ tet.
+
+ FEHLER : "name" gibt es nicht"
+ Es wurde versucht, einen nicht vorhandenen FILE mit 'input' zu asso­
+ ziieren.
+
+#page#
+
+'input'
+ #on("b")#PROC input (FILE VAR f) #off("b")#
+ Ändern der Verarbeitungsart von 'modify' oder 'output' in 'input'. Dabei wird auf
+ den ersten Satz der Datei positioniert.
+
+ #on("b")#TRANSPUTDIRECTION CONST input #off("b")#
+ Assoziierung in Zusammenhang mit der Prozedur 'sequential file' einer sequentiel­
+ len Datei mit der 'TRANSPUTDIRECTION' 'input' (nur lesen).
+
+
+'output'
+ #on("b")#PROC output (FILE VAR file) #off("b")#
+ Ändern der Verarbeitungsart von 'input' oder 'modify' in 'output'. Dabei wird hinter
+ den letzten Satz der Datei positioniert.
+
+ #on("b")#TRANSPUTDIRECTION CONST output #off("b")#
+ In Verbindung mit der Prozedur 'sequential file' kann eine Datei assoziiert werden
+ mit der Betriebsrichtung 'output' (nur schreiben).
+
+
+'modify'
+ #on("b")#PROC modify (FILE VAR f) #off("b")#
+ Ändern der Betriebsrichtung von 'input' oder 'output' in die Betriebsrichtung 'mo­
+ dify'.
+
+ #on("b")#TRANSPUTDIRECTION CONST modify #off("b")#
+ Diese Betriebsrichtung erlaubt das Vorwärts- und Rückwärts-Positionieren und
+ das beliebige Einfügen und Löschen von Sätzen. 'modify' wird für die Assoziie­
+ rungsprozedur 'sequential file' benötigt.
+
+
+
+#page#
+
+5.3.2 Informationsprozeduren
+
+'eof'
+ #on("b")#BOOL PROC eof (FILE CONST file) #off("b")#
+ Informationsprozedur auf das Ende eines FILEs. Liefert den Wert TRUE, sofern
+ hinter den letzten Satz eines FILEs positioniert wurde.
+
+
+'line no'
+ #on("b")#INT PROC line no (FILE CONST file) #off("b")#
+ Liefert die aktuelle Zeilennummer.
+
+
+'lines'
+ #on("b")#PROC lines (FILE VAR f) #off("b")#
+ Liefert die Anzahl der Zeilen der Datei 'f'.
+
+
+'headline'
+ #on("b")#TEXT PROC headline (FILE CONST f) #off("b")#
+ Liefert den Inhalt der Kopfzeile der Datei 'f'.
+
+ #on("b")#PROC headline (FILE VAR f, TEXT CONST ueberschrift) #off("b")#
+ Setzt #ib#'ueberschrift' in die Kopfzeile#ie# der Datei 'f'.
+#page#
+
+5.3.3 Betriebsrichtung INPUT
+
+In der Betriebsrichtung 'input' sind nur Leseoperationen auf der Datei zugelassen. Die
+Assoziierungsprozedur 'sequential file' bewirkt:
+
+1) Falls die Eingabedatei noch nicht existiert, wird eine Fehlermeldung ausgegeben.
+
+2) Falls es eine Datei des Namens gibt, wird auf das erste Zeichen des ersten
+ Satzes positioniert.
+
+
+
+'get'
+ #on("b")#PROC get (FILE VAR f, INT VAR number) #off("b")#
+ Lesen des nächsten Wortes aus der Datei 'f' und Konvertierung des Wortes zu
+ einem Integer-Objekt.
+
+ #on("b")#PROC get (FILE VAR f, REAL VAR number) #off("b")#
+ Lesen des nächsten Wortes aus der Datei 'f' und Konvertierung des Wortes zu
+ einem Real-Objekt.
+
+
+ #on("b")#PROC get (FILE VAR f, TEXT VAR text) #off("b")#
+ Lesen des nächsten Wortes aus der Datei 'f'.
+
+ #on("b")#PROC get (FILE VAR f, TEXT VAR text, TEXT CONST delimiter)#off("b")#
+ Lesen eines TEXT-Wertes 'text' von der Datei 'f', bis das Zeichen 'delimiter'
+ angetroffen wird. Ein eventueller Zeilenwechsel in der Datei wird dabei übergan­
+ gen.
+
+ #on("b")#PROC get (FILE VAR f, TEXT VAR text, INT CONST maxlength)#off("b")#
+ Lesen eines TEXT-Wertes 'text' von der Datei 'f' mit 'maxlength' Zeichen. Ein
+ eventueller Zeilenwechsel in der Datei wird dabei nicht übergangen.
+
+
+
+'getline'
+ #on("b")#PROC get line (FILE VAR file, TEXT VAR record) #off("b")#
+ Lesen der nächsten Zeile aus der sequentiellen Datei 'file'.
+ Mögliche Fehler bei Betriebsrichtung 'input':
+
+ "Datei zu"
+ Die Datei 'file' ist gegenwärtig nicht assoziiert.
+
+ "Leseversuch nach Dateiende"
+ Es wurde versucht, über die letzte Zeile einer Datei zu lesen.
+
+ "Leseversuch auf output file"
+ Es wurde versucht, von einem mit 'output' assoziierten FILE zu lesen.
+
+ "Unzulässiger Zugriff auf modify-FILE"
+
+#page#
+
+5.3.4 Betriebsrichtung OUTPUT
+
+In der Betriebsrichtung 'output' sind nur Schreiboperationen auf der Datei zugelassen.
+Die Assoziierungsprozedur 'sequential file' bewirkt:
+
+1) Falls die Ausgabedatei noch nicht existiert, wird sie angelegt und auf den ersten
+ Satz positioniert.
+
+2) Falls es bereits eine Datei des Namens gibt, wird hinter den letzten Satz positio­
+ niert, die Datei wird also fortgeschrieben.
+
+
+'put'
+ #on("b")#PROC put (FILE VAR f, INT CONST number) #off("b")#
+ Ausgabe eines INT-Wertes 'number' in die Datei 'f'. Dabei wird ein Leerzeichen
+ an die Ausgabe angefügt.
+
+ #on("b")#PROC put (FILE VAR f, REAL CONST number) #off("b")#
+ Ausgabe eines REAL-Wertes 'number' in die Datei 'f'. Dabei wird ein Leerzei­
+ chen an die Ausgabe angefügt.
+
+ #on("b")#PROC put (FILE VAR f, TEXT CONST text) #off("b")#
+ Ausgabe eines TEXT-Wertes 'text' in die Datei 'f'. Dabei wird ein Leerzeichen an
+ die Ausgabe angefügt.
+
+
+
+'putline'
+ #on("b")#PROC putline (FILE VAR file, TEXT CONST record) #off("b")#
+ Ausgabe eines TEXTes 'record' in die Datei 'file'. Danach wird auf die nächste
+ Zeile positioniert. 'file' muß mit 'output' assoziiert sein.
+
+
+'write'
+ #on("b")#PROC write (FILE VAR f, TEXT CONST text) #off("b")#
+ Schreibt 'text' in die Datei 'f' (analog 'put (f, text)'), aber ohne Trennblank.
+
+
+'line'
+ #on("b")#PROC line (FILE VAR file) #off("b")#
+ Positionierung auf die nächste Zeile der Datei 'file'. Wird versucht, über das Ende
+ eines mit 'input' assoziierten FILEs zu positionieren, wird keine Aktion vorgenom­
+ men.
+
+ #on("b")#PROC line (FILE VAR file, INT CONST lines) #off("b")#
+ Positionierung mit 'lines' Zeilen Vorschub in der Datei 'file'.
+
+
+ FEHLER: "Datei zu!"
+ Die Datei 'file' ist gegenwärtig nicht assoziiert.
+
+ "Schreibversuch auf input-File"
+ Es wurde versucht, auf einen mit 'input' assoziierten FILE zu
+ schreiben.
+
+
+ Bei Textdateien, die mit dem Editor weiterbearbeitet werden sollen, ist also zu
+ beachten: ine Ausgabe mit 'put' setzt ein 'blank' hinter die Ausgabe. Falls dieses
+ Leerzeichen das letzte Zeichen in der Zeile ist, wird eine Absatzmarke in der Zeile
+ gesetzt. Wird mit 'write' oder 'putline' ausgegeben, steht kein Leerzeichen und
+ somit keine Absatzmarke am Zeilenende.
+#page#
+
+5.3.5 Betriebsrichtung MODIFY
+
+In der Betriebsrichtung 'modify' sind Lese- und Schreiboperationen auf der Datei
+zugelassen. Desweiteren ist beliebiges Positionieren in der Datei erlaubt. Neue Sätze
+können an beliebiger Stelle in die Datei eingefügt werden, die sequentielle Struktur
+der Datei bleibt erhalten. Die Assoziierungsprozedur 'sequential file' bewirkt:
+
+1) Falls die Ausgabedatei noch nicht existiert, wird sie angelegt.
+
+2) Falls es bereits eine Datei des Namens gibt, ist undefiniert wo positioniert ist. Die
+ erste Positionierung muß explizit vorgenommen werden!
+
+
+
+'col'
+ #on("b")#PROC col (FILE VAR f, INT CONST position) #off("b")#
+ Positionierung auf die Spalte 'position' innerhalb der aktuellen Zeile.
+
+ #on("b")#INT PROC col (FILE CONST f) #off("b")#
+ Liefert die aktuelle Position innerhalb der aktuellen Zeile.
+
+
+'down'
+ #on("b")#PROC down (FILE VAR f) #off("b")#
+ Positionieren um eine Zeile vorwärts.
+
+ #on("b")#PROC down (FILE VAR f, INT CONST number) #off("b")#
+ Positionieren um 'number' Zeilen vorwärts.
+
+
+'to line'
+ #on("b")#PROC to line (FILE VAR f, INT CONST number) #off("b")#
+ Positionierung auf die Zeile 'number'.
+
+
+'up'
+ #on("b")#PROC up (FILE VAR f) #off("b")#
+ Positionieren um eine Zeile rückwärts.
+
+ #on("b")#PROC up (FILE VAR f, INT CONST number) #off("b")#
+ Positionieren um 'number' Zeilen rückwärts.
+
+#page#
+'delete record'
+ #on("b")#PROC delete record (FILE VAR file) #off("b")#
+ Der aktuelle Satz der Datei 'file' wird gelöscht. Der folgende Satz wird der aktuelle
+ Satz.
+
+
+'insert record'
+ #on("b'PROC insert record (FILE VAR file) #off("b")#
+ 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).
+
+
+
+'read record'
+ #on("b")#PROC read record (FILE CONST file, TEXT VAR record) #off("b")#
+ Liest den aktuellen Satz der Datei 'file' in den TEXT 'record'. Die Position wird
+ dabei nicht verändert.
+
+
+
+'write record'
+ #on("b")#PROC write record (FILE VAR file, TEXT CONST record) #off("b")#
+ 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.
+
+
+#page#
+
+5.3.6 FILE -Ausschnitte
+
+Ähnlich den Editorfunktionen 'ESC RUBOUT' und 'ESC RUBIN', die erlauben ganze
+Abschnitte einer Datei zu löschen und das Gelöschte an anderer Stelle wiedereinzu­
+fügen, gibt es die Möglichkeit per Programm solche Segmente
+eines 'modify-FILEs' zu verschieben.
+
+
+'clear removed'
+ #on("b")#PROC clear removed (FILE VAR f) #off("b")#
+ Das mit 'remove' entfernte Segment wird gelöscht und nicht an anderer Stelle
+ eingefügt.
+
+
+'reinsert'
+ #on("b")#PROC reinsert (FILE VAR f) #off("b")#
+ Das mit 'remove' entfernte Segment wird vor die aktuelle Zeile wiedereingefügt.
+
+
+'remove'
+ #on("b")#PROC remove (FILE VAR f, INT CONST size) #off("b")#
+ Löscht 'size' Zeilen vor der aktuellen Position aus 'f'. Das Segment wird in einen
+ internen Puffer geschrieben.
+
+
+'reorganize'
+ #on("b")#PROC reorganize (TEXT CONST datei)#off("b")#
+ Reorganisation von 'datei'. Die durch Löschen und Einfügen aus vielen
+ Segmenten bestehende Datei wird zu einem Segment zusammengefügt, die
+ aktuelle Position ist danach das erste Zeichen der ersten Zeile.
+
+ Durch diese Prozedur kann ggf. Speicherplatz gespart werden.
+
+ #on("b")#PROC reorganize#off("b")#
+ Reorganisation der zuletzt bearbeiteten Datei.
+
+
+'segments'
+ #on("b")#PROC segments (FILE VAR f) #off("b")#
+ Liefert die Anzahl der Segmente von 'f'. Eine große Anzahl von Segmenten kann
+ langsamere Zugriffe zur Folge haben.
+
+#page#
+
+5.4 Suchen und Ersetzen in Textdateien
+
+Such- und Ersetzungsprozeduren können sowohl interaktiv beim Editieren (siehe
+dazu 3.3), als auch in Prozeduren, die auf FILEs (siehe 5.3) arbeiten, angewandt
+werden.
+
+Die dazu dienenden Prozeduren sind im Paket 'pattern match' enthalten. Mit 'Pattern
+Matching' (Muster treffen) wird ein Verfahren bezeichnet Gleichheit von Objekten
+anhand von Regeln, denen diese Objekte genügen, zu überprüfen.
+
+Da oft nach Texten gesucht werden muß, deren genaue Ausprägung nicht bekannt ist,
+oder deren Auftreten nur in einem bestimmten Zusammenhang interessiert, gibt es die
+Möglichkeit feststehende Textelemente mit Elementen ungewisser Ausprägung zu
+kombinieren, also Textmuster zu erzeugen.
+
+Um einen Text zu suchen, muß die Suchrichtung und der gesuchte Text oder ein
+Muster, welches diesen Text beschreibt, angegeben werden.
+
+- Aufbauen von Textmustern : + , - , OR , any , bound , notion
+
+- Suchen nach Textmustern : down , downety , up , uppety
+
+- Treffer registrieren : LIKE , UNLIKE , at , pattern found
+
+- Treffer herausnehmen : ** , match , matchend , matchpos ,
+ somefix , word
+
+- Ändern in Dateien : change
+
+
+Nach einem erfolgreichen Suchvorgang ist stets auf das erste Zeichen der zu such­
+enden Zeichenkette positioniert.
+
+
+Eine besondere Funktion kommt dem 'joker' zu: Dieses Symbol (Defaultwert: '*') steht
+für eine beliebige Zeichenkette beliebiger Länge. Insbesondere bei Ersetzungsaktionen
+in denen dieses Zeichen zur Musterbeschreibung verwendet wird, ist daher Vorsicht
+geboten und sorgfältig zu testen.
+
+#page#
+
+5.4.1 Aufbau von Textmustern
+
+'+'
+ #on("b")#TEXT OP + (TEXT CONST links, rechts) #off("b")#
+ Verkettung der Texte 'links' und 'rechts' zu 'linksrechts'. Falls das Ergebnis länger
+ als die maximal zulässige Textlänge ist, ist es undefiniert.
+
+ Wenn 'muster1' einen beliebigen Text finden sollte, ( Siehe: PROC any) wird das
+ Ende des von 'muster1' erkannten Textes durch den Anfang des von 'muster2'
+ erkannten Textes im Nachhinein definiert.
+
+
+
+'-'
+ #on("b")#TEXT OP - (TEXT CONST alphabet) #off("b")#
+ Der Operator liefert das zu 'alphabet' komplementäre Alphabet, also alle Zeichen
+ gemäß der EUMEL Codetabelle (5.2.4), die nicht in 'alphabet' enthalten sind.
+ Sinnvoll im Zusammenhang mit der Textprozedur 'any'.
+
+
+'OR'
+ #on("b")#TEXT OP OR (TEXT CONST links, rechts) #off("b")#
+ Liefert die Alternative von 'links' und 'rechts'. Die Reihenfolge spielt beim Suchen
+ keine Rolle.
+
+
+
+'any'
+ Die Textprozedur 'any' liefert einen unbekannten Text unbestimmter Länge.
+ Dieser Text sollte entweder durch festen Text sinnvoll eingegrenzt werden, oder
+ direkt eingeschränkt werden.
+
+
+ #on("b")#TEXT PROC any #off("b")#
+ Beschreibt einen beliebigen Text.
+
+ #on("b")#TEXT PROC any (INT CONST laenge) #off("b")#
+ Beschreibt einen beliebigen Text der angebenen Länge.
+
+
+ #on("b")#TEXT PROC any (TEXT CONST alphabet) #off("b")#
+ Beschreibt einen beliebigen Text, der nur aus Zeichen besteht, die in 'alphabet'
+ enthalten sind.
+
+
+ #on("b")#TEXT PROC any (INT CONST laenge, TEXT CONST alphabet) #off("b")#
+ Beschreibt einen Text der vorgegebenen Länge, der nur aus den in 'alphabet'
+ vorgegebenen Zeichen besteht.
+
+
+____________________________________________________________________________
+
+ ........................... Beispiel ..........................
+ Die Textprozedur 'any' liefert einen unbekannten Text unbe­
+ stimmter Länge. Dieser Text sollte entweder durch festen Text
+ sinnvoll eingegrenzt werden, oder direkt eingeschränkt werden.
+gib kommando: D("D" OR "d" + any (2,"aeirs")
+ Sucht nach bestimmten Artikeln: 'der', 'die', 'das' etc.
+
+____________________________________________________________________________
+
+
+
+'bound'
+ #on("b")#TEXT PROC bound #off("b")#
+ Bezeichnet ein Muster der Länge null, das nur am Zeilenanfang oder am Zeilenen­
+ de gefunden wird. Ein Präfix 'bound' fordert, daß das gesuchte Muster in der
+ ersten Spalte beginnen muß, ein Postfix 'bound' fordert, daß das Muster mit dem
+ Zeilenende abschließt.
+
+____________________________________________________________________________
+
+ ........................... Beispiel ..........................
+ Die Textprozedur 'any' liefert einen unbekannten Text unbe­
+ stimmter Länge. Dieser Text sollte entweder durch festen
+ Textsinnvoll eingegrenzt werden, oder direkt eingeschränkt
+ werden.
+gib kommando: U(bound + any (" "))
+
+____________________________________________________________________________
+
+
+
+ liefert Treffer bei eingerückten Zeilen.
+
+
+
+'notion'
+ #on("b")#PROC notion (TEXT CONST suchwort) #off("b")#
+ Mit dieser Prozedur kann ein #on("u")#Wort#off("u")# spezifiziert werden, nach dem gesucht werden
+ soll. Bei der Suche nach 'suchwort' wird nur dann ein Treffer geliefert, wenn
+ 'suchwort' als Wort, also begrenzt von ' ' (blank), '.' , ',' oder anderen Sonderzei­
+ chen ist.
+
+ #on("b")#PROC notion (TEXT CONST suchwort, INT CONST reg) #off("b")#
+ Wie oben, der Treffer wird im Register 'reg' gespeichert.
+
+#page#
+
+5.4.2 Suche nach Textmustern
+
+'down'
+ #on("b")#PROC down (FILE VAR f, TEXT CONST muster) #off("b")#
+ Suche nach 'muster' in der Datei 'f' in Richtung Dateiende. Wird 'muster' gefun­
+ den, ist die Position das erste Zeichen von 'muster'. 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.
+
+
+ #on("b")#PROC down (FILE VAR f, TEXT CONST muster, INT CONST number)#off("b")#
+ Wie obiges 'down', es wird aber maximal nur 'number'-Zeilen weit nach 'muster'
+ gesucht.
+
+
+
+'downety'
+ #on("b")#PROC downety (FILE VAR f, TEXT CONST muster) #off("b")#
+ Suche nach 'muster' in der Datei 'f' in Richtung Dateiende. Wird 'muster' gefun­
+ den, ist die Position das erste Zeichen von 'muster'. Andernfalls steht man auf
+ dem letzten Zeichen der Datei.
+
+ Achtung: 'downety' sucht (im Gegensatz zu 'down') vom aktuellen Zeichen an.
+ Daher muß explizit vorwärts positioniert werden.
+
+
+ #on("b")#PROC downety (FILE VAR f, TEXT CONST muster, INT CONST number) #off("b")#
+ Wie obiges 'downety', aber maximal nur 'number'-Zeilen weit.
+#page#
+'up'
+ #on("b")#PROC up (FILE VAR f, TEXT CONST muster) #off("b")#
+ Suche nach 'muster' in der Datei 'f' in Richtung Dateianfang. Wird 'muster'
+ gefunden, ist die Position das erste Zeichen von 'muster'. Andernfalls steht man
+ auf dem ersten Zeichen der Datei.
+
+ Achtung: 'up' sucht vom nächsten Zeichen links ab, so daß wiederholtes Suchen
+ keine Endlosschleife ergibt.
+
+
+ #on("b")#PROC up (FILE VAR f, TEXT CONST muster, INT CONST number)#off("b")#
+ Wie obiges 'up', aber maximal nur 'number'-Zeilen weit.
+
+
+
+'uppety'
+ #on("b")#PROC uppety (FILE VAR f, TEXT CONST muster) #off("b")#
+ Suche nach 'muster' in der Datei 'f' in Richtung Dateianfang. Wird 'muster'
+ gefunden, ist die Position das erste Zeichen von 'muster'. Andernfalls steht man
+ auf dem ersten Zeichen der Datei.
+
+ Achtung: 'uppety' sucht (im Gegensatz zu 'up') vom aktuellen Zeichen.
+
+
+ #on("b")#PROC uppety (FILE VAR f, TEXT CONST muster, INT CONST number)#off("b")#
+ Wie obiges 'uppety', aber maximal nur 'number'-Zeilen weit.
+
+#page#
+
+5.4.3 Treffer registrieren
+
+'LIKE'
+ #on("b")#BOOL OP LIKE (TEXT CONST text , muster) #off("b")#
+ Liefert TRUE, falls der Text 'text' 'muster' entspricht. In 'muster' kann das
+ Spezialzeichen '*' verwandt werden, das abkürzend für die Konkatenation mit
+ 'any' steht.
+
+ Daraus folgt, daß das Suchen oder Ersetzen des Zeichens '*' nur durch
+ any (1,"*") zu bewerkstelligen ist.
+
+
+____________________________________________________________________________
+
+ ........................... Beispiel ..........................
+ \#Druckdateien aus Thesaurus löschen\#
+ gib kommando:"*.p" C ""
+ 16.04.87 "Handbuch teil1"
+ 04.05.87 "Handbuch teil1.p"
+ 16.04.87 "Handbuch teil2"
+ 06.05.87 "Handbuch teil2.p"
+
+____________________________________________________________________________
+
+
+
+ aber:
+
+____________________________________________________________________________
+
+ ........................... Beispiel ..........................
+ \#Vordere Kommentarklammern löschen \#
+ gib kommando:"(" + any(1,"*") C ""
+ lernsequenz auf taste legen("a" , "archive") ;
+ (* lernsequenz auf taste legen("(" , ""91"") ; *)
+ (* lernsequenz auf taste legen(")" , ""93"") ; *)
+ kommando auf taste legen("P" , "print("""")"8""8""11"") .
+
+____________________________________________________________________________
+
+
+
+'UNLIKE'
+ #on("b")#BOOL OP UNLIKE (TEXT CONST text , muster) #off("b")#
+ Wirkt wie: '(NOT text LIKE muster)'
+#page#
+
+5.4.4 Treffer herausnehmen
+
+Mit Hilfe der 'Register' ist es möglich identifizierte Texte zwischenzuspeichern und in
+weiteren Aktionen weiterzuverwenden.
+
+
+'**'
+ #on("b")#TEXT OP ** (TEXT CONST muster, INT CONST register)#off("b")#
+ Der als 'muster' erkannte Text wird einem 'Register' mit der Nummer 'register'
+ zugeordnet. Es können 256 Register (1 bis 256) benutzt werden.
+
+
+'match'
+ #on("b")#TEXT PROC match (INT CONST nr) #off("b")#
+ Liefert den Text der dem Register 'nr' zuletzt zugeordnet wurde.
+
+
+'matchpos'
+ #on("b")#INT PROC matchpos (INT CONST nummer) #off("b")#
+ Liefert die Spaltennummer, auf der das dem Register 'nummer' zugeordnete Mu­
+ ster in der Zeile beginnt.
+
+____________________________________________________________________________
+
+ ........................... Beispiel ..........................
+
+ gib kommando:D("file"+any+"("+(any ** (1)...
+
+____________________________________________________________________________
+#page#
+
+5.4.5 Ändern in Dateien
+
+'change'
+ #on("b")#PROC change (FILE VAR datei, INT CONST von, bis , TEXT CONST neuertext)#off("b")#
+ In der Datei wird in der aktuellen Zeile in den Ausschnitt zwischen 'von' und 'bis'
+ der Text 'neuertext' eingesetzt.
+
+ entspricht:
+
+
+____________________________________________________________________________
+
+ ........................... Beispiel ..........................
+ FILE VAR file := sequential file (modify, name)
+ TEXT VAR zeile;
+ .
+ .
+ read record (file ,zeile);
+ change (zeile, von, bis ,"neuertext");
+ write record (file, zeile);
+ .
+
+____________________________________________________________________________
+
+#page#
+
+5.4.6 Editor-Prozeduren
+
+'edit'
+ #on("b")#edit (TEXT CONST datei)#off("b")#
+ Editieren der Datei 'datei'. Das Editorfenster ist maximal groß (von 1,1 bis
+ max,max). Der Standard-Kommandointerpreter ist gültig, so daß Eingaben, die
+ mit #schl("ESC")# beginnen, interpretiert werden, wie in 3.4 'Vorbelegte Tasten' beschrie­
+ ben.
+
+ #on("b")#edit#off("b")#
+ Wie oben, editiert wird die Datei mit dem zuletzt benutzten Namen.
+
+ #on("b")#edit (THESAURUS CONST thes)#off("b")#
+ Wie oben, editiert werden alle Dateien, deren Namen im Thesaurus 'thes' enthal­
+ ten sind.
+
+ #on("b")#edit (TEXT CONST datei, INT CONST von x, von y, bis x, bis y)#off("b")#
+ Editieren der Datei 'datei'. Das Editorfenster hat die linke obere Ecke bei 'von x,
+ von y' und die rechte untere Ecke bei 'bis x, bis y'.
+
+ #on("b")#edit (FILE VAR f)#off("b")#
+ Editieren der als 'sequential file' assoziierten Textdatei 'f'.
+
+ #on("b")#edit (FILE VAR, INT CONST von x, von y, bis x, bis y)#off("b")#
+ Editieren der als 'sequential file' assoziierten Textdatei in einem Fenster mit der
+ linken, oberen Ecke 'von x, von y' und der rechten, unteren Ecke 'bis x, bis y'.
+
+ #on("b")#edit (FILE VAR f, TEXT CONST res,
+ PROC (TEXT CONST) kdo interpreter)#off("b")#
+ Editieren der als 'sequential file' assoziierten Textdatei 'f'. In 'res' werden reser­
+ vierte Zeichen übergeben, die von der Prozedur 'kdo interpreter' als Kommandos
+ interpretiert werden, wenn sie als ESC-Sequenz eingegeben werden.
+ Beispiel : #schl("ESC ")# #schl("e")#
+
+#page#
+'editget'
+ #on("b")#editget (TEXT VAR ausgabe) #off("b")#
+ Aufruf des Zeileneditor. An der aktuellen Cursorposition wird eine Zeile ausgegeben in
+ der 'ausgabe' steht. Für diese Zeile stehen alle Editiermöglichkeiten zur
+ Verfügung, 'ausgabe' kann also beliebig überschrieben, ergänzt etc. werden. Die
+ Eingabe wird durch #schl("CR")# abgeschlossen. Im Gegensatz zur Prozedur 'get' ist auch
+ eine leere Eingabe möglich.
+
+ #on("b")#editget (TEXT VAR ausgabe, INT CONST zeile, INT CONST scroll,
+ TEXT CONST sep, TEXT CONST res, TEXT VAR exit) #off("b")#
+ Wie oben, die Zeilenlänge ist jedoch auf 'zeile' Zeichen begrenzt. Die Eingabe
+ wird durch #schl("CR")# oder durch eine Cursorbewegung über die Position 'zeile' hinaus
+ abgeschlossen.
+
+ Die Angabe 'scroll' setzt die Breite des Zeilenfensters fest, wird diese Breite
+ überschritten, so wird 'ausgabe' gerollt.
+
+ In 'sep' (Separator) können Zeichen festgesetzt werden, mit denen die Eingabe
+ beendet wird (zusätzlich zu CR !).
+
+ In 'res' (reservierte Tasten) können Tasten festgelegt werden, die in Verbindung
+ mit <ESC> die Eingabe beenden.
+
+ Wurde der Zeileneditor durch einen Separator verlassen, so steht in 'exit' dieses
+ Zeichen. Falls der Zeileneditor durch eine reservierte Taste verlassen, so enthält
+ 'exit' 'ESC' und die Taste.
+
+ #on("b")#editget (TEXT VAR ausgabe, INT CONST zeile, INT CONST scroll)#off("b")#
+ Bedeutung der Parameter siehe oben.
+
+ #on("b")#editget (TEXT VAR ausgabe, TEXT CONST sep, TEXT CONST res,
+ TEXT VAR exit) #off("b")#
+ Bedeutung der Parameter siehe oben.
+
+ #on("b")#editget (TEXT VAR ausgabe, INT CONST zeile, TEXT VAR exit) #off("b")#
+ Bedeutung der Parameter siehe oben.
+#page#
+
+5.4.7 Sortierung von Textdateien
+
+Für die Sortierung von Textdateien gibt es zwei Sortierprogramme:
+
+- Sortierung nach ASCII : sort
+
+- Sortierung nach
+ deutschem Alphabet : lexsort
+
+
+'sort'
+ #on("b")#PROC sort (TEXT CONST datei) #off("b")#
+ Diese Prozedur sortiert die Datei 'datei' zeilenweise gemäß der von der EUMEL
+ Codetabelle (siehe 5.2.4) vorgegebenen Reihenfolge. Zur Sortierung werden die
+ Zeilen vom ersten Zeichen der Zeile beginnend, zeichenweise verglichen und
+ dementsprechend sortiert.
+
+ #on("b")#PROC sort (TEXT CONST datei, INT CONST position) #off("b")#
+ Sortierkriterien wie oben, jedoch wird bei Vergleich und Sortierung der Satz erst
+ ab der Position 'position' beachtet. Sortiert wird der ganze Satz!
+
+
+'lex sort'
+ #on("b")#PROC lex sort (TEXT CONST datei) #off("b")#
+ Zeilenweise Sortierung nach lexikographischer Reihenfolge gemäß DIN 5007. Zu
+ den Vergleichen werden die Operatoren LEXEQUAL, LEXGRATER,
+ LEXGRATEREQUAL benutzt (siehe 5.2.4).
+
+ #on("b")#PROC lex sort (TEXT CONST datei, INT CONST position) #off("b")#
+ Lexikalische Sortierung durch Vergleich ab Position 'position'.
+
+#page#
+
+5.4.8 Prozeduren auf Datenräumen
+
+Neben den Textdateien gibt es im EUMEL-System den Typ Datenraum, der Objekte
+jeglichen Typs aufnehmen kann und direkten Zugriff auf die Objekte gewährt (siehe
+2.9.2).
+
+Für Objekte von Type Datenraum (nicht für die in Datenräumen enthaltenen Objekte!)
+existieren folgende Standardprozeduren:
+
+
+':='
+ #on("b")#OP := ( DATASPACE VAR ds1, DATASPACE CONST ds2)#off("b")#
+ Der Datenraum 'ds1' wird als Kopie von 'ds2' angelegt. Es handelt sich zunächst
+ um eine logische Kopie, eine physische Kopie wird erst nach einem Schreibzugriff
+ auf 'ds1' oder 'ds2' nötig.
+
+
+'new'
+ #on("b")#DATASPACE PROC new (TEXT CONST dsname) #off("b")#
+ Liefert einen neuen Datenraum namens 'dsname'.
+
+____________________________________________________________________________
+
+ DATASPACE VAR ds := new ("datenraum")
+ (* ergibt zwei Datenräume 'ds' und 'datenraum'! *)
+
+____________________________________________________________________________
+
+
+
+'nilspace'
+ #on("b")#DATASPACE PROC nilspace#off("b")#
+ Der 'nilspace' ist ein leerer Datenraum, der ausschließlich als Quelle zum Kopie­
+ ren bei der Initialisierung Verwendung finden darf.
+
+
+'old'
+ #on("b")#DATASPACE PROC old (TEXT CONST dsname) #off("b")#
+ Liefert einen bereits existierenden Datenraum (oder auch eine Datei) mit dem
+ Namen 'dsname'.
+
+ FEHLER : "dsname" gibt es nicht
+
+
+'type'
+ #on("b")#PROC type (DATASPACE CONST ds, INT CONST typ)#off("b")#
+ Der Datenraum 'ds' erhält den frei wählbaren Schlüssel 'typ'. Es muß eine positive
+ Zahl gewählt werden. Der Datenraum muß zum Zeitpunkt der Typzuweisung an
+ ein BOUND Objekt gekoppelt (gewesen) sein.
+
+ #on("b")#INT PROC type (DATASPACE CONST ds)#off("b")#
+ Liefert den Schlüssel des Datenraums 'ds'. Falls 'ds' nie an ein BOUND Objekt
+ gekoppelt war, liefert die Prozedur einen Wert < 0, sonst 0 (keine Zuweisung
+ erfolgt) oder die zugewiesene Typnummer.
+
+
+'dataspaces'
+ #on("b")#INT PROC dataspaces (TASK CONST task) #off("b")#
+ Liefert die Anzahl der Datenräume der Task 'task'.
+
+ #on("b")#INT PROC dataspaces #off("b")#
+ Anzahl der Datenräume von 'myself'.
+
+
+'ds pages'
+ #on("b")#INT PROC ds pages (DATASPACE CONST ds)#off("b")#
+ Liefert die Anzahl der durch 'ds' belegten Seiten (je 512 Byte).
+
+
+'storage'
+ #on("b")#INT PROC storage (DATASPACE CONST ds)#off("b")#
+ Liefert den von 'ds' belegten Speicherplatz in KB.
+
+#page#
+'copy'
+ #on("b")#PROC copy (DATASPACE CONST ds, TEXT CONST datei) #off("b")#
+ Eine neue Datei mit dem Namen 'datei' wird angelegt. Der Inhalt der Datei ist eine
+ Kopie des Inhalts des Datenraumes 'ds'.
+
+
+'forget'
+ #on("b")#PROC forget (DATASPACE CONST ds)#off("b")#
+ Der Datenraum 'ds' wird gelöscht#u#1)#e#.
+
+#foot#
+
+ 1) Durch diese Prozedur steht nicht unmittelbar mehr freier Speicherplatz zur
+ Verfügung. Die physische Räumung von Speicherplatz erfolgt durch die
+ 'Müllabfuhr' bei einem Fixpunkt.
+#end#
+
+'fetch'
+ #on("b")#PROC fetch (DATASPACE CONST ziel, TEXT CONST datei,
+ TASK CONST manager) #off("b")#
+ Aus der Task 'manager' wird der Datenraum der Datei 'datei' in den eigenen
+ Datenraum 'ziel' kopiert.
+
+
+'save'
+ #on("b")#PROC save (DATASPACE CONST quelle, TEXT CONST datei,
+ TASK CONST manager) #off("b")#
+ Der eigene Datenraum 'quelle' wird in die Datei 'datei' in der Task 'manager'
+ kopiert.
+#page#
+
+5.5 Eingabe/Ausgabe
+
+- Eingabesteuerzeichen : HOP , � � � � , TAB , RUBIN , RUBOUT
+ CR , MARK , ESC
+
+- Ausgabesteuerzeichen : HOME , � � � � , CL EOP , CL EOL
+ CPOS , BELL , CR , ENDMARK , BEGINMARK
+
+- Positionierung : cursor , get cursor , line , page
+
+- Eingabe : get , getline , inchar , incharety
+
+- Ausgabe : cout , out , out subtext , put , putline ,
+ TIMESOUT , write
+
+- Kontrolle : online , pause , sysin , sysout
+
+- Zeitmessung : clock , date , day , hour , pause , time
+ time of day
+
+#page#
+
+5.5.1 E/A auf Bildschirm
+
+Steuerzeichen und Standardprozeduren zur Ein- Ausgabe am Bildschirm werden
+zur Steuerung des Dialogverhaltens von Prozeduren benutzt.
+
+
+5.5.1.1 Eingabesteuerzeichen
+Eingabesteuerzeichen werden durch die Funktionstasten (s. 3.2) erzeugt. Die Wirkung
+der Tasten ist ebenfalls an dieser Stelle beschrieben.
+
+Durch die Tasten werden folgende Codes an Programme gegeben:
+
+Codierung I Bezeichnung
+-----------+--------------
+HOP I 1
+RECHTS I 2
+OBEN I 3
+LINKS I 8
+TAB I 9
+UNTEN I 10
+RUBIN I 11
+RUBOUT I 12
+CR I 13
+MARK I 16
+ESC I 27
+
+
+#page#
+
+5.5.1.2 Ausgabesteuerzeichen
+
+Die Ausgabe dieser Zeichen bewirkt folgendes Verhalten der Bildschirmausgabe.
+
+Code I Name I Wirkung
+-----+-------------+-------------------------------------------------------
+ 0 I NUL I keine Wirkung
+ 1 I HOME I Cursor in die linke obere Ecke setzen (Position 0,0!)
+ 2 I RECHTS I Cursor eine Stelle nach rechts setzen
+ 3 I OBEN I Cursor eine Zeile höher setzen
+ 4 I CL EOP I Rest der Seite löschen
+ 5 I CL EOL I Rest der Zeile löschen
+ 6 I CPOS I Cursor setzen, nächstes Ausgabezeichen bestimmt die
+ I I y-Position, das darauf folgende die x-Position.
+ 7 I BELL I akustisches Signal
+ 8 I LINKS I Cursor eine Stelle nach links setzen
+10 I UNTEN I Cursor eine Stelle nach unten setzen
+13 I CR I Cursor an den Anfang der nächsten Zeile setzen
+14 I ENDMARK I Ende des markierten Bereichs
+15 I BEGINMARK I Anfang des markierten Bereichs
+
+
+
+
+____________________________________________________________________________
+
+ ........................... Beispiel ..........................
+ TEXT VAR ausgabe := (""7""15"V O R S I C H T"14"7"");
+ out(ausgabe);
+
+____________________________________________________________________________
+
+#page#
+
+5.5.1.3 Positionierung
+
+'cursor'
+ #on("b")#PROC cursor (INT CONST column, row) #off("b")#
+ 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äteab­
+ hängig.
+
+
+
+'get cursor'
+ #on("b")#PROC get cursor (INT VAR x, y) #off("b")#
+ Erfragung der aktuellen Cursor-Position. Die Koordinaten des Cursors 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 Prozedur '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).
+
+
+'line'
+ #on("b")#PROC line #off("b")#
+ Es wird zum Anfang einer neuen Zeile positioniert.
+
+ #on("b")#PROC line (INT CONST number) #off("b")#
+ Es werden 'number' Zeilenwechsel vorgenommen.
+
+
+'page'
+ #on("b")#PROC page #off("b")#
+ Es wird zum Anfang einer neuen Seite positioniert (hier: linke obere Ecke (Position
+ 1,1 !) des Bildschirms, wobei der Bildschirm gelöscht wird).
+
+#page#
+
+5.5.1.4 Eingabe
+
+
+Grundlegende Prozeduren
+Die folgenden Prozeduren dienen ausschließlich der Eingabe vom Terminal.
+
+'editget'
+ Siehe 5.4.6
+
+
+'getchar'
+ #on("b")#PROC getchar (TEXT VAR zeichen)#off("b")#
+ Liest genau ein Zeichen von der Tastatur und schreibt es in die Variable 'zeichen'.
+
+
+'inchar'
+ #on("b")#PROC inchar (TEXT VAR character) #off("b")#
+ Wartet solange, bis ein Zeichen von der Tastatur eingegeben wird, und schreibt
+ dieses Zeichen in die Variable 'character'.
+
+
+'incharety'
+ #on("b")#TEXT PROC incharety #off("b")#
+ Versucht, ein Zeichen von der Tastatur zu lesen. Wurde kein Zeichen eingegeben,
+ wird niltext geliefert.
+
+ #on("b")#TEXT PROC incharety (INT CONST time limit) #off("b")#
+ Versucht, ein Zeichen vom Bildschirm zu lesen. Dabei wird maximal eine 'time
+ limit' lange Zeit auf das Zeichen gewartet (gemessen in Zehntel-Sekunden).
+
+#page#
+
+Umleitbare Eingabeprozeduren
+Die folgenden Eingabeprozeduren lesen ebenfalls vom Terminal, die Eingabequelle
+kann jedoch durch die Prozedur 'sysin' umgestellt werden. Falls in 'sysin' eine Datei
+angegeben wird wird die Eingabe statt vom Terminal aus dieser Datei gelesen.
+
+
+'sysin'
+ #on("b")#PROC sysin (TEXT CONST file name) #off("b")#
+ Eingabe-Routinen lesen nicht mehr vom Benutzer-Terminal, sondern aus der
+ Datei 'file name'.
+
+ #on("b")#TEXT PROC sysin #off("b")#
+ Liefert den Namen der eingestellten 'sysin'-Datei. "" bezeichnet das Benutzer-
+ Terminal.
+
+
+'get'
+ #on("b")#PROC get (INT VAR number) #off("b")#
+ Einlesen eines INT-Wertes vom Bildschirm. Der einzulesende INT-Wert kann
+ bei der Eingabe vom Terminal editiert werden.
+
+ #on("b")#PROC get (REAL VAR value) #off("b")#
+ Einlesen eines REAL-Wertes vom Bildschirm. Der einzulesende REAL-Wert
+ kann bei der Eingabe vom Terminal editiert werden.
+
+ #on("b")#PROC get (TEXT VAR word) #off("b")#
+ Liest einen Text in die Variable 'word' mit maximal 255 Zeichen. Es werden
+ solange Zeichen vom Terminal gelesen, bis ein Leerzeichen oder #schl("CR")# eingegeben
+ wird. Dabei werden führende Leerzeichen übergeben. Der einzulesende Text
+ kann bei der Eingabe editiert werden. Eine leere Eingabe ist nicht erlaubt.
+
+ #on("b")#PROC get (TEXT VAR word, INT CONST laenge) #off("b")#
+ Liest einen Text vom Bildschirm mit der Länge 'laenge' oder bis #schl("CR")# eingegeben
+ wird. Der einzulesende Wert kann bei der Eingabe editiert werden.
+
+ #on("b")#PROC get (TEXT VAR word, TEXT CONST separator) #off("b")#
+ Liest einen Text vom Bildschirm, bis ein Zeichen 'separator' angetroffen oder #schl("CR")#
+ eingegeben wird. Der einzulesende Text kann bei der Eingabe editiert werden.
+
+
+'getline'
+ #on("b")#PROC get line (TEXT VAR line) #off("b")#
+ Das System wartet auf eine Zeile vom Bildschirm (max. 255 Zeichen). #schl("CR")# been­
+ det die Eingabe.
+
+#page#
+
+5.5.1.5 Ausgabe
+
+
+Grundlegende Prozeduren
+Die folgenden Prozeduren dienen ausschließlich der Ausgabe auf das Terminal.
+
+
+'cout'
+ #on("b")#PROC cout (INT CONST number) #off("b")#
+ Schreibt 'number' an die aktuelle Cursor-Position auf den Bildschirm. Anschlie­
+ ßend wird an diese Position wieder zurück positioniert. 'number' muß > 0 sein.
+ Paßt 'number' nicht mehr auf die Zeile, so ist die Wirkung von 'cout' nicht de­
+ finiert. '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.
+
+
+'out'
+ #on("b")#PROC out (TEXT CONST text) #off("b")#
+ Ausgabe eines Textes auf dem Bildschirm. Im Unterschied zu 'put' wird kein
+ Blank an den ausgegebenen Text angefügt.
+
+
+
+'out subtext'
+ #on("b")#PROC out subtext (TEXT CONST source, INT CONST from) #off("b")#
+ Ausgabe eines Teiltextes von 'source' von der Position 'from' bis Textende. Es
+ wird keine Aktion vorgenommen für
+
+
+ from > LENGTH source
+
+
+ #on("b")#PROC out subtext (TEXT CONST source, INT CONST from, to)#off("b")#
+ Ausgabe eines Teiltextes von 'source' von der Position 'from' bis zur Position 'to'.
+ Für
+
+
+ to > LENGTH source
+
+
+ wird out subtext (source, from) ausgeführt.
+
+ #on("b")#PROC out text (TEXT CONST source, INT CONST from, to) #off("b")#
+ Ausgabe eines Teiltextes von 'source' von der Position 'from' bis zur Position 'to'.
+ Für
+
+
+ to > LENGTH source
+
+
+ wird für die fehlenden Zeichen Blanks ausgegeben.
+
+
+
+'TIMESOUT'
+ #on("b")#OP TIMESOUT (INT CONST times, TEXT CONST text) #off("b")#
+ 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
+
+
+#page#
+
+Umleitbare Ausgabeprozeduren
+Die folgenden Ausgabeprozeduren schreiben ebenfalls auf das Terminal, die Ausgabe
+kann jedoch durch die Prozedur 'sysout' umgeleitet werden. Falls in 'sysout' eine
+Datei angegeben wird wird die Ausgabe statt zum
+Terminal in die angegebene Datei geleitet.
+
+
+'sysout'
+ #on("b")#PROC sysout (TEXT CONST file name) #off("b")#
+ Ausgabe-Routinen gehen nicht mehr zum Benutzer-Terminal, sondern in die
+ Datei 'file name'.
+
+ #on("b")#TEXT PROC sysout #off("b")#
+ Liefert den Namen der eingestellten 'sysout'-Datei. "" bezeichnet das Benut­
+ zer-Terminal.
+
+
+'line'
+ #on("b")#line#off("b")#
+ Positionierung auf den Anfang einer neuen Ausgabezeile.
+
+ #on("b")#line (INT CONST faktor)#off("b")#
+ Nächste Ausgabezeile um 'faktor' Zeilen weiter positionieren.
+
+
+'put'
+ #on("b")#PROC put (INT CONST number) #off("b")#
+ Ausgabe eines INT-Wertes auf dem Bildschirm. Anschließend wird ein Leer­
+ zeichen ausgegeben.
+
+ #on("b")#PROC put (REAL CONST real) #off("b")#
+ Ausgabe eines REAL-Wertes auf dem Bildschirm. Anschließend wird ein Leer­
+ zeichen ausgegeben.
+
+ #on("b")#PROC put (TEXT CONST text) #off("b")#
+ Ausgabe eines Textes auf dem Bildschirm. Nach der Ausgabe von 'text' wird ein
+ Blank ausgegeben, um nachfolgenden Ausgaben auf der gleichen Zeile voneinan­
+ der zu trennen. Hardwareabhängig sind die Aktionen, wenn eine Ausgabe über
+ eine Zeilengrenze (hier: Bildschirmzeile) vorgenommen wird. Meist wird die Ausga­
+ be auf der nächsten Zeile fortgesetzt.
+
+
+'putline'
+ #on("b")#PROC putline (TEXT CONST text) #off("b")#
+ 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 Ausgabe über eine Zeilengrenze (hier: Bildschirm­
+ zeile) vorgenommen wird. Meist wird die Ausgabe auf der nächsten Zeile fort­
+ gesetzt.
+
+
+'write'
+ #on("b")#PROC write (TEXT CONST text) #off("b")#
+ Gibt 'text' ohne Trennblank aus ('put' mit Trennblank).
+
+#page#
+
+5.5.1.6 Kontrolle
+
+'online'
+ #on("b")#BOOL PROC online #off("b")#
+ Liefert TRUE, wenn die Task mit einem Terminal gekoppelt ist.
+
+
+'pause'
+ #on("b")#PROC pause (INT CONST time limit) #off("b")#
+ Wartet 'time limit' in Zehntel-Sekunden. Bei negativen Werten ist die Wirkung
+ nicht definiert. Die Wartezeit wird nicht nur durch das Erreichen der Grenze ab­
+ gebrochen, sondern auch durch die Eingabe eines beliebigen Zeichens.
+
+ #on("b")#PROC pause#off("b")#
+ Wartet bis zur Eingabe eines beliebigen Zeichens.
+
+
+#page#
+
+5.5.2 Zeitmessung
+
+'clock'
+ #on("b")#REAL PROC clock (INT CONST index) #off("b")#
+ 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 Realzeituhr 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' (vergl. 5- #topage("date")# ) (für den aktuellen Tag) und 'time of day' (Uhrzeit, vergl.
+ 5-#topage("time")#) 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' (vergl. 5- #topage("time")#) verwenden. Beispiel:
+
+____________________________________________________________________________
+
+ ........................... Beispiel ..........................
+ REAL CONST anfang :: clock (0);
+ berechnungen;
+ REAL CONST ende :: clock (0);
+ put ("benoetigte CPU-Zeit in Sek:");
+ put (time (ende - anfang))
+
+____________________________________________________________________________
+#page#
+'date'
+#goalpage("date")#
+ #on("b")#TEXT PROC date (REAL CONST time) #off("b")#
+ 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.87 *)
+
+____________________________________________________________________________
+
+
+ #on("b")#REAL PROC date (TEXT CONST datum) #off("b")#
+ 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.87")) (* 6.273539e10 *)
+
+____________________________________________________________________________
+
+
+ #on("b")#TEXT PROC date#off("b")#
+ Liefert das Tagesdatum. Wirkt wie 'date (clock (1))', ist jedoch erheblich schneller.
+
+
+
+'day'
+ #on("b")#REAL CONST day #off("b")#
+ Liefert die Anzahl der Sekunden eines Tages (86 400.0).
+
+
+
+'hour'
+ #on("b")#REAL CONST hour #off("b")#
+ Liefert die Anzahl der Sekunden einer Stunde (3600.0).
+
+
+
+'pause'
+ #on("b")#PROC pause (INT CONST time limit) #off("b")#
+ Wartet 'time limit' in Zehntel-Sekunden. Bei negativen Werten ist die Wirkung
+ nicht definiert. Die Wartezeit wird nicht nur durch das Erreichen der Grenze ab­
+ gebrochen, sondern auch durch die Eingabe eines beliebigen Zeichens.
+
+
+
+'time'
+#goalpage("time")#
+ #on("b")#TEXT PROC time (REAL CONST time) #off("b")#
+ Konvertierungsprozedur für die Zeiten der CPU-Zeituhr. Liefert die Zeiten in der
+ Form 'hh:mm:ss.s'. Vergl. dazu 'clock'.
+
+ #on("b")#TEXT PROC time (REAL CONST value, INT CONST laenge) #off("b")#
+ Konvertiert die Zeit in externe Darstellung. Für die 'laenge'-Werte ergibt sich:
+
+
+ laenge = 10 (* hh:mm:ss.s *)
+ laenge = 12 (* hhhh:mm:ss.s *)
+
+
+
+ #on("b")#REAL PROC time (TEXT CONST time) #off("b")#
+ Konvertierungsprozedur für Texte der CPU-Zeituhr in REAL-Werte.
+
+
+
+'time of day'
+ #on("b")#TEXT PROC time of day (REAL CONST time) #off("b")#
+ 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 *)
+
+____________________________________________________________________________
+
+
+ #on("b")#TEXT PROC time of day #off("b")#
+ Liefert die aktuelle Tageszeit. Entspricht
+
+____________________________________________________________________________
+
+ time of day (clock (1))
+
+____________________________________________________________________________
+#page#
+
+5.6 Scanner
+
+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
+
+
+ #ib#scan#ie#
+
+
+in den Scanner "hineingesteckt" werden. Mit der Prozedur
+
+
+ #ib#next symbol#ie#
+
+
+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" gemel­
+det. 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
+
+
+ #ib#continue scan#ie#
+
+
+verwandt. Sie setzt im letzten Scan-Zustand (z.B. Kommentar oder TEXT-Deno­
+ter) 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.
+
+____________________________________________________________________________
+
+ 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.
+
+____________________________________________________________________________
+
+#page#
+
+Scanner-Kommandos
+
+
+'continue scan'
+ #on("b")#PROC continue scan (TEXT CONST scan text) #off("b")#
+ 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' eingeleitet
+ werden!
+
+'next symbol'
+ #on("b")#PROC next symbol (TEXT VAR symbol, INT VAR type) #off("b")#
+ 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 abgeschnitten. Leerzeichen oder Kommentare
+ spielen in "tags" oder "numbers" keine Rolle. Zwischen Symbolen spielen Leer­
+ zeichen 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 innerhalb eines TEXT-Denoters
+ gefunden, so wird der schon analysierte Teil des Denoters und 'within text' gelie­
+ fert.
+
+ #on("b")#PROC next symbol (TEXT VAR symbol) #off("b")#
+ s.o. Es wird aber nur der Text des Symbols (ohne Typ) geliefert.
+
+ #on("b")#PROC next symbol (FILE VAR f, TEXT CONST symbol) #off("b")#
+ Arbeitet wie obige Prozeduren, jedoch auf einen FILE.
+
+ #on("b")#PROC next symbol (FILE VAR f, TEXT CONST symbol, INT VAR type)#off("b")#
+ Arbeitet wie obige Prozeduren, jedoch auf einen FILE.
+
+
+'scan'
+ #on("b")#PROC scan (TEXT CONST scan text) #off("b")#
+ 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.
+
+ #on("b")#PROC scan (FILE VAR f) #off("b")#
+ Wie obige Prozedur, jedoch auf einen FILE. Die zu scannende Zeile ist die näch­
+ ste Zeile im FILE 'f' ('scan' macht zuerst ein 'getline').
+
diff --git a/doc/programmer-manual/1.8.7/doc/programmierhandbuch.6 b/doc/programmer-manual/1.8.7/doc/programmierhandbuch.6
new file mode 100644
index 0000000..ce11f6f
--- /dev/null
+++ b/doc/programmer-manual/1.8.7/doc/programmierhandbuch.6
@@ -0,0 +1,1441 @@
+#pagenr("%",1)##setcount(1)##block##pageblock#
+#headeven#
+#center#EUMEL-Benutzerhandbuch
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#TEIL 6 : Das Archiv 'std.zusatz'
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+6 - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#6 - %
+#end#
+
+TEIL 6: Das Archiv 'std.zusatz'
+
+Das Archiv 'std.zusatz' enthält Pakete, die nur bei Bedarf insertiert werden sollen.
+Eine Einbindung in das EUMEL Grundsystem würde dieses ungebührlich unfangreich
+machen.
+
+Das Archiv enthält zusätzliche Software für:
+
+- mathematische Operationen : complex , longint , vector , matrix
+
+- Analyse : reporter , referencer
+
+- Taschenrechnerfunktion
+ zur Editor-Erweiterung : TeCal , TeCal Auskunft
+
+
+#page#
+
+6.1. Erweiterungen um
+ Mathematische Operationen
+
+
+6.1.1 COMPLEX
+
+Das Packet COMPLEX erweitert das System um den Datentyp COMPLEX (komplexe
+Zahlen) und Operationen auf komplexen Zahlen. Folgende Operationen stehen für
+COMPLEX zur Verfügung:
+
+- Einfache Operatoren : := , = , <> , + ,- , *
+
+- Eingabe/Ausgabe : get , put
+
+- Denotierungsprozedur : complex , complex i , complex one , com­
+ plex zero
+
+- Komponenten : real part , imag part
+
+- bes. Funktionen : ABS , CONJ , phi , dphi , sqrt
+
+#page#
+
+COMPLEX Operationen
+
+
+'TYPE COMPLEX'
+ Komplexe Zahl, bestehend aud Realteil 're' und Imaginärteil 'im'.
+
+
+':='
+ #on("b")#OP := (COMPLEX VAR a, COMPLEX CONST b) #off("b")#
+ Zuweisung.
+
+
+'='
+ #on("b")#BOOL OP = (COMPLEX CONST a, b) #off("b")#
+ Vergleich von 'a' und 'b' auf Gleichheit.
+
+
+'<>'
+ #on("b")#BOOL OP <> (COMPLEX CONST a, b) #off("b")#
+ Vergleich von 'a' und 'b' auf Ungleichheit.
+
+
+'+'
+ #on("b")#COMPLEX OP + (COMPLEX CONST a, b) #off("b")#
+ Summe von 'a' und 'b'.
+
+
+'-'
+ #on("b")#COMPLEX OP - (COMPLEX CONST a, b) #off("b")#
+ Differenz von 'a' und 'b'.
+
+
+'*'
+ #on("b")#COMPLEX OP * (COMPLEX CONST a, b) #off("b")#
+ Multiplikation von 'a' mit 'b'.
+
+
+'/'
+ #on("b")#COMPLEX OP / (COMPLEX CONST a, b) #off("b")#
+ Division von 'a' mit 'b'.
+
+#page#
+'get'
+ #on("b")#PROC get (COMPLEX VAR a) #off("b")#
+ Einlesen eines komplexen Wertes vom Bildschirm in der Form zweier REAL-De­
+ noter. Die Eingabe kann editiert werden.
+
+
+'put'
+ #on("b")#PROC put (COMPLEX CONST a) #off("b")#
+ Ausgabe eines komplexen Wertes auf dem Bildschirm in Form zweier REAL-
+ Werte. Hinter jedem REAL-Wert wird ein Leerzeichen angefügt.
+
+
+'complex'
+ #on("b")#COMPLEX PROC complex (REAL CONST re, im) #off("b")#
+ Denotierungsprozedur. Angabe in kartesischen Koordinaten.
+
+
+'complex i'
+ #on("b")#COMPLEX PROC complex i #off("b")#
+ Denotierungsprozedur für den komplexen Wert '0.0 + i 1.0'.
+
+
+'complex one'
+ #on("b")#COMPLEX PROC complex one #off("b")#
+ Denotierungsprozedur für den komplexen Wert '1.0 + i 0.0'.
+
+
+'complex zero'
+ #on("b")#COMPLEX PROC complex zero #off("b")#
+ Denotierungsprozedur für den komplexen Wert '0.0 + i 0.0'.
+
+
+'imag part'
+ #on("b")#REAL PROC imag part (COMPLEX CONST number) #off("b")#
+ Liefert den Imaginärteil des komplexen Wertes 'number'.
+
+
+'real part'
+ #on("b")#REAL PROC real part (COMPLEX CONST number) #off("b")#
+ Liefert den Real-Teil des komplexen Wertes 'number'.
+
+
+'ABS'
+ #on("b")#REAL OP ABS (COMPLEX CONST x) #off("b")#
+ REAL-Betrag von 'x'.
+
+
+'CONJ'
+ #on("b")#COMPLEX OP CONJ (COMPLEX CONST number) #off("b")#
+ Liefert den konjugiert komplexen Wert von 'number'.
+
+
+'dphi'
+ #on("b")#REAL PROC dphi (COMPLEX CONST x) #off("b")#
+ Winkel von 'x' (Polardarstellung).
+
+
+'phi'
+ #on("b")#REAL PROC phi (COMPLEX CONST x) #off("b")#
+ Winkel von 'x' (Polardarstellung) in Radiant.
+
+
+'sqrt'
+ #on("b")#COMPLEX PROC sqrt (COMPLEX CONST x) #off("b")#
+ Wurzelfunktion für komplexe Werte.
+
+#page#
+
+6.1.2 LONGINT
+
+LONGINT ist ein Datentyp, für den (fast) alle Prozeduren und Operatoren des Daten­
+typs 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:
+
+- Operatoren : := , = , <> , < , <= ,> , >= , + , - , * ,
+ ** ,
+ ABS , DECR , DIV , INCR , MOD , SIGN
+
+- Eingabe/Ausgabe : get , put
+
+
+- Math. Prozeduren : abs , int , longint , max , max logint , min ,
+ random , sign , text , zero
+
+
+
+LONGINT-Operationen
+
+
+'TYPE LONGINT'
+ Datentyp
+
+
+':='
+ #on("b")#OP := (LONGINT VAR links, LONGINT CONST rechts) : #off("b")#
+ Zuweisungsoperator
+
+
+'= '
+ #on("b")#BOOL OP = (LONGINT CONST links, rechts) #off("b")#
+ Vergleichen zweier LONGINTs auf Gleichheit.
+
+
+'<>'
+ #on("b")#BOOL OP <> (LONGINT CONST links, rechts) #off("b")#
+ Vergleichen zweier LONGINTs auf Ungleichheit.
+
+
+'< '
+ #on("b")#BOOL OP < (LONGINT CONST links, rechts) #off("b")#
+ Vergleichen zweier LONGINTs auf kleiner.
+
+
+'<='
+ #on("b")#BOOL OP <= (LONGINT CONST links, rechts) #off("b")#
+ Vergleichen zweier LONGINTs auf kleiner gleich.
+
+
+'> '
+ #on("b")#BOOL OP > (LONGINT CONST links, rechts) #off("b")#
+ Vergleichen zweier LONGINTs auf größer.
+
+
+'>='
+ #on("b")#BOOL OP >= (LONGINT CONST links, rechts) #off("b")#
+ Vergleichen zweier LONGINTs auf größer gleich.
+
+
+'+ '
+ #on("b")#LONGINT OP + (LONGINT CONST argument) #off("b")#
+ Monadischer Operator. Ohne Wirkung.
+
+ #on("b")#LONGINT OP + (LONGINT CONST links, rechts) #off("b")#
+ Addition zweier LONGINTs.
+
+
+'- '
+ #on("b")#LONGINT OP - (LONGINT CONST argument) #off("b")#
+ Vorzeichenumkehrung.
+
+ #on("b")#LONGINT OP - (LONGINT CONST links, rechts) #off("b")#
+ Subtraktion zweier LONGINTs.
+
+
+'* '
+ #on("b")#LONGINT OP * (LONGINT CONST links, rechts) #off("b")#
+ Multiplikation von zwei LONGINTs.
+
+
+'**'
+ #on("b")#LONGINT OP ** (LONGINT CONST argument, exponent) #off("b")#
+ Exponentiation zweier LONGINTs mit positivem Exponenten.
+
+ FEHLER :
+ LONGINT OP ** : negative exponent
+ Der 'exponent' muß >= 0 sein.
+ 0 ** 0 is not defined
+ 'argument' und 'exponent' dürfen nicht gleich 0 sein.
+
+
+ #on("b")#LONGINT OP ** (LONGINT CONST argument, INT CONST exponent)#off("b")#
+ Exponentiation eines LONGINT mit positiven INT Exponenten.
+
+ FEHLER :
+ LONGINT OP ** : negative exponent
+ Der 'exponent' muß >= 0 sein.
+ 0 ** 0 is not defined
+ 'argument' und 'exponent' dürfen nicht gleich 0 sein.
+
+'ABS'
+ #on("b")#LONGINT OP ABS (LONGINT CONST argument) #off("b")#
+ Absolutbetrag eines LONGINT.
+
+
+'DECR'
+ #on("b")#OP DECR (LONGINT VAR resultat, LONGINT CONST ab) #off("b")#
+ resultat := resultat - ab
+
+
+'DIV'
+ #on("b")#LONGINT OP DIV (LONGINT CONST links, rechts) #off("b")#
+ Division zweier LONGINTs.
+
+ FEHLER :
+ Division durch 0
+ 'rechts' muß <> 0 sein.
+
+
+'INCR'
+ #on("b")#LONGINT OP INCR (LONGINT VAR resultat, LONGINT CONST dazu)#off("b")#
+ resultat := resultat + dazu
+
+
+
+'MOD'
+ #on("b")#LONGINT OP MOD (LONGINT CONST links, rechts) #off("b")#
+ Modulo-Funktion für LONGINTs. Der Rest einer LONGINT-Division wird ermit­
+ telt.
+
+ FEHLER :
+ text (links) + 'MOD 0'
+ 'rechts' muß ungleich null sein.
+
+
+'SIGN'
+ #on("b")#INT OP SIGN (LONGINT CONST longint) #off("b")#
+ Feststellen des Vorzeichens von 'longint'. Liefert:
+
+
+ 0 wenn 'longint' = 0,
+ 1 wenn 'longint' > 0,
+ -1 wenn 'longint' < 0.
+
+
+#page#
+'get'
+ #on("b")#PROC get (LONGINT VAR zahl) #off("b")#
+ Eingabe eines LONGINTs vom Terminal.
+
+ #on("b")#PROC get (FILE VAR file, LONGINT VAR zahl) #off("b")#
+ Einlesen von 'zahl' aus der sequentiellen Datei 'file'. Die Datei muß mit 'input'
+ assoziiert sein (vergl. 'sequential file').
+
+ FEHLER :
+ Datei zu
+ Leseversuch nach Daateiende
+ Leseversuch auf output-FILE
+
+
+'put'
+ #on("b")#PROC put (LONGINT CONST longint) #off("b")#
+ 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 fortgesetzt.
+
+ #on("b")#PROC put (FILE VAR file, LONGINT CONST zahl) #off("b")#
+ Ausgabe von 'zahl' in die sequentielle Datei 'file'. 'file' muß mit 'output' assoziiert
+ sein.
+
+ FEHLER :
+ Datei zu
+ Schreibversuch auf input-FILE
+#page#
+'abs'
+ #on("b")#LONGINT PROC abs (LONGINT CONST argument) #off("b")#
+ Absolutbetrag eines LONGINT.
+
+
+'int'
+ #on("b")#INT PROC int (LONGINT CONST longint) #off("b")#
+ Konvertierung von LONGINT nach INT.
+
+ FEHLER :
+ integer overflow
+ 'longint' ist größer als 'maxint'.
+
+
+'longint'
+ #on("b")#LONGINT PROC longint (INT CONST int) #off("b")#
+ Konvertierung von 'int' nach LONGINT.
+
+ #on("b")#LONGINT PROC longint (TEXT CONST text) #off("b")#
+ Konvertierung von 'text' nach LONGINT.
+
+
+'max'
+ #on("b")#LONGINT PROC max (LONGINT CONST links, rechts) #off("b")#
+ Liefert das Maximum zweier LONGINTs.
+
+
+'maxlongint'
+ #on("b")#LONGINT PROC max longint #off("b")#
+ Liefert größten LONGINT Wert.
+
+
+'min'
+ #on("b")#LONGINT PROC min (LONGINT CONST links, rechts) #off("b")#
+ Liefert das Minimum zweier LONGINTs.
+
+
+'random'
+ #on("b")#LONGINT PROC random (LONGINT CONST lower bound, upper bound)#off("b")#
+ Pseudo-Zufallszahlen-Generator im Intervall 'lower bound' und 'upper bound'
+ einschließlich. Es handelt sich hier um den 'LONGINT Random Generator'.
+
+
+'sign'
+ #on("b")#INT PROC sign (LONGINT CONST longint) #off("b")#
+ Feststellen des Vorzeichens von 'longint'. Liefert:
+
+
+ 0 wenn 'longint' = 0,
+ 1 wenn 'longint' > 0,
+ -1 wenn 'longint' < 0.
+
+
+
+'text'
+ #on("b")#TEXT PROC text (LONGINT CONST longint) #off("b")#
+ Konvertierung von 'longint' nach TEXT.
+
+ #on("b")#TEXT PROC text (LONGINT CONST longint, INT CONST laenge) #off("b")#
+ 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' eingetra­
+ gen. 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)) > laenge
+
+
+ wird ein Text mit der Länge 'laenge' geliefert, der mit '*'-Zeichen gefüllt ist.
+
+
+'zero'
+ #on("b")#LONGINT PROC zero #off("b")#
+ Liefert LONGINT Wert Null.
+
+
+#page#
+
+6.1.3 VECTOR
+
+Der Datentyp VECTOR erlaubt Operationen auf Vektoren aus Elementen vom Typ
+REAL. Im Gegensatz zur Struktur 'ROW m REAL' muß die Anzahl der Elemente nicht
+zur Übersetzungszeit deklariert werden, sondern kann zur Laufzeit festgelegt werden.
+Somit kann eine zur Übersetzungszeit unbekannte Anzahl von REALs bearbeitet
+werden, wobei nur soviel Speicherplatz wie nötig verwendet wird. Die maximale Größe
+eines VECTOR beträgt 4000 Elemente.
+
+Der in den Operationen ':=', 'idn' und 'vector' benutzte Datentyp INITVECTOR wird
+nur intern gehalten. Er dient der Speicherplatzersparnis bei der Initialisierung.
+
+
+- Operatoren : := , = , <> , + , - , * , /
+ LENGTH , SUB
+
+- Eingabe/Ausgabe : get , put
+
+- Besondere Vector- : length , nilvector , norm , vector , replace
+ Operationen
+
+#page#
+':='
+ #on("b")#OP := (VECTOR VAR ziel, VECTOR CONST quelle) #off("b")#
+ 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 Zuweisung mehr oder weniger Ele­
+ mente als 'quelle' besaß. Beispiel:
+
+
+ VECTOR VAR y :: vector (10, 1.0),
+ z :: vector (15, 2.0);
+ ...
+ y := z; (* length (y) liefert nun 15 ! *)
+
+
+ #on("b")#OP := (VECTOR VAR ziel, INITVECTOR CONST quelle) #off("b")#
+ 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 Speicherplatz verbraucht.
+
+
+'='
+ #on("b")#BOOL OP = (VECTOR CONST a, b) #off("b")#
+ 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 *)
+
+
+'<>'
+ #on("b")#BOOL OP <> (VECTOR CONST a, b) #off("b")#
+ Vergleich zweier Vektoren auf Ungleichheit (NOT (a = b)).
+
+
+'+'
+ #on("b")#VECTOR OP + (VECTOR CONST a) #off("b")#
+ Monadisches '+' für VECTOR. Keine Auswirkung.
+
+ #on("b")#VECTOR OP + (VECTOR CONST a, b) #off("b")#
+ Elementweise Addition der Vektoren 'a' und 'b'. Beispiel:
+
+
+ VECTOR VAR x, (* 'x' hat undefinierte Länge *)
+ a :: vector (10, 1.0),
+ b :: vector (10, 2.0);
+ ...
+ x := a + b; (* 'x' hat nun 10 Elemente mit Werten'3.0'
+ *)
+
+ FEHLER :
+ VECTOR OP + : LENGTH a <> LENGTH b
+ 'a' und 'b' haben nicht die gleiche Anzahl von Elementen.
+
+
+'-'
+ #on("b")#VECTOR OP - (VECTOR CONST a) #off("b")#
+ Monadisches '-'.
+
+ #on("b")#VECTOR OP - (VECTOR CONST a, b) #off("b")#
+ Elementweise Subtraktion der Vektoren 'a' und 'b'.
+
+ FEHLER :
+ VECTOR OP - : LENGTH a <> LENGTH b
+ 'a' und 'b' haben nicht die gleiche Anzahl von Elementen.
+
+'*'
+ #on("b")#REAL OP * (VECTOR CONST a, b) #off("b")#
+ Skalarprodukt zweier Vektoren. Liefert die Summe der elementweisen Multiplika­
+ tion der Vektoren 'a' und 'b'. Beachte eventuelle Rundungsfehler! Beispiel:
+
+
+ REAL VAR a;
+ VECTOR VAR b :: vector (10, 2.0),
+ c :: vector (10, 2.0);
+ ...
+ a := b * c; (* 40.0 *)
+
+ FEHLER :
+ REAL OP * : LENGTH a <> LENGTH b
+ 'a' und 'b' haben nicht die gleiche Anzahl von Elementen.
+
+ #on("b")#VECTOR OP * (VECTOR CONST a, REAL CONST s) #off("b")#
+ Multiplikation des Vektors 'a' mit dem Skalar 's'.
+
+ #on("b")#VECTOR OP * (REAL CONST s, VECTOR CONST a) #off("b")#
+ Multiplikation des Skalars 's' mit dem Vektor 'a'.
+
+
+'/'
+ #on("b")#VECTOR OP / (VECTOR CONST a, REAL CONST s) #off("b")#
+ 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' *)
+
+
+
+'LENGTH'
+ #on("b")#INT OP LENGTH (VECTOR CONST a) #off("b")#
+ Liefert die Anzahl der Elemente von 'a'.
+
+
+'SUB'
+ #on("b")#REAL OP SUB (VECTOR CONST v, INT CONST i) #off("b")#
+ Liefert das 'i'-te Element von 'v'.
+
+ FEHLER :
+ OP SUB : subscript overflow
+ Der Index 'i' liegt außerhalb des Vektors (i > LENGTH v).
+ OP SUB : subscript underflow
+ Der Index 'i' liegt außerhalb des Vektors (i < 1).
+
+#page#
+'get'
+ #on("b")#PROC get (VECTOR VAR a, INT CONST l) #off("b")#
+ Einlesen der Elemente von 'a' vom Terminal, wobei 'l' die Anzahl der Elemente
+ angibt.
+
+ FEHLER :
+ PROC get : size <= 0
+ Die angeforderte Elementanzahl 'l' muß > 0 sein.
+
+
+'put'
+ #on("b")#PROC put (VECTOR CONST v) #off("b")#
+ Ausgabe der Werte der Elemente von 'v' auf dem Terminal.
+
+
+#page#
+'length'
+ #on("b")#INT PROC length (VECTOR CONST a) #off("b")#
+ 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 *)
+
+
+
+'nilvector'
+ #on("b")#INITVECTOR PROC nilvector #off("b")#
+ Erzeugen eines Vektors mit einem Element mit dem Wert '0.0'.
+
+
+'norm'
+ #on("b")#REAL PROC norm (VECTOR CONST v) #off("b")#
+ Euklidische Norm (Wurzel aus der Summe der Quadrate der Elemente).
+
+
+
+'replace'
+ #on("b")#PROC replace (VECTOR VAR v, INT CONST i, REAL CONST r)#off("b")#
+ 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' *)
+
+ FEHLER :
+ PROC replace : subscript overflow
+ Der Index 'i' liegt außerhalb des Vektors (i > LENGTH v).
+ PROC replace : subscript underflow
+ Der Index 'i' liegt außerhalb des Vektors (i < 1).
+
+
+'vector'
+ #on("b")#INITVECTOR PROC vector (INT CONST l) #off("b")#
+ 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.
+
+ FEHLER :
+ PROC vector : size <= 0
+ Die angeforderte Elementanzahl 'l' muß > 0 sein.
+
+ #on("b")#INITVECTOR PROC vector (INT CONST l, REAL CONST value)#off("b")#
+ 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' *)
+
+ FEHLER :
+ PROC vector : size <= 0
+ Die angeforderte Elementanzahl 'l' muß > 0 sein.
+
+#page#
+
+6.1.4 MATRIX
+
+Der Datentyp MATRIX erlaubt Operationen auf m x n Matrizen. Im Gegensatz zur
+Struktur 'ROW m ROW n REAL' muß die Anzahl der Elemente nicht zur Überset­
+zungszeit deklariert werden, sondern kann zur Laufzeit festgelegt werden. Somit kann
+eine zur Übersetzungszeit unbekannte Anzahl von REALs bearbeitet werden, wobei
+nur soviel Speicherplatz wie nötig verwendet wird. Die maximale Größe einer MATRIX
+beträgt 4000 Elemente.
+
+Der in den Operationen ':=', 'idn' und 'matrix' benutzte Datentyp INITMATRIX wird
+nur intern gehalten. Er dient der Speicherplatzersparnis bei der Initialisierung.
+
+
+- Operatoren : := , = , <> , + , - , *
+ COLUMNS , DET , INV , ROWS , TRANSP ,
+
+- Eingabe/Ausgabe : get , put
+
+- Besondere Matrix- : column , idn , matrix , row , sub
+ Operationen transp ,
+ replace column , replace element ,
+ replace row
+
+
+
+#page#
+':='
+ #on("b")#OP := (MATRIX VAR l, MATRIX CONST r) #off("b")#
+ 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 *)
+
+
+ #on("b")#OP := (MATRIX VAR l, INITMATRIX CONST r) #off("b")#
+ 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 Speicherplatz verbraucht.
+
+'='
+ #on("b")#BOOL OP = (MATRIX CONST l, r) #off("b")#
+ 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 *)
+
+
+
+'<>'
+ #on("b")#BOOL OP <> (MATRIX CONST l, r) #off("b")#
+ Vergleich der Matrizen 'l' und 'r' auf Ungleichheit.
+
+
+'+'
+ #on("b")#MATRIX OP + (MATRIX CONST m) #off("b")#
+ Monadisches '+'. Keine Auswirkungen.
+
+ #on("b")#MATRIX OP + (MATRIX CONST l, r) #off("b")#
+ 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' *)
+
+
+ FEHLER:
+ 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.
+
+
+'-'
+ #on("b")#MATRIX OP - (MATRIX CONST m) #off("b")#
+ Monadisches Minus. Beispiel:
+
+
+ MATRIX VAR a :: matrix (3, 4, 10.0)
+ a := - a; (* Alle Elemente haben den Wert '- 10.0' *)
+
+
+ #on("b")#MATRIX OP - (MATRIX CONST l, r) #off("b")#
+ Subtraktion zweier Matrizen. Die Anzahl der Reihen und Spalten muß gleich sein.
+
+ FEHLER:
+ 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.
+
+'*'
+ #on("b")#MATRIX OP * (REAL CONST r, MATRIX CONST m) #off("b")#
+ 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' *)
+
+
+ #on("b")#MATRIX OP * (MATRIX CONST m, REAL CONST r) #off("b")#
+ Multiplikation einer Matrix 'm' mit einem Skalar 'r'.
+
+ #on("b")#MATRIX OP * (MATRIX CONST l, r) #off("b")#
+ 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' *)
+
+
+ FEHLER :
+ MATRIX OP * : COLUMNS l <> ROWS r
+ Die Anzahl der Spalten von 'l' muß mit der Anzahl der Zeilen von 'r'
+ übereinstimmen.
+
+ #on("b")#VECTOR OP * (VECTOR CONST v, MATRIX CONST m) #off("b")#
+ Multiplikation des Vektors 'v' mit der Matrix 'm'.
+
+ FEHLER :
+ VECTOR OP * : LENGTH v <> ROWS m
+ Die Anzahl der Elemente von 'v' stimmt nicht mit den Anzahl der Zeilen
+ von 'm' überein.
+
+ #on("b")#VECTOR OP * (MATRIX CONST m, VECTOR CONST v) #off("b")#
+ Multiplikation der Matrix 'm' mit dem Vektor 'v'.
+
+ FEHLER :
+ VECTOR OP * : COLUMNS m <> LENGTH v
+ Die Anzahl der Spalten von 'm' stimmt nicht mit der Anzahl der Ele­
+ menten von 'v' überein.
+
+
+'COLUMNS'
+ #on("b")#INT OP COLUMNS (MATRIX CONST m) #off("b")#
+ 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'
+ #on("b")#REAL OP DET (MATRIX CONST m) #off("b")#
+ Es wird der Wert der Determinanten von 'm' geliefert.
+
+ FEHLER :
+ OP DET : no square matrix
+ Die Matrix ist nicht quadratisch, d.h. ROWS m <> COLUMNS m
+
+
+'INV'
+ #on("b")#MATRIX OP INV (MATRIX CONST m) #off("b")#
+ Liefert als Ergebnis die Inverse von 'm' (Achtung: starke Rundungsfehler möglich).
+
+ FEHLER:
+ 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.
+
+
+'ROWS'
+ #on("b")#INT OP ROWS (MATRIX CONST m) #off("b")#
+ 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 *)
+
+
+
+'TRANSP'
+ #on("b")#MATRIX OP TRANSP (MATRIX CONST m) #off("b")#
+ Liefert als Ergebnis die transponierte Matrix 'm'.
+
+#page#
+'get'
+ #on("b")#PROC get (MATRIX VAR m, INT CONST rows, columns) #off("b")#
+ Einlesen von Werten für die Matrix 'm' vom Terminal mit 'rows'-Zeilen und
+ 'columns'-Spalten.
+
+
+'put'
+ #on("b")#PROC put (MATRIX CONST m) #off("b")#
+ Ausgabe der Werte einer Matrix auf dem Terminal.
+#page#
+'column'
+ #on("b")#VECTOR PROC column (MATRIX CONST m, INT CONST i) #off("b")#
+ 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' *)
+
+ FEHLER:
+ 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).
+
+'idn'
+ #on("b")#INITMATRIX PROC idn (INT CONST size) #off("b")#
+ 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 Diagonalele­
+ mente, die den Wert '1.0' haben.*)
+
+ FEHLER :
+ PROC idn : size <= 0
+ Die angeforderte 'size' Anzahl Spalten oder Zeilen muß > 0 sein.
+
+
+'matrix'
+ #on("b")#INITMATRIX PROC matrix (INT CONST rows, columns) #off("b")#
+ 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);
+
+ FEHLER:
+ PROC matrix : rows <= 0
+ Die angeforderte Zeilenanzahl 'rows' muß > 0 sein.
+ PROC matrix : columns <= 0
+ Die angeforderte Spaltenanzahl 'columns' muß > 0 sein.
+
+ #on("b")#INITMATRIX PROC matrix (INT CONST rows, columns, REAL CONST value)#off("b")#
+ Erzeugen eines Datenobjekts vom Datentyp MATRIX mit 'rows' Zeilen und 'co­
+ lumns' Spalten. Alle Elemente der erzeugten MATRIX werden mit dem Wert
+ 'value' initialisiert. Beispiel:
+
+
+ MATRIX CONST :: matrix (3, 3, 3.14);
+
+ FEHLER:
+ PROC matrix : rows <= 0
+ Die angeforderte Zeilenanzahl 'rows' muß > 0 sein.
+ PROC matrix : columns <= 0
+ Die angeforderte Spaltenanzahl 'columns' muß > 0 sein.
+
+
+'row'
+ #on("b")#VECTOR PROC row (MATRIX CONST m, INT CONST i) #off("b")#
+ Die 'i'-te Reihe von 'm' wird als VECTOR mit 'COLUMNS m' Elementen gelie­
+ fert. Beispiel:
+
+
+ MATRIX CONST a :: matrix (3, 4);
+ VECTOR VAR b :: row (a, 1);
+ (* 'b' hat vier Elemente mit den Werten '0.0'*)
+
+ FEHLER:
+ 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).
+
+
+'sub'
+ #on("b")#REAL PROC sub (MATRIX CONST m, INT CONST row, column) #off("b")#
+ 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));
+
+ FEHLER:
+ 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'
+ #on("b")#PROC transp (MATRIX VAR m) #off("b")#
+ Transponieren der Matrix 'm', wobei kaum zusätzlicher Speicherplatz benötigt
+ wird.
+
+#page#
+'replace column'
+ #on("b")#PROC replace column (MATRIX VAR m, INT CONST column index, VECTOR
+ CONST column value) #off("b")#
+ 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 *)
+
+ FEHLER:
+ 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'
+ #on("b")#PROC replace element (MATRIX VAR m , INT CONST row, column,
+ REAL CONST value) #off("b")#
+ 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);
+
+ FEHLER:
+ 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'
+ #on("b")#PROC replace row (MATRIX VAR m, INT CONST rowindex,
+ VECTOR CONST rowvalue) #off("b")#
+ 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 *)
+
+ FEHLER:
+ 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).
+
+6.2 Programmanalyse
+
+Das Packet 'reporter' ermöglicht:
+
+a) Ablaufinformationen ("trace");
+b) #ib#Häufigkeitszählung#ie# ("frequency count");
+c) Programmunterbrechung bei Nichterfüllung einer Bedingung ("#ib#assertion#ie#").
+
+
+'Installation'
+Das Programm befindet sich in der Datei 'reporter' und kann wie üblich insertiert
+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' ver­
+wechselt werden können. Beispiel:
+
+
+ check off; insert ("reporter"); check on
+
+
+Mit dem Kommando
+
+
+ #ib#generate reports#ie# ("testdatei")
+
+
+werden die oben erwähnten Prozeduraufrufe ('#ib#report#ie#') in das zu testende Programm,
+welches in der Datei 'testdatei' steht, geschrieben. Die Prozeduraufrufe 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 Prozedurauf­
+rufe):
+
+
+ ...
+ PROC beispiel (INT CONST mist):
+ \#\#report ("PROC beispiel");\#\#
+ ...
+
+
+
+'Automatische Ablaufinformation'
+Ist ein Programm mit 'generate reports' mit 'report'-Aufrufen versehen worden, kann
+es wie gewohnt übersetzt werden. Wird das Programm vom ELAN-Compiler kor­
+rekt ü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' eingerichtet.
+
+Mit Hilfe dieser Datei kann der Programmablauf verfolgt werden. Es ist damit auch
+möglich festzustellen, wo eine "Endlos-Rekursion" auftritt. Die Ablaufinformationen
+bestehen nur aus den Namen der angetroffenen Prozeduren und Refinements. Trotz­
+dem können die Anzahl der Informationen sehr umfangreich werden. Deshalb gibt es
+die Möglichkeit, die Erzeugung der Ablaufinformationen ab- bzw. wieder anzuschal­
+ten. Dazu gibt es die Möglichkeit, in das zu testende Programm die Prozeduren
+
+
+ #ib#report on#ie#
+ #ib#report off#ie#
+
+
+einzufügen und das zu testende Programm mit diesen Prozeduraufrufen (erneut) zu
+übersetzen.
+
+
+'Benutzereigene Ablaufinformation'
+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 zwei­
+ten 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 einge­
+ fuegt *)
+ ...
+
+
+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
+
+
+ #ib#generate counts#ie# ("zu testende datei")
+
+
+werden die vermerkten Häufigkeiten in das zu testende Programm direkt eingefügt.
+Die Häufigkeiten werden wie oben beschrieben gekennzeichnet, so daß sie mit 'elimi­
+nate reports' entfernt werden können.
+
+
+'Assertions'
+Zusätzlich zu den oben erwähnten Möglichkeiten bietet 'reporter' noch die Prozedur
+
+
+ #ib#assert#ie#
+
+
+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 #ib#assert#ie# (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'
+ #on("b")#PROC count on #off("b")#
+ Schaltet die Häufigkeitszählung ein.
+
+'count off'
+ #on("b")#PROC count off #off("b")#
+ Schaltet die Häufigkeitszählung aus.
+
+'eliminate reports'
+ #on("b")#PROC eliminate reports (TEXT CONST datei) #off("b")#
+ Entfernt gekennzeichnete 'report'-Aufrufe aus der Datei 'datei'.
+
+'generate reports'
+ #on("b")#PROC generate reports (TEXT CONST datei) #off("b")#
+ Fügt 'report'-Aufrufe in die Datei 'datei' ein und kennzeichnet diese mit '\#\#'.
+
+'report on'
+ #on("b")#PROC report on #off("b")#
+ Schaltet die Ablaufinformationen in die Datei 'TRACE' ein.
+
+'report off'
+ #on("b")#PROC report off #off("b")#
+ Schaltet die Ablaufinformationen wieder aus.
+
+'generate counts'
+ #on("b")#PROC generate counts (TEXT CONST datei) #off("b")#
+ Bringt die Häufigkeitszählung (wie oft eine Prozedur oder Refinement durchlaufen
+ wurde) in die Programmdatei 'datei'. Mit 'eliminate reports' werden diese wieder
+ automatisch entfernt.
+
+'assert'
+ #on("b")#PROC assert (TEXT CONST message, BOOL CONST value) #off("b")#
+ Schreibt 'message' und den Wert von 'value' in die TRACE-Datei. Ist 'value'
+ FALSE, wird angefragt, ob das Programm fortgesetzt werden soll.
+#page#
+
+Referencer
+
+
+'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 #ib# Referenzliste#ie#.
+
+#ub#Achtung#ue#: 'referencer' arbeitet ausschließlich mit Namen und verarbeitet nur wenige
+syntaktische Konstrukte. Darum ist es nur erlaubt, ein PACKET auf einmal von 'refe­
+rencer' verarbeiten zu lassen. Verarbeitet man mehrere PACKETs auf einmal, kann es
+geschehen, daß gleichnamige Objekte in unterschiedlichen 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 umfan­
+greicheren Programmen (bei "Mini"-Programmen kann man dies sofort sehen).
+
+Bei der Erstellung der Referenzliste nimmt das Programm 'referencer' gleichzeitig
+einige Überprüfungen vor, die helfen können, ein Programm zu verbessern:
+
+1. Warnung bei mehrzeiligen Kommentaren.
+
+2. Überdeckungsfehler. Wird ein Objekt global (auf PACKET-Ebene) und nochmals
+ 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 Refinement 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 Zeilennum­
+ mern in der Referenzliste besitzen, sind verdächtig (Ausnahmen: importierte
+ Prozeduren, LET-Objekte u.a.m.).
+
+
+
+referencer - Kommandos
+
+
+'referencer'
+ #on("b")#PROC referencer (TEXT CONST check file, dump file) #off("b")#
+ Überprüft 'check file'. In 'dump file' steht nach Abschluß die Referenzliste.
+
+#page#
+
+6.3 Rechnen im Editor
+
+Das Programm TeCal ermöglicht einfache Rechnungen (ähnlich wie mit einem Ta­
+schenrechner) 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. Zur Benutzung
+müssen 'TeCal' und 'TeCal Auskunft' insertiert werden.
+
+TeCal wird aus dem Editor heraus durch 'ESC t' oder durch das Editor-Kommando
+
+
+ tecal
+
+
+aktiviert. Dadurch wird in der untersten Zeile des Bildschirms eine Informationszeile
+aufgebaut, in der die (Zwischen-) Ergebnisse einer Rechnung zur Kontrolle fest­
+gehalten werden.
+
+
+
+Arbeitsweise
+
+
+Wenn TeCal insertiert ist, kann die Taschenrechnerfunktion jederzeit durch <ESC> <t>
+aufgerufen werden. Aus der editierten Datei werden Werte mit <ESC> <L> gelesen,
+durch <ESC> <+> (bzw. -,*,/) verknüpft und mit <ESC> <S> an die aktuelle Cursor­
+position geschrieben werden.
+
+Der von TeCal errechnete Wert wird durch <ESC> <S> derart ausgegeben, daß an der
+Stelle an der der Cursor steht die letzte Stelle vor dem Dezimalpunkt geschrieben
+wird.
+
+Die Eingabe von Klammern geschieht durch <ESC> <(> <ESC> <)>.
+
+Durch die Hilfsfunktion <ESC> <?> lassen sich die TeCal Funktionen auflisten.
+
+Der Prozentoperator <ESC> <%> erlaubt einfache Rechnungen der Form: 'zahl' <ESC> <+>
+<ESC> <%> <ESC> <=> .
+
+Derartige Folgen können natürlich mit der bekannten Editor-Lernfunktion auch ge­
+lernt werden, so daß sich z.B. die Mehrwertsteuerberechnung auf wenige Tasten
+reduziert.
+
+Spalten können summiert werden, indem auf der #on("u")#untersten#off("u")# Zahl einer Spalte <ESC> <V>
+eingegeben wird. Daraufhin werden alle darüberliegende Zahlen addiert, bis ein
+Zeichen auftritt, das nicht in einer Zahl auftritt (Leerzeichen stören nicht!).
+
+____________________________________________________________________________
+ ............
+ 55.00
+ 66.99
+ 123.45
+
+ 99.99
+
+ 9876.54
+ ...........
+
+ Anzeige: 0.00 14.00% Memory: 0.00
+
+____________________________________________________________________________
+
+
+TeCal Prozeduren
+
+
+'evaluate'
+ #on("b")#evaluate (TEXT CONST zeile, INT CONST von) #off("b")#
+ Ausdruck 'zeile' ab der Stelle 'von' berechnen.
+
+ #on("b")#evaluate (TEXT CONST zeile) #off("b")#
+ Ausdruck 'zeile' ab Stelle 1 berechnen.
+
+
+'kommastellen'
+ #on("b")#kommastellen (INT CONST stellen) #off("b")#
+ Berechnungen auf 'stellen' Zahlen hinter dem Komma einstellen.
+
+
+'merke'
+ #on("b")#PROC merke (INT CONST zahl)#off("b")#
+ Integer 'zahl' im Merkregister abspeichern.
+
+ #on("b")#PROC merke (REAL CONST zahl)#off("b")#
+ Real 'zahl' im Merkregister abspeichern.
+
+'prozentsatz'
+ #on("b")#PROC prozentsatz (INT CONST zahl) #off("b")#
+ Prozentsatz von 'zahl' Prozent einstellen. Der Wert wird automatisch konvertiert.
+
+ #on("b")#PROC prozentsatz (REAL CONST zahl) #off("b")#
+ Prozentsatz von 'zahl' Prozent einstellen.
+
+
+'tecal'
+ #on("b")#PROC tecal (FILE VAR f) #off("b")#
+ Datei 'f', die mit 'sequential file' assoziiert ist, mit TeCal editieren.
+
+ #on("b")#PROC tecal (TEXT VAR datei) #off("b")#
+ 'datei' mit TeCal editieren.
+
+ #on("b")#PROC tecal #off("b")#
+ Zuletzt editierte Datei mit TeCal editieren.
+
+
+'tecalauskunft'
+ #on("b")#PROC tecalauskunft #off("b")#
+ Auskunft zeigen.
+
+ #on("b")#PROC tecalauskunft (TEXT CONST zeichen) #off("b")#
+ Auskunft zu 'zeichen' zeigen.
+
diff --git a/doc/programmer-manual/1.8.7/doc/programmierhandbuch.index b/doc/programmer-manual/1.8.7/doc/programmierhandbuch.index
new file mode 100644
index 0000000..f3f4ede
--- /dev/null
+++ b/doc/programmer-manual/1.8.7/doc/programmierhandbuch.index
@@ -0,0 +1,449 @@
+#pagenr("%",1)##block##pageblock#
+#headandbottom("1","EUMEL-Benutzerhandbuch","INDEX","Index")#
+#headeven#
+#center#EUMEL-Benutzerhandbuch
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#INDEX
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+Index - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#Index - %
+#end#
+#lpos(0.2)##lpos(6.2)#
+
+INDEX
+
+#table#
+* 5-11, 5-18, 5-32, 6-19, 6-27, 6-4, 6-9
+** 5-11, 5-19, 5-60, 6-10
++ 4-20, 5-11, 5-18, 5-32, 5-54, 6-18, 6-26, 6-3, 6-9
+- 4-20, 5-11, 5-18, 5-54, 6-18, 6-26, 6-3, 6-9
+/ 4-20, 4-22, 5-18, 6-19, 6-4
+:= 2-91, 5-10, 5-17, 5-30, 5-65, 6-17, 6-25, 6-3, 6-8
+< 5-10, 5-17, 5-30, 6-8
+<= 5-10, 5-17, 5-30, 6-8
+<> 5-10, 5-17, 5-30, 6-18, 6-26, 6-3, 6-8
+= 5-10, 5-17, 5-30, 6-17, 6-25, 6-3, 6-8
+> 5-10, 5-17, 5-30, 6-9
+>= 5-10, 5-17, 5-30, 6-9
+
+Abfragekette 2-25
+ABS 6-10, 6-6
+abs 5-13, 5-20, 6-13
+Abweisende Schleife 2-29
+ALL 4-17
+all 4-17
+AND 5-7
+any 5-54
+Archiv 4-44
+Archivdiskette 4-47
+archive 1-9, 4-24, 4-45
+arctan 5-20
+arctand 5-20
+assert 6-39
+assertion 6-36
+Assertions 6-39
+Ausgabesteuerzeichen 5-70
+Ausschalten des Geräts 1-17
+Automatische Ablaufinformation 6-37
+
+begin 2-78, 4-3
+begin password 4-40
+Benutzereigene Ablaufinformation 6-37
+BOOL-Denoter: 2-9
+BOUND 2-83
+bound 5-56
+break 4-4
+brother 4-23
+bulletin 4-8
+
+CAND 5-7
+CAT 5-32
+change 5-33
+change 5-61
+change all 5-33
+check 4-49, 5-4
+clear 4-46
+clear removed 5-51
+clock 5-80
+code 5-34
+col 5-48
+column 6-31
+COLUMNS 6-28
+COMPILER ERROR 5-5
+complex 6-5
+complex i 6-5
+complex one 6-5
+complex zero 6-5
+compress 5-34
+configurator 1-9
+CONJ 6-6
+Container 5-26
+continue 4-3
+continue scan 5-83
+copy 4-26, 5-67
+COR 5-7
+cos 5-20
+cosd 5-20
+count off 6-39
+count on 6-39
+cout 5-75
+cursor 5-71
+
+dataspaces 5-66
+date 5-81
+Datenraum 1-3
+Datensicherheit 1-8
+day 5-81
+decimal exponent 5-20
+DECR 5-12, 5-19, 6-10
+delete char 5-34
+delete record 5-50
+Der EUMEL-Zeichensatz 5-29
+Der Lernmodus 3-17
+DET 6-28
+DIRFILE 2-73
+DIV 5-12, 6-11
+do 5-2
+down 5-48, 5-57
+downety 5-57
+dphi 6-6
+ds pages 5-66
+
+e 5-21
+edit 3-1, 4-29, 5-62
+editget 4-30, 5-63, 5-72
+editor 1-9
+Editor verlassen 3-2
+Ein- bzw. Ausschalten der Markierung 3-9
+Ein- bzw. Ausschalten des Einfügemodus 3-10
+Einfügen von Textpassagen 3-6
+Eingabesteuerzeichen 5-69
+Eingabetaste / Absatztaste 3-4
+eliminate reports 6-39
+Endlosschleife 2-28
+enter password 4-41
+eof 5-43
+erase 4-37
+Erweiterbarkeit 1-6
+
+ESC ) 3-16
+ESC ( 3-16
+ESC > 3-16
+ESC < 3-16
+ESC 9 3-14
+ESC 1 3-14
+ESC a 3-16
+ESC A 3-16
+ESC b 3-14
+ESC blank 3-16
+ESC d 3-15
+ESC e 3-14
+ESC ESC 3-16
+ESC f 3-14
+ESC g 3-15
+ESC HOP 3-17
+ESC HOP HOP 3-17
+ESC HOP taste 3-17
+ESC k 3-16
+ESC n 3-14
+ESC O 3-16
+ESC o 3-16
+ESC p 3-15
+ESC q 3-14
+ESC RUBIN 3-15
+ESC RUBOUT 3-15
+ESC s 3-16
+ESC ? taste 3-16
+ESC ! taste 3-16
+ESC U 3-16
+ESC u 3-16
+ESC v 3-14
+ESC w 3-14
+ESC k 3-16
+ESC ­ 3-16
+
+EUMEL-Editor 3-1
+evaluate 6-44
+exp 5-21
+
+false 5-7
+family password 4-42
+father 4-23
+Fehlermeldungen des Archivs 4-52
+fetch 4-33, 5-67
+fetchall 4-34
+FILE 2-73
+Fixpunkt 1-8
+floor 5-21
+forget 4-26, 4-47, 5-67
+frac 5-21
+
+Garbage Collection 5-26
+Gelerntes vergessen 3-17
+generate counts 6-40
+generate reports 6-40
+get 2-80, 5-44, 5-73, 6-5, 6-12, 6-21, 6-30
+getchar 5-72
+get cursor 5-71
+getline 5-45, 5-74
+
+Häufige Fehler bei der Benutzung von Datenräumen 2-85
+Häufigkeitszählung 6-36
+halt 4-4
+headline 5-43
+heap size 5-27
+help 4-5, 4-9
+hour 5-81
+
+idn 6-31
+imag part 6-6
+inchar 5-72
+incharety 5-72
+INCR 5-12, 5-19, 6-11
+INITFLAG 2-91
+initialized 2-91
+initialize random 5-13, 5-21
+input 2-75, 5-42
+insert 5-2
+insert char 5-35
+insert record 5-50
+Installation 6-36
+int 5-21
+int 6-13
+INT-Denoter: 2-7
+INV 6-28
+
+Kommando 1-9
+kommando auf taste 4-31
+kommando auf taste legen 4-31
+Kommando auf Taste legen 3-16
+Kommandotaste 3-11
+kommastellen 6-44
+Konfiguration 1-9
+
+length 5-35, 6-22
+LENGTH 5-35, 6-19
+Lernen ausschalten 3-17
+Lernen einschalten 3-17
+lernsequenz auf taste 4-32
+lernsequenz auf taste legen 4-32
+Lese-Fehler (Archiv) 4-52
+LEXEQUAL 5-31
+LEXGREATER 5-31
+LEXGREATEREQUAL 5-31
+lex sort 5-64
+LIKE 4-19, 5-59
+line 5-47, 5-71, 5-77
+line no 5-43
+lines 5-43
+list 4-27
+ln 5-22
+Löschtaste 3-10
+log10 5-22
+log2 5-22
+longint 6-13
+
+manager task 1-9
+Mantisse 5-16
+Markierzustand 3-9
+match 5-60
+matchpos 5-60
+matrix 6-32
+max 5-13, 5-22, 6-13
+maxint 5-13
+maxlongint 6-13
+maxreal 5-22
+max text length 5-35
+merke 6-45
+min 5-13, 5-23, 6-14
+minint 5-14
+MOD 5-14, 5-23, 6-11
+modify 2-75, 5-42
+Monitor 1-9
+Multi-Tasking-/Multi-User-Betrieb 1-5
+myself 4-23
+
+name 4-25
+Namensverzeichnis 4-16
+Netzwerkfähigkeit 1-6
+new 5-65
+next symbol 5-83
+next symbol 5-85
+Nicht abweisende Schleife 2-29
+nilspace 5-65
+niltask 4-22
+nilvector 6-22
+norm 6-22
+NOT 5-8
+notion 5-56
+
+old 5-66
+online 5-79
+Operationen auf Markierungen 3-15
+Operatoren 2-14
+OR 5-8
+OR 5-54
+out 5-75
+output 2-75, 5-42
+out subtext 5-76
+
+packets 4-8
+page 5-71
+Paketkonzept 2-1
+pause 5-79, 5-82
+phi 6-6
+pi 5-23
+pos 5-36
+Positionierung 5-71
+Positionierung des Cursors 3-4
+print 4-38
+PRINTER 4-24
+printer 4-24
+Priorität von generischen Operatoren 2-49
+Priorität von Operatoren 2-16
+prot 5-4
+Prozeduren als Parameter 2-39
+Prozeduren mit Parametern 2-38
+prozentsatz 6-45
+Prozeßkommunikation 1-6
+PUBLIC 4-24
+public 4-24
+put 5-46, 5-78, 6-12, 6-21, 6-30, 6-5
+putline 5-46, 5-78
+
+random 5-14, 5-23, 6-14
+read record 5-50
+real 5-14, 5-37
+REAL-Denoter: 2-8
+Realisierung von abstrakten Datentypen 2-47
+real part 6-6
+referencer 6-42
+Referenzliste 6-41
+Refinements 2-1
+reinsert 5-51
+release 4-45
+remainder 4-18
+remove 5-51
+rename 4-28
+rename myself 4-25
+reorganize 5-52
+replace 5-37, 6-22
+replace column 6-34
+replace element 6-34
+replace row 6-35
+report 6-36
+report off 6-40
+report on 6-40
+reserve 4-25
+REST 3-6
+round 5-23
+row 6-32
+ROWS 6-29
+run 5-3
+runagain 5-3
+
+save 4-35, 5-67
+saveall 4-36
+scan 5-86
+Schreibarbeit beenden 3-2
+Schutz vor fehlerhaftem Zugriff auf Datenobjekte 2-45
+Scratch-Datei 3-13
+segments 5-52
+sequential file 5-41
+SHard 1-5
+show 4-30
+shutup 1-17
+sign 5-15, 5-24, 6-14
+SIGN 6-11
+sin 5-24
+sind 5-24
+smallreal 5-24
+SOME 2-80, 4-17
+son 4-23
+sort 5-64
+Spracherweiterung 2-44
+sqrt 5-24, 6-6
+Standard-Datenraum 1-9
+std tastenbelegung 4-32
+STOP-Taste 3-20
+storage 4-11, 5-66
+storage info 4-5, 4-11
+sub 6-33
+SUB 5-37, 6-20
+subtext 5-38
+supervisor 4-24
+Supervisor 1-9
+SUPERVISOR-Taste 3-18
+Symbole 5-83
+sysin 5-73
+sysout 5-77
+
+Tabulatortaste 3-8
+tan 5-25
+tand 5-25
+task 4-22
+Task 1-9
+task info 4-5, 4-12
+Task-Organisation 1-2
+task password 4-43
+task status 4-15
+taste enthaelt kommando 4-31
+tecal 6-45
+tecalauskunft 6-45
+text 5-15, 5-25, 5-39, 6-15
+TEXT-Denoter: 2-9
+Thesaurus 4-16
+time 5-82
+time of day 5-82
+TIMESOUT 5-76
+Titelzeile 3-2
+to line 5-48
+transp 6-33
+TRANSP 6-29
+true 5-8
+type 5-66
+TYPE COMPLEX 6-3
+TYPE LONGINT 6-8
+
+Überschrift in die Kopfzeile 5-43
+Umschalttaste 3-4
+UNLIKE 5-59
+Unterbrechen einer Ausgabe 3-20
+up 5-49
+up 5-58
+uppety 5-58
+
+vector 6-23
+Vereinbarung eines dyadischen Operators 2-42
+Vereinbarung eines monadischen Operators 2-42
+Verstärkertaste 3-5
+Verwendung von Prozeduren 2-35
+Virtuelle Speicherverwaltung 1-7
+Vorbelegte Tasten 3-17
+
+warnings 5-4
+WEITER-Taste 3-20
+Wertliefernde Prozeduren 2-40
+Wertliefernde Refinements 2-34
+word wrap 4-32
+write 5-78
+write 5-47
+write record 5-50
+
+XOR 5-8
+
+Zählschleife 2-30
+Zeichen schreiben 3-16
+zero 6-15
+#tableend#
+
diff --git a/doc/programmer-manual/1.8.7/doc/programmierhandbuch.inhalt b/doc/programmer-manual/1.8.7/doc/programmierhandbuch.inhalt
new file mode 100644
index 0000000..45b3f1f
--- /dev/null
+++ b/doc/programmer-manual/1.8.7/doc/programmierhandbuch.inhalt
@@ -0,0 +1,249 @@
+#setcount (1)#
+#block##pageblock#
+#pagenr ("%", 1)#
+#headeven#
+#center#EUMEL-Benutzerhandbuch
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#Inhalt
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+
+#center#____________________________________________________________
+I - % #right#GMD
+#end#
+#bottomodd#
+
+#center#____________________________________________________________
+GMD #right# I - %
+#end#
+
+#lpos(0.2)##lpos(1.8)##lpos(9.0)#
+
+TEIL 1 : Einleitung
+#table#
+1.1 Allgemeines über EUMEL 1
+1.2 Struktur des Betriebssystems EUMEL 2
+1.3 Eigenschaften des Betriebssystems 4
+ Multi-Tasking-/Multi-User-Betrieb 5
+ Prozeßkommunikation und Netzwerkfähigkeit 6
+ Erweiterbarkeit 6
+ Virtuelle Speicherverwaltung 7
+ Datensicherheit 8
+1.4 Wichtige Begriffe 9
+1.5 Die Notation in diesem Buch 10
+1.6 Die Funktionstasten des EUMEL-Systems 11
+1.7 Eine Beispielsitzung 12
+#tableend#
+
+
+
+
+TEIL 2 : ELAN
+#table#
+2.1 Besondere Eigenschaften von ELAN 1
+2.2 Lexikalische Elemente 2
+2.2.1 Schlüsselwörter 2
+2.2.2 Bezeichner 3
+2.2.3 Sonderzeichen 4
+2.2.4 Kommentare 5
+2.3 Datenobjekte 6
+2.3.1 Elementare Datentypen 6
+2.3.1.1 Denoter für elementare Datentypen 7
+ INT-Denoter: 7
+ REAL-Denoter: 8
+ TEXT-Denoter: 9
+ BOOL-Denoter: 9
+2.3.1.2 LET-Konstrukt für Denoter 10
+2.3.2 Zugriffsrecht 11
+2.3.3 Deklaration 11
+2.3.4 Initialisierung 12
+2.4 Programmeinheiten 13
+2.4.1 Elementare Programmeinheiten 14
+2.4.1.1 Ausdruck 14
+ Operatoren 14
+ Priorität von Operatoren 16
+2.4.1.2 Zuweisung 18
+2.4.1.3 Refinementanwendung 19
+2.4.1.4 Prozeduraufruf 20
+2.4.2 Zusammengesetzte Programmeinheiten 22
+2.4.2.1 Folge 22
+2.4.2.2 Abfrage 23
+2.4.2.3 Auswahl 26
+2.4.2.4 Wertliefernde Abfrage
+ und wertliefernde Auswahl 27
+2.4.2.5 Wiederholung 27
+ Abfragekette 25
+ Endlosschleife 28
+ Abweisende Schleife 29
+ Nicht abweisende Schleife 29
+ Zählschleife 30
+2.4.3 Abstrahierende Programmeinheiten 32
+2.4.3.1 Refinementvereinbarung 32
+ Vorteile der Refinementanwendung 33
+ Wertliefernde Refinements 34
+2.4.3.2 Prozedurvereinbarung 35
+2.4.3.3 Operatorvereinbarung 41
+ Verwendung von Prozeduren 35
+ Prozeduren mit Parametern 38
+ Prozeduren als Parameter 39
+ Wertliefernde Prozeduren 40
+ Vereinbarung eines monadischen Operators 42
+ Vereinbarung eines dyadischen Operators 42
+2.4.3.4 Paketvereinbarung 43
+ Spracherweiterung 44
+ Schutz vor fehlerhaftem Zugriff
+ auf Datenobjekte 45
+ Realisierung von abstrakten Datentypen 47
+2.4.4 Terminatoren für Refinements,
+ Prozeduren und Operatoren 48
+2.4.5 Generizität von Prozeduren und Operatoren 49
+ Priorität von generischen Operatoren 49
+2.4.6 Rekursive Prozeduren und Operatoren 50
+2.5 Programmstruktur 52
+2.6 Zusammengesetzte Datentypen 56
+2.6.1 Reihung 56
+2.6.2 Struktur 61
+2.6.3 LET-Konstrukt für
+ zusammengesetzte Datentypen 64
+2.6.4 Denoter für zusammengesetzte
+ Datentypen (Konstruktor) 65
+2.7 Abstrakte Datentypen 67
+2.7.1 Definition neuer Datentypen 67
+2.7.2 Konkretisierung 69
+2.7.3 Denoter für abstrakte Datentypen (Konstruktor) 70
+2.8 Dateien 73
+2.8.1 Datentypen FILE und DIRFILE 73
+ FILE: 73
+ DIRFILE: 73
+2.8.2 Deklaration und Assoziierung 74
+ input: 75
+ output: 75
+ modify: 75
+2.9 Abstrakte Datentypen im EUMEL-System 77
+2.9.1 Datentyp TASK 77
+2.9.2 Datentyp THESAURUS 79
+2.9.3 Datenräume 81
+2.9.3.1 Datentyp DATASPACE 82
+2.9.3.2 BOUND-Objekte 83
+ Häufige Fehler bei der Benutzung von Datenräume 85
+2.9.3.3 Definition neuer Dateitypen 88
+2.9.4 Datentyp INITFLAG 91
+#tableend#
+
+
+
+
+TEIL 3 : Der Editor
+#table#
+3.1 Ein- und Ausschalten des Editors 1
+3.2 Die Funktionstasten 3
+3.3 Die Wirkung der Funktionstasten 4
+3.4 ESC Kommandos 11
+ Operationen auf Markierungen 15
+ Zeichen schreiben 16
+ Kommando auf Taste legen 16
+ Vorbelegte Tasten 17
+ Der Lernmodus 17
+3.5 Positionieren, Suchen, Ersetzen
+ im Kommandodialog 21
+ Weitere Hilfen 23
+#tableend#
+
+
+
+
+TEIL 4 : Kommandosprache
+#table#
+4.1 Supervisor 2
+4.2 Monitor 6
+4.2.1 Hilfsprozeduren 8
+ Informationsprozeduren 11
+4.2.2 Thesaurus 16
+4.2.3 Tasks 21
+4.2.4 Handhabung von Dateien 26
+4.2.5 Editor-Prozeduren 29
+4.2.6 Dateitransfer 33
+4.2.7 Passwortschutz 39
+4.2.8 Das Archiv 44
+ Fehlermeldungen des Archivs 52
+#tableend#
+
+
+
+
+TEIL 5 : Programmierung
+#table#
+5.1 Der ELAN-Compiler 1
+5.1.1 Fehlermeldungen des ELAN-Compilers 5
+5.2 Standardtypen 7
+5.2.1 Bool 7
+5.2.2 Integer-Arithmetik 9
+5.2.3 Real-Arithmetik 16
+5.2.4 Text 26
+ Der EUMEL-Zeichensatz 29
+5.3.1 Assoziierung 41
+5.3.2 Informationsprozeduren 43
+5.3.3 Betriebsrichtung INPUT 44
+5.3.4 Betriebsrichtung OUTPUT 46
+5.3.5 Betriebsrichtung MODIFY 48
+5.3.6 FILE -Ausschnitte 51
+5.4 Suchen und Ersetzen in Textdateien 53
+5.4.1 Aufbau von Textmustern 54
+5.4.2 Suche nach Textmustern 57
+5.4.3 Treffer registrieren 59
+5.4.4 Treffer herausnehmen 60
+5.4.5 Ändern in Dateien 61
+5.4.6 Editor-Prozeduren 62
+5.4.7 Sortierung von Textdateien 64
+5.4.8 Prozeduren auf Datenräumen 65
+5.5 Eingabe/Ausgabe 68
+5.5.1 E/A auf Bildschirm 69
+5.5.1.1 Eingabesteuerzeichen 69
+5.5.1.2 Ausgabesteuerzeichen 70
+5.5.1.3 Positionierung 71
+ Grundlegende Prozeduren 72
+ Umleitbare Eingabeprozeduren 73
+ Grundlegende Prozeduren 75
+ Umleitbare Ausgabeprozeduren 77
+5.5.1.4 Eingabe 72
+5.5.1.5 Ausgabe 75
+5.5.1.6 Kontrolle 79
+5.5.2 Zeitmessung 80
+5.6 Scanner 83
+ Scanner-Kommandos 85
+#tableend#
+
+
+
+
+TEIL 6 : Das Archiv 'std zusatz'
+#table#
+6.1 Erweiterungen um Mathematische Operationen 2
+6.1.1 COMPLEX 2
+6.1.2 LONGINT 7
+6.1.3 VECTOR 16
+6.1.4 MATRIX 24
+6.2 Programmanalyse 36
+ reporter - Kommandos 39
+ Referencer 41
+ referencer - Kommandos 42
+6.3 Rechnen im Editor 43
+ Arbeitsweise 43
+ TeCal Prozeduren 44
+#tableend#
+
+
+
+
+Anhang : ELAN-Syntaxdiagramme
+
+
+
+
+INDEX
+
diff --git a/doc/programmer-manual/1.8.7/doc/programmierhandbuch.titel b/doc/programmer-manual/1.8.7/doc/programmierhandbuch.titel
new file mode 100644
index 0000000..79b09b0
--- /dev/null
+++ b/doc/programmer-manual/1.8.7/doc/programmierhandbuch.titel
@@ -0,0 +1,52 @@
+____________________________________________________________________________
+
+
+#on("b")##on ("u")#
+#center#Betriebssystem E U M E L
+#off ("u")#
+
+
+#center#Programmierhandbuch
+
+
+
+
+#off("b")#
+#center#Lizenzfreie Software der
+#on ("b")#
+
+#center#Gesellschaft für Mathematik und Datenverarbeitung mbH,
+#center#5205 Sankt Augustin
+
+
+#off("b")#
+#center#Die Nutzung der Software ist nur im Schul- und Hochschulbereich für
+#center#nichtkommerzielle Zwecke gestattet.
+
+#center#Gewährleistung und Haftung werden ausgeschlossen
+
+
+____________________________________________________________________________
+#page#
+#block##pageblock#
+#start(5.0,1.5)#
+
+#lpos(3.0)#
+#table#
+
+
+
+
+
+
+Benutzerhandbuch
+
+Programmierung
+
+
+
+Stand: 1.7.87
+
+#tableend##page#
+
+
diff --git a/doc/programmer-manual/1.8.7/source-disk b/doc/programmer-manual/1.8.7/source-disk
new file mode 100644
index 0000000..13e2021
--- /dev/null
+++ b/doc/programmer-manual/1.8.7/source-disk
@@ -0,0 +1 @@
+grundpaket/10_handbuecher.2.img