summaryrefslogtreecommitdiff
path: root/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil5
blob: d59b1475f6890a04a8cf96602f806e678a9fa0a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
                     EUMEL-Benutzerhandbuch 
 
 
                      TEIL 5: ELAN-Compiler                         
 
 
Der ELAN-Compiler im EUMEL-System 
 
In diesem Kapitel wird die Benutzung des ELAN-Compilers im EUMEL-System be- 
schrieben. Es enthält Angaben, welche Einschränkungen bzw. Erweiterungen 
gegenüber dem Sprachstandard existieren. Eine Einführung in die Programmier- 
sprache ELAN wird hier nicht gegeben. 
 
 
 
1. Einführung 
 
Der im EUMEL-System eingesetzte ELAN-Compiler wurde von J. Liedtke und 
U. Bartling am HRZ Bielefeld in den Jahren 1975/76 erstellt und in den 
folgenden Jahren erweitert und der Sprachbeschreibung angepaßt. Der gleiche 
ELAN-Compiler wird auch auf verschiedenen Großrechnern (TR440, IBM, SIEMENS) 
eingesetzt. 
 
Den ELAN-Compiler kann man sich als aus zwei Teilen bestehend vorstellen. 
Einmal gibt es den "eigentlichen" ELAN-Compiler, der ein ELAN-Programm in 
eine Maschinensprache (im EUMEL-System der sogenannte EUMEL0-Code) übersetzt. 
Zum anderen verwaltet der ELAN-Compiler übersetzte Moduln (in ELAN Packets 
genannt). 
 
In einem Packet können Prozeduren, Datentypen und/oder Operatoren definiert 
werden. Ist ein solches Packet vorübersetzt (im EUMEL-System wird dieser 
Vorgang 'insertieren' genannt), stehen diese Objekte zur Benutzung zur Ver- 
fügung. Durch Packets kann man somit die Sprache ELAN erweitern. 
 
Weitere Informationen über die Programmiersprache ELAN finden Sie in den 
folgenden Büchern: 
 
Hommel / Jähnichen / Koster: 
Methodisches Programmieren 
W. de Gruyter, Berlin, 1983 
 
Klingen / Liedtke: 
Programmieren mit ELAN 
Teubner, Stuttgart, 1983 
 
In der Regel sind in einem EUMEL-System die Standard-Packets bereits in- 
sertiert (Ausnahmen: Datentypen #ib#VECTOR#ie# und #ib#MATRIX#ie#). Zusätz- 
lich sind weitere Packets vorübersetzt, die Kommandos zur Verfügung stellen. 
Welche weiteren Packets insertiert werden, kann jede EUMEL-Installation und 
jeder Nutzer entscheiden. Somit kann man sein System auf spezielle 
Anwendungen zuschneiden. 
 
 
 
2. Übersetzen mit dem ELAN-Compiler 
 
In diesem Abschnitt wird erklärt, wie Programme mit dem ELAN-Compiler über- 
setzt oder vorübersetzt werden können. 
 
 
 
Einfaches Übersetzen: 'run'-Kommando 
 
Mit dem 'run'-Kommando kann ein ELAN-Programm übersetzt und ausgeführt 
werden. 
 
Das 'run'-Kommando (vergl. auch die Kommandos in der Beschreibung des 
Monitors) übersetzt ein in einer Datei befindliches ELAN-Programm. Beispiel: 
 
     run ("mein programm") 
 
übersetzt das ELAN-Programm, welches in der Datei 'mein programm' enthalten 
ist. (Wie man ELAN-Programme schreibt, ist u.a. im Editor-Kapitel beschrie- 
ben). 
 
Der Fortschritt der Übersetzung wird durch laufende Nummern auf dem Bild- 
schirm des Benutzers angezeigt, die die gerade verarbeiteten Zeilennummern 
anzeigen. Da der ELAN-Compiler ein Zwei-Paß Compiler ist, werden alle 
Zeilen (mindestens) zweimal überprüft. 
 
Ist das Programm syntaktisch korrekt, d.h. hat der ELAN-Compiler keine 
Fehler gefunden, wird eine Ende-Meldung abgesetzt, die den Speicherumfang 
des übersetzten Programms enthält. Die Ende-Meldung entfällt, wenn die Task 
an kein Terminal angekoppelt ist. 
 
Nach der Ende-Meldung wird das Programm unmittelbar ausgeführt (ein Binder 
ist im EUMEL-System nicht notwendig). 
 
Merke: Das Kommando 'run' übersetzt ein in einer Datei befindliches Programm 
und führt fehlerfreie Programme aus. 
 
 
 
Korrektur von Fehlern 
 
In diesem Abschnitt wird beschrieben, wie (syntaktische bzw. semantische) 
Fehler korrigiert werden können. 
 
Entdeckt der ELAN-Compiler Fehler, so meldet er sie dem Benutzer unter An- 
Angabe der Zeilennummer. Die zwei Pässe des Compilers sind so konstruiert, 
daß sie unterschiedliche Fehler entdecken. Ist bereits im ersten Paß ein 
Fehler entdeckt worden, wird der zweite Paß nicht gestartet. Somit kann es 
vorkommen, daß man glaubt, alle Fehler beseitigt zu haben und dann werden 
wieder (andere) Fehler durch den zweiten Paß gemeldet ... 
 
Fehlermeldungen und Quelldatei werden nach Abschluß der Übersetzung durch 
den Paralleleditor angezeigt. Vergl. dazu auch die Beschreibung des Editors. 
 
Merke: Eventuelle Fehler und das zu korrigierende Programm werden durch den 
Paralleleditor angezeigt. So kann man das fehlerhafte Programm bequem ver- 
ändern. 
 
 
Nochmalige Ausführung eines Programms: 'run again' 
 
Mit 'run again' kann das zuletzt fehlerfrei übersetzte Programm nochmals 
ausgeführt werden. 
 
Ist ein Programm fehlerfrei übersetzt worden, so kann man es mit dem Komman- 
do 'run again' (beispielsweise mit anderen Eingabedaten) nochmals ausführen. 
 
Merke: Das Kommando 'run again' führt das zuletzt übersetzte Programm noch- 
mals aus. 
 
 
 
Übersetzen von Kommandos 
 
Auch Kommandos werden in der Regel vom ELAN-Compiler übersetzt. 
 
Der ELAN-Compiler wird nicht nur für Programme eingesetzt, sondern auch als 
Übersetzer für die EUMEL-Kommandosprache (in anderen Systemen "job control 
language", abgekürzt JCL genannt) und für Kommandos, die man im Editor geben 
kann. Jedes Kommando der EUMEL-Kommandosprache ist ein kleines ELAN-Programm, 
welches in der Regel aus einem Prozeduraufruf besteht. Einige häufig be- 
nutzte Kommandos werden der Effizienz halber über einen Kommando-Interpreter 
abgewickelt. Beispiel: 
 
     edit ("mein erstes Programm") 
 
Natürlich ist es möglich, mehrere Kommandos oder ein richtiges, einzeiliges 
Programm als Kommando zu verwenden. Beispiele: 
 
     put (17 * 4) 
 
     INT VAR i; FOR i FROM 1 UPTO 100 REP put ("i") PER 
 
     edit ("datei"); lineform ("datei"); print ("datei") 
 
     INT VAR i; FOR i FROM 1 UPTO 10 REP print ("d") END REP 
 
Mit vorübersetzten Prozeduren (siehe auch das Kommando 'insert') ist es 
möglich, eine eigene Kommandosprache zusammenzustellen. 
 
Merke: Der ELAN-Compiler wird auch für die Übersetzung und Ausführung von 
Kommandos benutzt. 
 
 
 
Vorübersetzen: 'insert' 
 
Das Kommando 'insert' übersetzt ein in einer Datei befindliches ELAN-Pro- 
gramm und trägt dieses in den Tabellenspeicher des Compilers ein. 
 
Mit dem Kommando 'insert' kann ein ELAN-Programm (d.h. ein Packet oder eine 
Packetfolge) in den Tabellenspeicher (eine Art "Compilerdatenbank") des 
ELAN-Compilers eingetragen werden. Die in den Packets enthaltenen Objekte 
stehen nach Abschluß der Übersetzung zur Verfügung. Beispiel: 
 
Die Datei 'mein druck' enthalte folgendes Programm: 
 
     PACKET mein druck DEFINES drucke: 
 
     PROC drucke (TEXT CONST datei): 
       edit (datei); 
       lineform (datei); 
       pageform (datei); 
       print (datei) 
     END PROC drucke; 
 
     END PACKET drucke; 
 
Mit dem Kommando 
 
     insert ("mein druck") 
 
wird das Packet 'drucke' in die Tabellen des ELAN-Compilers aufgenommen. 
Nun kann (als Kommando oder in einem Programm) der Prozeduraufruf 'drucke' 
verwandt werden. 
 
Man beachte, daß der Nutzer beim Einrichten seiner Task alle insertierten Ob- 
jekte der Vater-Task erhält. Insertiert der Benutzer in seiner Task weitere 
Packets, so sind diese nur ihm verfügbar (oder ggf. seinen Sohn-Tasks). Es 
ist somit möglich, Tasks mit unterschiedlichem Sprachumfang einzurichten. 
 
Einmal insertierte Packets können nicht mehr aus den Compilertabellen ent- 
fernt werden. Man kann also nur die Task löschen (bitte vorher alle Dateien 
archivieren oder bei der Vater-Task aufheben (siehe Kommando: 'save')). 
 
Das Kommando 'insert' arbeitet auch mit einem Thesaurus (vergl. dazu auch 
den Teil über Dateien). Beispiel: 
 
     insert (ALL myself) 
 
insertiert alle Dateien der Benutzer-Task in Reihenfolge. 
 
Merke: Das Kommando 'insert' übersetzt die in einer Datei enthaltene Packet- 
folge und trägt diese in die Tabellen des Compilers ein. 
 
 
 
Programme von einem Programm übersetzen lassen 
 
Manchmal ist es notwendig, daß ein Programm den ELAN-Compiler zur Über- 
setzung und Ausführung eines Programms aufrufen muß. 
 
Natürlich kann man auch die Kommandos 'run' oder 'insert' von einem Programm 
aus aufrufen. Leider müssen die zu übersetzenden Programme in einer Datei 
enthalten sein. Will man jedoch nur eine Anweisung übersetzen und ausführen 
lassen und nicht den "Umweg" über eine Datei gehen (wie z.B. die Kommandos 
im Monitor oder Editor), so kann man die Prozedur '#ib#do#ie#' verwenden. 
Beispiel: 
 
     ... 
     get (eingabe); 
     do (eingabe); 
     ... 
 
Findet der ELAN-Compiler bei der Übersetzung eines Textes der Prozedur 'do'
einen Fehler, so wird dieser Fehler über 'errorstop' gemeldet (vergl. dazu 
auch das Kapitel über die Fehlerbehandlung im System-Handbuch) und die Über- 
setzung bei der ersten Fehlermeldung abgebrochen. In diesem Fall kann ein 
Nutzer den Fehler durch eine #ib#Fängerebene#ie# leicht selbst behandeln. 
 
Merke: Die Prozedur 'do' übersetzt (kleinere) ELAN-Programme von einem Pro- 
gramm aus. 
 
 
 
Kommandos zur Steuerung des ELAN-Compilers 
 
In diesem Abschnitt beschreiben wir die Kommandos für die Steuerung des 
ELAN-Compilers#ie#. Ebenso wie die Kommandos zur Übersetzung eines Programms 
müssen die Kommandos zur Steuerung des Compilers vom Monitor gegeben werden. 
 
Mit dem Kommando 
 
     prot ("datei name") 
 
wird das Listing des ELAN-Compilers eingeschaltet und in die angegebene 
Datei ausgegeben. Mit 
 
     prot off 
 
wird es wieder ausgeschaltet. 'prot off' ist voreingestellt. 
 
Normalerweise werden Zeilennummern des Quellprogramms im übersetzten Pro- 
gramm mitgeführt, so daß bei einem Fehler zusätzlich zur Fehlermeldung auch 
die Nummer der Zeile ausgegeben werden kann, in der der Fehler aufgetreten 
ist. Mit dem Kommando 
 
     check off 
 
kann die Generierung von Zeilenummern für das Objektprogramm abgeschaltet 
werden. Durch die Angabe dieses Kommandos wird weniger Code für das 
Programm erzeugt. Mit 
 
     check on 
 
wird die Generierung von Zeilennummern durch den Compiler wieder einge- 
schaltet. 'check on' ist voreingestellt. Mit der Prozedur 
 
     check 
 
die ein boolesches Resultat liefert, kann in einem Programm abgefragt werden, 
ob der 'check'-Zustand ein- oder ausgeschaltet ist. Beispiel: 
 
     IF check THEN check off FI 
 
Merke: Die Kommandos 'check on' bzw. 'check off' schalten das Einfügen von 
Zeilennummern in den erzeugten Code ein bzw. aus. 
 
 
 
3. Abweichungen gegenüber dem Sprachstandard 
 
Der im HRZ Bielefeld entwickelte ELAN-Compiler weist einige Abweichungen 
gegenüber dem Sprachstandard auf, wie er in der Sprachbeschreibung formu- 
liert ist. Es existieren einige Einschränkungen, die einen Programmierer 
jedoch nicht weiter behindern. Die Spracherweiterungen wurden meist speziell 
für das EUMEL-System geschaffen. Weitere Abweichungen gegenüber dem aktuellen 
Sprachstandard, die aber in der nächsten Sprachbeschreibung enthalten sein 
werden, sind in einem weiteren Abschnitt aufgeführt. 
 
 
 
Einschränkungen gegenüber dem Sprachstandard 
 
   * Das "row display" wurde nicht implementiert. Der Grund dafür liegt in 
     dem unverhältnismäßig hohen Aufwand, dieses Sprachmittel bei der gegen- 
     wärtigen Compiler-Struktur zu implementieren. Abhilfe: Man verwende den 
     Konstruktor. Beispiel: 
 
        ROW 5 INT VAR vektor; 
        vektor := [1, 2, 3, 4, 5];   (* nicht möglich       *) 
        vektor := ROW 5 INT :(1, 2, 3, 4, 5); (* Ersatz: Konstruktor *) 
 
   * Einige alternative Darstellungen von Symbolen können nicht verwendet 
     werden. Diese sind: 
 
        "&"-Zeichen für "AND", 
        "/="-Zeichen für "<>", 
        "%"- und "//"-Zeichen für "DIV". 
 
   * Eine Typ-Definition muß einer Deklaration immer textuell vorangehen. 
     Beispiel: 
 
        TYPE QUADRAT = ...                   (* erlaubt *) 
        QUADRAT VAR rundes quadrat; 
        ... 
        PUNKT VAR meiner;                    (* verboten *) 
        TYPE PUNKT = ... 
 
     Es ist jedoch erlaubt, einen Typ in einer Typ-Definition zu verwenden, 
     der textuell erst später definiert wird. Beispiel: 
 
        TYPE PERSON = STRUCT (TEXT name, vorname, ADRESSE wohnort); 
        TYPE ADRESSE = ... 
 
     Diese Einschränkung ("defined before applied") gilt nur für Typen, 
     nicht für Datenobjekte u.ä.. Selbstverständlich ist 
 
        otto := 0; 
        INT VAR otto; 
        ... 
 
     erlaubt (aber kein besonders schöner Programmierstil)! 
 
   * Die Operatoren AND und OR können nicht redefiniert werden, sofern einer 
     ihrer Operanden vom Typ BOOL ist. 
 
 
 
Implementationsbedingte Einschränkungen 
 
   * Es sind bis zu 32 000 Zeichen in einem TEXT zugelassen. Hat ein TEXT 
     bis 13 Zeichen, so wird er vollständig auf dem Stack untergebracht. 
     TEXTe mit mehr als 13 Zeichen werden auf dem Heap gespeichert. Die 
     Benutzung des Heaps bedeutet unter Umständen eine Verlangsamung eines 
     Programms. Darum ist 
 
max text length = 32 000 
 
   * Die Anzahl der Zeichen in einem TEXT-Denoter (Angabe eines TEXTes in 
     einem Programm) ist auf 254 Zeichen beschränkt. 
 
   * INT-Werte werden in sechzehn Bit dargestellt (einschließlich Vor- 
     zeichen). Das bedeutet, daß 
 
        maxint = 32 767 
        minint = - 32 768 
 
     ist. 
 
   * REAL-Werte werden intern mit einer Mantisse von 13 Stellen abgespei- 
     chert, von denen die ersten sieben Stellen bei der Ausgabe dargestellt 
     werden. Das bedeutet, daß 
 
        maxreal = 9.999999999999e126 
 
     ist. 
 
   * Die lexikographische Reihenfolge von Zeichen entspricht dem ASCII-Code 
     (vergl. dazu die Code-Tabelle). 
 
   * Weiterhin sieht der ASCII-Code noch eine Anzahl von Steuerzeichen vor, 
     die jedoch von Herstellern leider nicht immer gleich interpretiert 
     werden. Diese Zeichen sind im EUMEL-System teilweise normiert und 
     können verwandt werden. Die verfügbaren Steuerzeichen sind ebenfalls im 
     EUMEL-Taschenbuch aufgeführt. 
 
   * Die Initialisierung von Paketen (genauer: die Initialisierung von 
     Datenobjekten, die in vorübersetzten PACKETs außerhalb von Prozeduren 
     deklariert wurden) wird nur einmal, während der Übersetzung, durchge- 
     führt. Werden mehrere Pakete hintereinander (aus einer Datei) übersetzt, 
     dürfen die Prozeduren 'run', 'run again', 'insert' und 'do', die wieder 
     den ELAN-Compiler aufrufen, nur bei der Ausführung des letzten Packets 
     verwandt werden, weil der ELAN-Compiler nicht rekursiv benutzbar ist. 
 
 
 
Erweiterungen gegenüber dem Standard 
 
   * Einem Datenobjekt, das an einen #ib#Datenraum#ie# gebunden werden soll, 
     wird bei der Deklaration das Schlüsselwort #ib#BOUND#ie# vorangestellt. 
     Damit wird dem ELAN-Compiler mitgeteilt, daß er für ein solches Objekt 
     keinen Speicherplatz reservieren muß. Die Assoziation mit einem Daten- 
     raum erfolgt bei der Deklaration mit Hilfe der Initialisierung. 
     Beispiel: 
 
        BOUND INT VAR objekt :: old ("hugo"); 
        (* eine bereits errichtete Datei wird unter dem Namen "hugo" benutzt. 
        "objekt" ist jetzt an die Datei mit dem Namen "hugo" "gebunden" *) 
 
 
 
Vorweggenommene Implementation des nächsten Standards 
 
In diesem Abschnitt sind Erweiterungen/Einschränkungen des ELAN-Compilers 
hinsichtlich der aktuellen ELAN-Sprachbeschreibung aufgeführt, die in der 
nächsten Sprachbeschreibung mit aufgenommen werden. 
 
   * ASCII-Zeichen, die nicht unmittelbar dargestellt werden können, können 
     in TEXT-Denotern angegeben werden, sofern sie in Anführungszeichen 
     eingeschlossen werden. Beispiele: 
 
        ""13"" 
 
     ist ein TEXT-Denoter, der nur CR (carriage return) enthält. 
 
        "Jetzt erfolgt ein Zeilenwechsel "13""10"" 
 
     Hier wird nach der Ausgabe des Textes ein "Wagenrücklauf" ('CR', 
     Code = 13) und einen Zeilenvorschub ('LF', Code = 10) erzeugt. 
 
        ""1""4"" 
 
     positioniert in die linke obere Ecke eines Bildschirms (Code = 1) und 
     löscht den Bildschirm (Code = 4). 
 
   * Im aktuellen Standard wurde die #ib#Reihenfolge der Auswertung von 
     Operanden#ie# nicht definiert. Nunmehr wird zusätzlich nicht garantiert, 
     daß alle Operanden ausgewertet werden, wenn dies nicht notwendig ist. 
     Beispiel: 
 
        IF f (x) > 0 AND x <> 0  THEN ... FI 
 
     Hier muß beispielsweise 'f (x)' nicht ausgewertet werden, wenn 'x = 0' 
     ist. 
 
   * Die booleschen Operatoren CAND und COR stehen zusätzlich zur Verfügung. 
     Wirkung: 
 
        a CAND b        :<==>   IF a THEN b ELSE FALSE FI 
 
        a COR b         :<==>   IF a THEN TRUE ELSE b FI 
 
     Beispiel: 
 
        IF element vorhanden 
          THEN verarbeite element 
        FI. 
 
     element vorhanden: 
        index > 0 CAND liste (index) > 0. 
 
   * Prozeduren als Parameter. Beispiel: 
 
        (* Deklaration: *) 
         PROC draw (REAL PROC (REAL CONST) funktion, 
                    REAL CONST von, bis, delta) 
        (* Aufruf: *) 
        draw (REAL PROC (REAL CONST) sin, -pi, pi, 0.1) 
 
     Die obige Form von Prozedur-Parametern wird als "Langform" bezeichnet. 
     Die Langform muß verwandt werden, wenn generische aktuelle Parameter 
     benutzt werden. Eine "Kurzform" reicht aus, wenn der aktuelle Prozedur- 
     Parameter keine generischen Prozedur ist, d.h. eindeutig über den 
     Prozedurnamen (und nicht noch über die Datentypen seiner Parameter) 
     identifiziert werden kann. Die Kurzform unterscheidet sich von der 
     Langform nur beim Aufruf, bei dem eventuelle Resultate und die Daten- 
     typen der Parameter nicht mit angegeben werden müssen. Beispiel: 
 
        (* Aufruf obiger Prozedur bei nichtgenerischer aktueller Prozedur 
        'sin' *) 
        draw (PROC sin, -pi, pi, 0.1) 
 
   * In Paketen sind auch außerhalb von Prozeduren Refinements zugelassen. 
     In solchen "Paket-Refinements" dürfen nur Paket-Objekte angesprochen 
     werden. Insbesondere ist es erlaubt, auch im letzten Paket ('main 
     packet') neben Prozeduren auch Refinements in beliebiger Reihenfolge zu 
     benutzen. Beispiel: 
 
        PROC kommando erkennung: 
           ... 
        END PROC kommando erkennung; 
 
        PROC kommando ausführung: 
           ... 
        END PROC kommando ausführung; 
 
        datei assoziieren; 
        saetze lesen und bearbeiten; 
        ende behandlung. 
 
        datei assoziieren: 
           FILE VAR f :: sequential file ...; 
           ... 
        saetze lesen und bearbeiten: 
           ... 
        ende behandlung: 
           put ("Ende der Bearbeitung"). 
 
     Dies ist die Schreibweise, die wir empfehlen. Will man aber Refinements 
     auch zwischen Prozeduren deklarieren, wird es etwas komplizierter. 
     Beispiel: 
 
        PROC a: 
        END PROC a; 
        ref;         (* Refinement Aufruf *) 
        PROC b: 
        END PROC b; 
                     (* Achtung: Semikolon, Punkt vor dem Refinement *) 
       .ref: . ;     (* Punkt, Semikolon nach dem Refinement *) 
        PROC c: 
        END PROC c 
 
     Paket-Refinements dürfen auch von Prozeduren benutzt werden, allerdings 
     sind dann auch die Sichtbarkeitsregeln zu beachten. D.h. die Paket- 
     Refinements, die in Prozeduren verwandt werden, dürfen dann auch nur 
     Paket-Objekte ansprechen. Die Aufnahme eines Refinements in das Inter- 
     face ist verboten. 
 
 
 
4. Interne Fehlermeldungen des Compilers
 
Interne Fehlermeldungen des Compilers#ie# erfolgen, wenn der ELAN-Übersetzer 
an implementationsbedingte Einschränkungen stößt. 
 
  Interne Fehlermeldungen erfolgen in der Form: 
 
    COMPILER ERROR: <zahl> 
 
wobei <zahl> folgende Werte annehmen kann: 
 
<zahl>   Bedeutung und eventuelle Abhilfe: 
 
 101      name table overflow: 
          Die Anzahl der Namen im Programm ist zu groß oder es wurden die 
          Anführungstriche eines TEXT-Denoters vergessen. Keine Abhilfe. 
 
 102      symbol table overflow: 
          Die Anzahl der deklarierten Objekte ist zu groß. 
          Abhilfe: Programm in Pakete unterteilen. 
 
 103      intermediate string overflow: 
          Abhilfe: Programm in Pakete unterteilen. 
 
 104      permanent table overflow 
          Zu viele Pakete insertiert. 
          Abhilfe: Keine (neue Task beginnen). 
 
 106      packet address overflow: 
          Insgesamt zu viele Adressen in Paketen ( > 64K ), d.h. ein Daten- 
          objekt ist zu groß. 
          Keine Abhilfe. 
 
 107      local data overflow: 
          Ein Datenobjekt in einer Prozedur ist zu groß ( > 32K ). 
          Abhilfe: 
          Datenobjekt in mehrere unterteilen. 
 
 204      compiler stack overflow: 
          Keine Abhilfe. 
 
 301      too many modules: 
          Zu viele Pakete, Prozeduren und Operatoren ( > 2048 ). 
          Keine Abhilfe. 
 
 303      applied table overflow: 
          siehe 304 
 
 304      too many labels: 
          In dem gerade übersetzten Modul (Prozedur, Operator oder Paket- 
          rumpf) werden vom Compiler zu viele Marken benötigt (mehr als 
          2000). Marken werden z.B. für die Codegenerierung von Auswahl 
          (IF ...) und Wiederholung (REP ...) gebraucht. Insbesondere bei 
          SELECT-Anweisungen werden 'casemax - casemin + 2' Marken 
          benötigt, wobei 'casemax' der INT-Wert des maximalen, 'casemin' 
          der des minimalen CASE-Wertes ist. Dieser Fehler ist somit fast 
          immer auf zu viele und/oder zu weit gespannte SELECT-Anweisungen 
          zurückzuführen. 
          Abhilfe: SELECT-Anweisungen über mehrere Prozeduren verteilen oder 
          Spannweiten verringern. 
 
 305      code overflow: 
          Der insgesamt erzeugte Code ist zu umfangreich ( > 256K ). 
          Keine Abhilfe. 
 
 306      packet data overflow: 
          Insgesamt zu viele Datenobjekte in den Paketen ( > 128K ). 
          Keine Abhilfe. 
 
 307      local data overflow: 
          Zu viele (lokale) Datenobjekte in einer Prozedur ( > 32K ). 
          Abhilfe: Prozedur in mehrere unterteilen, so daß die Datenobjekte 
          sich über mehrere Prozeduren verteilen. 
 
 308      module code overflow: 
          Ein Modul (Prozedur, Operator oder Paket-Initialisierungsteil) ist 
          zu groß ( > 7.5 KB Code). 
          Abhilfe: In mehrere Prozeduren oder Pakete zerlegen. 
 
Anmerkung: Fehlermeldungen, die hier nicht aufgeführt sind, weisen in der 
Regel auf ein fehlerhaftes Arbeiten des ELAN-Compilers hin. In diesem Fall 
bitten wir um die Einsendung des Programms (Listing, Quelldatei auf Diskette 
bei umfangreichen Programmen) und entsprechender Fehlermeldung. 
 
 
 
5. Übersicht über die Compiler-Kommandos 
 
check 
   BOOL PROC check 
   Zweck: Informationsprozedur. 
 
   PROC check on 
   Zweck: Einschalten der Generierung von Zeilennummern durch den 
          ELAN-Compiler. Voreingestellt ist 'check on'. 
 
   PROC check off 
   Zweck: Ausschalten der Generierung von Zeilennummern durch den 
          ELAN-Compiler. 
 
do 
   PROC do (TEXT CONST program) 
   Zweck: Übersetzen und Ausführen von 'program' von einem Programm aus. 
 
insert 
   PROC insert 
   Zweck: Insertieren eines oder mehrerer PACKETs. Der Programmtext muß sich 
          in einer Datei befinden. Der Dateiname ist der zuletzt benutzte 
          Dateiname. 
 
   PROC insert (TEXT CONST dateiname) 
   Zweck: Wie oben. Der Programmtext wird aus der Datei mit dem Namen 
          'dateiname' geholt. 
 
   PROC insert (THESAURUS CONST t) 
   Zweck: Insertieren aller PACKETs, die in den Dateien des Thesaurus 't' 
          enthalten sind. 
 
prot 
   BOOL PROC prot 
   Zweck: Informationsprozedur, ob 'prot' eingeschaltet ist. 
 
   PROC prot (TEXT CONST dateiname) 
   Zweck: Einschalten des Compilerlistings auf dem Bildschirm. Das Listing 
          wird gleichzeitig in die Datei 'dateiname' geschrieben. 
 
prot off 
   PROC prot off 
   Zweck: Ausschalten des Listings. 
 
run 
   PROC run 
   Zweck: Übersetzen und Ausführen eines ELAN-Programms. Der Programmtext 
          muß sich in einer Datei befinden. Der Dateiname ist der zuletzt 
          benutzte Dateiname. 
 
   PROC run (TEXT CONST dateiname) 
   Zweck: Wie oben. Der Programmtext wird aus der Datei mit dem Namen 
          'dateiname' geholt.