diff options
Diffstat (limited to 'doc/programmer-manual')
| -rw-r--r-- | doc/programmer-manual/1.8.7/doc/programmierhandbuch.1 | 650 | ||||
| -rw-r--r-- | doc/programmer-manual/1.8.7/doc/programmierhandbuch.2a | 1845 | ||||
| -rw-r--r-- | doc/programmer-manual/1.8.7/doc/programmierhandbuch.2b | 1395 | ||||
| -rw-r--r-- | doc/programmer-manual/1.8.7/doc/programmierhandbuch.3 | 728 | ||||
| -rw-r--r-- | doc/programmer-manual/1.8.7/doc/programmierhandbuch.4 | 1692 | ||||
| -rw-r--r-- | doc/programmer-manual/1.8.7/doc/programmierhandbuch.5 | 1329 | ||||
| -rw-r--r-- | doc/programmer-manual/1.8.7/doc/programmierhandbuch.5b | 1481 | ||||
| -rw-r--r-- | doc/programmer-manual/1.8.7/doc/programmierhandbuch.6 | 1441 | ||||
| -rw-r--r-- | doc/programmer-manual/1.8.7/doc/programmierhandbuch.index | 449 | ||||
| -rw-r--r-- | doc/programmer-manual/1.8.7/doc/programmierhandbuch.inhalt | 249 | ||||
| -rw-r--r-- | doc/programmer-manual/1.8.7/doc/programmierhandbuch.titel | 52 | ||||
| -rw-r--r-- | doc/programmer-manual/1.8.7/source-disk | 1 | 
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 | 
