summaryrefslogtreecommitdiff
path: root/doc/programmer-manual/1.8.7/doc/programmierhandbuch.2a
blob: a2040915a73bc7c743701b1a6b3322f76075cb5b (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
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
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.