summaryrefslogtreecommitdiff
path: root/doc/programmer-manual/1.8.7/doc/programmierhandbuch.6
blob: ce11f6fb2bb40998f19db3ee42dc8e047e5acd07 (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
#pagenr("%",1)##setcount(1)##block##pageblock# 
#headeven# 
#center#EUMEL-Benutzerhandbuch 
#center#____________________________________________________________ 
 
#end# 
#headodd# 
#center#TEIL 6 : Das Archiv 'std.zusatz' 
#center#____________________________________________________________ 
 
#end# 
#bottomeven# 
#center#____________________________________________________________ 
6 - % #right#GMD 
#end# 
#bottomodd# 
#center#____________________________________________________________ 
GMD #right#6 - % 
#end# 
 
TEIL 6:  Das Archiv 'std.zusatz' 
 
Das Archiv 'std.zusatz' enthält Pakete, die nur bei Bedarf insertiert werden sollen.
Eine Einbindung in das EUMEL Grundsystem würde dieses ungebührlich unfangreich
machen. 
 
Das Archiv enthält zusätzliche Software für: 
 
- mathematische Operationen :  complex , longint , vector , matrix 
 
- Analyse                   :  reporter , referencer 
 
- Taschenrechnerfunktion 
  zur Editor-Erweiterung    :  TeCal , TeCal Auskunft 
 
 
#page# 

6.1.  Erweiterungen um 
      Mathematische Operationen
 
 
6.1.1  COMPLEX 
 
Das Packet COMPLEX erweitert das System um den Datentyp COMPLEX (komplexe
Zahlen) und Operationen auf komplexen Zahlen. Folgende Operationen stehen für
COMPLEX zur Verfügung: 
 
- Einfache Operatoren       :  := , = , <> , + ,- , * 
 
- Eingabe/Ausgabe           :  get , put 
 
- Denotierungsprozedur      :  complex , complex i , complex one , com­ 
                               plex zero 
 
- Komponenten               :  real part , imag part 
 
- bes. Funktionen           :  ABS , CONJ , phi , dphi , sqrt 
 
#page# 

COMPLEX Operationen 
 
 
'TYPE COMPLEX' 
   Komplexe Zahl, bestehend aud Realteil 're' und Imaginärteil 'im'. 
 
 
':=' 
   #on("b")#OP := (COMPLEX VAR a, COMPLEX CONST b) #off("b")# 
   Zuweisung. 
 
 
'=' 
   #on("b")#BOOL OP = (COMPLEX CONST a, b) #off("b")# 
   Vergleich von 'a' und 'b' auf Gleichheit. 
 
 
'<>' 
   #on("b")#BOOL OP <> (COMPLEX CONST a, b) #off("b")# 
   Vergleich von 'a' und 'b' auf Ungleichheit. 
 
 
'+' 
   #on("b")#COMPLEX OP + (COMPLEX CONST a, b) #off("b")# 
   Summe von 'a' und 'b'. 
 
 
'-' 
   #on("b")#COMPLEX OP - (COMPLEX CONST a, b) #off("b")# 
   Differenz von 'a' und 'b'. 
 
 
'*' 
   #on("b")#COMPLEX OP * (COMPLEX CONST a, b) #off("b")# 
   Multiplikation von 'a' mit 'b'. 
 
 
'/' 
   #on("b")#COMPLEX OP / (COMPLEX CONST a, b) #off("b")# 
   Division von 'a' mit 'b'. 
 
#page# 
'get' 
   #on("b")#PROC get (COMPLEX VAR a) #off("b")# 
   Einlesen eines komplexen Wertes vom Bildschirm in der Form zweier REAL-De­
   noter. Die Eingabe kann editiert werden. 
 
 
'put' 
   #on("b")#PROC put (COMPLEX CONST a) #off("b")# 
   Ausgabe eines komplexen Wertes auf dem Bildschirm in Form zweier REAL-
   Werte. Hinter jedem REAL-Wert wird ein Leerzeichen angefügt. 
 
 
'complex' 
   #on("b")#COMPLEX PROC complex (REAL CONST re, im) #off("b")# 
   Denotierungsprozedur. Angabe in kartesischen Koordinaten. 
 
 
'complex i' 
   #on("b")#COMPLEX PROC complex i #off("b")# 
   Denotierungsprozedur für den komplexen Wert '0.0 + i 1.0'. 
 
 
'complex one' 
   #on("b")#COMPLEX PROC complex one #off("b")# 
   Denotierungsprozedur für den komplexen Wert '1.0 + i 0.0'. 
 
 
'complex zero' 
   #on("b")#COMPLEX PROC complex zero #off("b")# 
   Denotierungsprozedur für den komplexen Wert '0.0 + i 0.0'. 
 
 
'imag part' 
   #on("b")#REAL PROC imag part (COMPLEX CONST number) #off("b")# 
   Liefert den Imaginärteil des komplexen Wertes 'number'. 
 
 
'real part' 
   #on("b")#REAL PROC real part (COMPLEX CONST number) #off("b")# 
   Liefert den Real-Teil des komplexen Wertes 'number'. 
 
 
'ABS' 
   #on("b")#REAL OP ABS (COMPLEX CONST x) #off("b")# 
   REAL-Betrag von 'x'. 
 
 
'CONJ' 
   #on("b")#COMPLEX OP CONJ (COMPLEX CONST number) #off("b")# 
   Liefert den konjugiert komplexen Wert von 'number'. 
 
 
'dphi' 
   #on("b")#REAL PROC dphi (COMPLEX CONST x) #off("b")# 
   Winkel von 'x' (Polardarstellung). 
 
 
'phi' 
   #on("b")#REAL PROC phi (COMPLEX CONST x) #off("b")# 
   Winkel von 'x' (Polardarstellung) in Radiant. 
 
 
'sqrt' 
   #on("b")#COMPLEX PROC sqrt (COMPLEX CONST x) #off("b")# 
   Wurzelfunktion für komplexe Werte. 
 
#page# 

6.1.2  LONGINT 
 
LONGINT ist ein Datentyp, für den (fast) alle Prozeduren und Operatoren des Daten­
typs INT implementiert wurden. LONGINT unterscheidet sich von INT dadurch, daß
erheblich größere Werte darstellbar sind. 
 
Für den Datentyp LONGINT stehen folgende Operationen zur Verfügung: 
 
- Operatoren                :  := , = , <> , < , <= ,> , >= , + , - , * , 
                               ** , 
                               ABS , DECR , DIV , INCR , MOD , SIGN 
 
- Eingabe/Ausgabe           :  get , put 
 
 
- Math. Prozeduren          :  abs , int , longint , max , max logint , min , 
                               random , sign , text , zero 
 
 
 
LONGINT-Operationen 
 
 
'TYPE LONGINT' 
   Datentyp 
 
 
':=' 
   #on("b")#OP := (LONGINT VAR links, LONGINT CONST rechts) : #off("b")# 
   Zuweisungsoperator 
 
 
'= ' 
   #on("b")#BOOL OP = (LONGINT CONST links, rechts) #off("b")# 
   Vergleichen zweier LONGINTs auf Gleichheit. 
 
 
'<>' 
   #on("b")#BOOL OP <> (LONGINT CONST links, rechts) #off("b")# 
   Vergleichen zweier LONGINTs auf Ungleichheit. 
 
 
'< ' 
   #on("b")#BOOL OP < (LONGINT CONST links, rechts) #off("b")# 
   Vergleichen zweier LONGINTs auf kleiner. 
 
 
'<=' 
   #on("b")#BOOL OP <= (LONGINT CONST links, rechts) #off("b")# 
   Vergleichen zweier LONGINTs auf kleiner gleich. 
 
 
'> ' 
   #on("b")#BOOL OP > (LONGINT CONST links, rechts) #off("b")# 
   Vergleichen zweier LONGINTs auf größer. 
 
 
'>=' 
   #on("b")#BOOL OP >= (LONGINT CONST links, rechts) #off("b")# 
   Vergleichen zweier LONGINTs auf größer gleich. 
 
 
'+ ' 
   #on("b")#LONGINT OP + (LONGINT CONST argument) #off("b")# 
   Monadischer Operator. Ohne Wirkung. 
 
   #on("b")#LONGINT OP + (LONGINT CONST links, rechts) #off("b")# 
   Addition zweier LONGINTs. 
 
 
'- ' 
   #on("b")#LONGINT OP - (LONGINT CONST argument) #off("b")# 
   Vorzeichenumkehrung. 
 
   #on("b")#LONGINT OP - (LONGINT CONST links, rechts) #off("b")# 
   Subtraktion zweier LONGINTs. 
 
 
'* ' 
   #on("b")#LONGINT OP * (LONGINT CONST links, rechts) #off("b")# 
   Multiplikation von zwei LONGINTs. 
 
 
'**' 
   #on("b")#LONGINT OP ** (LONGINT CONST argument, exponent) #off("b")# 
   Exponentiation zweier LONGINTs mit positivem Exponenten. 
 
   FEHLER : 
            LONGINT OP ** : negative exponent 
            Der 'exponent' muß >= 0 sein. 
            0 ** 0 is not defined 
            'argument' und 'exponent' dürfen nicht gleich 0 sein. 
 
 
   #on("b")#LONGINT OP ** (LONGINT CONST argument, INT CONST exponent)#off("b")# 
   Exponentiation eines LONGINT mit positiven INT Exponenten. 
 
   FEHLER : 
            LONGINT OP ** : negative exponent 
            Der 'exponent' muß >= 0 sein. 
            0 ** 0 is not defined 
            'argument' und 'exponent' dürfen nicht gleich 0 sein. 
 
'ABS' 
   #on("b")#LONGINT OP ABS (LONGINT CONST argument) #off("b")# 
   Absolutbetrag eines LONGINT. 
 
 
'DECR' 
   #on("b")#OP DECR (LONGINT VAR resultat, LONGINT CONST ab) #off("b")# 
   resultat := resultat - ab 
 
 
'DIV' 
   #on("b")#LONGINT OP DIV (LONGINT CONST links, rechts) #off("b")# 
   Division zweier LONGINTs. 
 
   FEHLER : 
             Division durch 0 
            'rechts' muß <> 0 sein. 
 
 
'INCR' 
   #on("b")#LONGINT OP INCR (LONGINT VAR resultat, LONGINT CONST dazu)#off("b")# 
   resultat := resultat + dazu 
 
 
 
'MOD' 
   #on("b")#LONGINT OP MOD (LONGINT CONST links, rechts) #off("b")# 
   Modulo-Funktion für LONGINTs. Der Rest einer LONGINT-Division wird ermit­
   telt. 
 
   FEHLER : 
           text (links) + 'MOD 0' 
           'rechts' muß ungleich null sein. 
 
 
'SIGN' 
   #on("b")#INT OP SIGN (LONGINT CONST longint) #off("b")# 
   Feststellen des Vorzeichens von 'longint'. Liefert: 
 
 
           0 wenn 'longint' = 0, 
           1 wenn 'longint' > 0, 
          -1 wenn 'longint' < 0. 
 
 
#page# 
'get' 
   #on("b")#PROC get (LONGINT VAR zahl) #off("b")# 
   Eingabe eines LONGINTs vom Terminal. 
 
   #on("b")#PROC get (FILE VAR file, LONGINT VAR zahl) #off("b")# 
   Einlesen von 'zahl' aus der sequentiellen Datei 'file'. Die Datei muß mit 'input'
   assoziiert sein (vergl. 'sequential file'). 
 
   FEHLER : 
           Datei zu 
           Leseversuch nach Daateiende 
           Leseversuch auf output-FILE 
 
 
'put' 
   #on("b")#PROC put (LONGINT CONST longint) #off("b")# 
   Ausgabe eines LONGINTs auf dem Bildschirm. Anschließend wird ein Leerzeichen
   ausgegeben. Hardwareabhängig sind die Aktionen, wenn eine Ausgabe über die
   Bildschirmzeilengrenze vorgenommen wird. Meist wird jedoch die Ausgabe auf der
   nächsten Zeile fortgesetzt. 
 
   #on("b")#PROC put (FILE VAR file, LONGINT CONST zahl) #off("b")# 
   Ausgabe von 'zahl' in die sequentielle Datei 'file'. 'file' muß mit 'output' assoziiert
   sein. 
 
   FEHLER : 
           Datei zu 
           Schreibversuch auf input-FILE 
#page# 
'abs' 
   #on("b")#LONGINT PROC abs (LONGINT CONST argument) #off("b")# 
   Absolutbetrag eines LONGINT. 
 
 
'int' 
   #on("b")#INT PROC int (LONGINT CONST longint) #off("b")# 
   Konvertierung von LONGINT nach INT. 
 
   FEHLER : 
           integer overflow 
           'longint' ist größer als 'maxint'. 
 
 
'longint' 
   #on("b")#LONGINT PROC longint (INT CONST int) #off("b")# 
   Konvertierung von 'int' nach LONGINT. 
 
   #on("b")#LONGINT PROC longint (TEXT CONST text) #off("b")# 
   Konvertierung von 'text' nach LONGINT. 
 
 
'max' 
   #on("b")#LONGINT PROC max (LONGINT CONST links, rechts) #off("b")# 
   Liefert das Maximum zweier LONGINTs. 
 
 
'maxlongint' 
   #on("b")#LONGINT PROC max longint #off("b")# 
   Liefert größten LONGINT Wert. 
 
 
'min' 
   #on("b")#LONGINT PROC min (LONGINT CONST links, rechts) #off("b")# 
   Liefert das Minimum zweier LONGINTs. 
 
 
'random' 
   #on("b")#LONGINT PROC random (LONGINT CONST lower bound, upper bound)#off("b")# 
   Pseudo-Zufallszahlen-Generator im Intervall 'lower bound' und 'upper bound'
   einschließlich. Es handelt sich hier um den 'LONGINT Random Generator'. 
 
 
'sign' 
   #on("b")#INT PROC sign (LONGINT CONST longint) #off("b")# 
   Feststellen des Vorzeichens von 'longint'. Liefert: 
 
 
           0 wenn 'longint' = 0, 
           1 wenn 'longint' > 0, 
          -1 wenn 'longint' < 0. 
 
 
 
'text' 
   #on("b")#TEXT PROC text (LONGINT CONST longint) #off("b")# 
   Konvertierung von 'longint' nach TEXT. 
 
   #on("b")#TEXT PROC text (LONGINT CONST longint, INT CONST laenge) #off("b")# 
   Konvertierung von 'longint' nach TEXT. Die Anzahl der Zeichen soll 'laenge'
   betragen. Für 
 
 
           LENGTH (text (longint)) < laenge 
 
 
   werden die Zeichen rechtsbündig in einen Text mit der Länge 'laenge' eingetra­
   gen. Ist der daraus entstehende TEXT kleiner als 'laenge', werden die an 'laenge'
   fehlenden Zeichen im TEXT mit Leerzeichen aufgefüllt. Für 
 
 
          LENGTH (text (longint)) > laenge 
 
 
   wird ein Text mit der Länge 'laenge' geliefert, der mit '*'-Zeichen gefüllt ist. 
 
 
'zero' 
   #on("b")#LONGINT PROC zero #off("b")# 
   Liefert LONGINT Wert Null. 
 
 
#page# 

6.1.3  VECTOR 
 
Der Datentyp VECTOR erlaubt Operationen auf Vektoren aus Elementen vom Typ
REAL. Im Gegensatz zur Struktur 'ROW m REAL' muß die Anzahl der Elemente nicht
zur Übersetzungszeit deklariert werden, sondern kann zur Laufzeit festgelegt werden.
Somit kann eine zur Übersetzungszeit unbekannte Anzahl von REALs bearbeitet
werden, wobei nur soviel Speicherplatz wie nötig verwendet wird. Die maximale Größe
eines VECTOR beträgt 4000 Elemente. 
 
Der in den Operationen ':=', 'idn' und 'vector' benutzte Datentyp INITVECTOR wird
nur intern gehalten. Er dient der Speicherplatzersparnis bei der Initialisierung. 
 
 
- Operatoren                :  := , = , <> , + , - , * , / 
                               LENGTH , SUB 
 
- Eingabe/Ausgabe           :  get , put 
 
- Besondere Vector-         :  length , nilvector , norm , vector , replace 
  Operationen 
 
#page# 
':=' 
   #on("b")#OP := (VECTOR VAR ziel, VECTOR CONST quelle) #off("b")# 
   Zuweisung. Nach der Zuweisung gilt auch 
 
 
           length (quelle) = length (ziel) 
 
 
   d.h. der linke Operand besitzt nach der Zuweisung genauso viele Elemente wie
   'quelle', unabhängig davon, ob 'ziel' vor der Zuweisung mehr oder weniger Ele­
   mente als 'quelle' besaß. Beispiel: 
 
 
           VECTOR VAR y :: vector (10, 1.0), 
                      z :: vector (15, 2.0); 
                ... 
           y := z; (* length (y) liefert nun 15 ! *) 
 
 
   #on("b")#OP := (VECTOR VAR ziel, INITVECTOR CONST quelle) #off("b")# 
   Dient zur Initialisierung eines VECTORs. Beispiel: 
 
 
           VECTOR VAR x :: vector (17); 
 
 
   'vector' erzeugt ein Objekt vom Datentyp INITVECTOR. Dieses Objekt braucht
   nicht soviel Speicherplatz wie ein VECTOR-Objekt. Dadurch wird vermieden, daß
   nach erfolgter Zuweisung nicht ein durch 'vector' erzeugtes Objekt auf dem Heap
   unnötig Speicherplatz verbraucht. 
 
 
'=' 
   #on("b")#BOOL OP = (VECTOR CONST a, b) #off("b")# 
   Vergleich zweier Vektoren. Der Operator liefert FALSE, wenn die Anzahl der
   Elemente von 'a' und 'b' ungleich ist oder wenn zwei Elemente mit gleichem
   Index ungleich sind. Beispiel: 
 
 
           VECTOR VAR x :: vector (10, 1.0), 
                      y :: vector (15, 2.0), 
                      z :: vector (10, 1.0); 
                   ... x = y ... (* FALSE *) 
                   ... x = z ... (* TRUE  *) 
 
 
'<>' 
   #on("b")#BOOL OP <> (VECTOR CONST a, b) #off("b")# 
   Vergleich zweier Vektoren auf Ungleichheit (NOT (a = b)). 
 
 
'+' 
   #on("b")#VECTOR OP + (VECTOR CONST a) #off("b")# 
   Monadisches '+' für VECTOR. Keine Auswirkung. 
 
   #on("b")#VECTOR OP + (VECTOR CONST a, b) #off("b")# 
   Elementweise Addition der Vektoren 'a' und 'b'. Beispiel: 
 
 
           VECTOR VAR x, (* 'x' hat undefinierte Länge *) 
                      a :: vector (10, 1.0), 
                      b :: vector (10, 2.0); 
                 ... 
           x := a + b; (* 'x' hat nun 10 Elemente mit Werten'3.0'
           *) 
 
   FEHLER : 
           VECTOR OP + : LENGTH a <> LENGTH b 
           'a' und 'b' haben nicht die gleiche Anzahl von Elementen. 
 
 
'-' 
   #on("b")#VECTOR OP - (VECTOR CONST a) #off("b")# 
   Monadisches '-'. 
 
   #on("b")#VECTOR OP - (VECTOR CONST a, b) #off("b")# 
   Elementweise Subtraktion der Vektoren 'a' und 'b'. 
 
   FEHLER : 
           VECTOR OP - : LENGTH a <> LENGTH b 
           'a' und 'b' haben nicht die gleiche Anzahl von Elementen. 
 
'*' 
   #on("b")#REAL OP * (VECTOR CONST a, b) #off("b")# 
   Skalarprodukt zweier Vektoren. Liefert die Summe der elementweisen Multiplika­
   tion der Vektoren 'a' und 'b'. Beachte eventuelle Rundungsfehler! Beispiel: 
 
 
           REAL VAR a; 
           VECTOR VAR b :: vector (10, 2.0), 
                      c :: vector (10, 2.0); 
                 ... 
           a := b * c; (* 40.0 *) 
 
   FEHLER : 
           REAL OP * : LENGTH a <> LENGTH b 
           'a' und 'b' haben nicht die gleiche Anzahl von Elementen. 
 
   #on("b")#VECTOR OP * (VECTOR CONST a, REAL CONST s) #off("b")# 
   Multiplikation des Vektors 'a' mit dem Skalar 's'. 
 
   #on("b")#VECTOR OP * (REAL CONST s, VECTOR CONST a) #off("b")# 
   Multiplikation des Skalars 's' mit dem Vektor 'a'. 
 
 
'/' 
   #on("b")#VECTOR OP / (VECTOR CONST a, REAL CONST s) #off("b")# 
   Division des Vektors 'a' durch den Skalar 's'. Beispiel: 
 
 
           VECTOR VAR a, (* 'a' hat undefinierte Laenge *) 
                      b :: vector (10, 4.0); 
                ... 
           a := b / 2.0; 
           (* 'a' hat nun 10 Elemente mit Werten '2.0' *) 
 
 
 
'LENGTH' 
   #on("b")#INT OP LENGTH (VECTOR CONST a) #off("b")# 
   Liefert die Anzahl der Elemente von 'a'. 
 
 
'SUB' 
   #on("b")#REAL OP SUB (VECTOR CONST v, INT CONST i) #off("b")# 
   Liefert das 'i'-te Element von 'v'. 
 
   FEHLER : 
           OP SUB : subscript overflow 
           Der Index 'i' liegt außerhalb des Vektors (i > LENGTH v). 
           OP SUB : subscript underflow 
           Der Index 'i' liegt außerhalb des Vektors (i < 1). 
 
#page# 
'get' 
   #on("b")#PROC get (VECTOR VAR a, INT CONST l) #off("b")# 
   Einlesen der Elemente von 'a' vom Terminal, wobei 'l' die Anzahl der Elemente
   angibt. 
 
   FEHLER : 
           PROC get : size <= 0 
           Die angeforderte Elementanzahl 'l' muß > 0 sein. 
 
 
'put' 
   #on("b")#PROC put (VECTOR CONST v) #off("b")# 
   Ausgabe der Werte der Elemente von 'v' auf dem Terminal. 
 
 
#page# 
'length' 
   #on("b")#INT PROC length (VECTOR CONST a) #off("b")# 
   Liefert die Anzahl der Elemente von 'a'. Beispiel: 
 
 
           VECTOR VAR a :: vector (10, 1.0), 
                      b :: vector (15, 2.0); 
                ... 
            ... length (a) ... (* 10 *) 
            ... length (b) ... (* 15 *) 
 
 
 
'nilvector' 
   #on("b")#INITVECTOR PROC nilvector #off("b")# 
   Erzeugen eines Vektors mit einem Element mit dem Wert '0.0'. 
 
 
'norm' 
   #on("b")#REAL PROC norm (VECTOR CONST v) #off("b")# 
   Euklidische Norm (Wurzel aus der Summe der Quadrate der Elemente). 
 
 
 
'replace' 
   #on("b")#PROC replace (VECTOR VAR v, INT CONST i, REAL CONST r)#off("b")# 
   Zuweisung des i-ten Elementes von 'v' mit dem Wert von 'r'. Beispiel: 
 
 
           VECTOR VAR v :: ...; 
               ... 
           replace (v, 13, 3.14); 
           (* Das 13. Element von 'v' bekommt den Wert '3.14' *) 
 
   FEHLER : 
           PROC replace : subscript overflow 
           Der Index 'i' liegt außerhalb des Vektors (i > LENGTH v). 
           PROC replace : subscript underflow 
           Der Index 'i' liegt außerhalb des Vektors (i < 1). 
 
 
'vector' 
   #on("b")#INITVECTOR PROC vector (INT CONST l) #off("b")# 
   Erzeugen eines Vektors mit 'l' Elementen. Ein INITVECTOR-Objekt benötigt nicht
   soviel Speicherplatz wie ein VECTOR-Objekt. Die Elemente werden mit dem
   Wert '0.0' initialisiert. 
 
   FEHLER : 
           PROC vector : size <= 0 
           Die angeforderte Elementanzahl 'l' muß > 0 sein. 
 
   #on("b")#INITVECTOR PROC vector (INT CONST l, REAL CONST value)#off("b")# 
   Erzeugen eines Vektors mit 'l' Elementen. Ein INITVECTOR-Objekt benötigt nicht
   soviel Speicherplatz wie ein VECTOR-Objekt. Die Elemente werden mit dem
   Wert 'value' initialisiert. Beispiel: 
 
 
           VECTOR VAR v := vector (17, 3.14159); 
           (* 'v' hat 17 Elemente mit den Wert '3.14159' *) 
 
    FEHLER : 
           PROC vector : size <= 0 
           Die angeforderte Elementanzahl 'l' muß > 0 sein. 
 
#page# 

6.1.4  MATRIX

Der Datentyp MATRIX erlaubt Operationen auf m x n Matrizen. Im Gegensatz zur
Struktur 'ROW m ROW n REAL' muß die Anzahl der Elemente nicht zur Überset­
zungszeit deklariert werden, sondern kann zur Laufzeit festgelegt werden. Somit kann
eine zur Übersetzungszeit unbekannte Anzahl von REALs bearbeitet werden, wobei
nur soviel Speicherplatz wie nötig verwendet wird. Die maximale Größe einer MATRIX
beträgt 4000 Elemente. 
 
Der in den Operationen ':=', 'idn' und 'matrix' benutzte Datentyp INITMATRIX wird
nur intern gehalten. Er dient der Speicherplatzersparnis bei der Initialisierung. 
 
 
- Operatoren                :  := , = , <> , + , - , * 
                               COLUMNS , DET , INV , ROWS , TRANSP , 
 
- Eingabe/Ausgabe           :  get , put 
 
- Besondere Matrix-         :  column , idn , matrix , row , sub 
  Operationen                  transp , 
                               replace column , replace element , 
                               replace row 
 
 
 
#page# 
':=' 
   #on("b")#OP := (MATRIX VAR l, MATRIX CONST r) #off("b")# 
   Zuweisung von 'r' auf 'l'. Die MATRIX 'l' bekommt u.U. eine neue Anzahl von
   Elementen. Beispiel: 
    
 
           MATRIX VAR a :: matrix (3, 4, 0.0), 
                      b :: matrix (5, 5, 3.0); 
                          ... 
           a := b; (* 'a' hat jetzt 5 x 5 Elemente *) 
 
 
   #on("b")#OP := (MATRIX VAR l, INITMATRIX CONST r) #off("b")# 
   Dient zur Initialisierung einer Matrix. Beispiel: 
 
 
           MATRIX VAR x :: matrix (17, 4); 
 
 
   'matrix' erzeugt ein Objekt vom Datentyp INITMATRIX. Dieses Objekt braucht
   nicht soviel Speicherplatz wie ein MATRIX-Objekt. Dadurch wird vermieden, daß
   nach erfolgter Zuweisung nicht ein durch 'matrix' erzeugtes Objekt auf dem Heap
   unnötig Speicherplatz verbraucht. 
 
'=' 
   #on("b")#BOOL OP = (MATRIX CONST l, r) #off("b")# 
   Vergleich zweier Matrizen. Der Operator '=' liefert FALSE, wenn die Anzahl
   Spalten oder Reihen der Matrizen 'l' und 'r' ungleich ist und wenn mindestens ein
   Element mit gleichen Indizes der zwei Matrizen ungleiche Werte haben. Beispiel: 
 
 
           MATRIX VAR a :: matrix (3, 3), 
                      b :: matrix (3, 3, 1.0), 
                      c :: matrix (4, 4); 
                 ... a = b ... 
           (* FALSE wegen ungleicher Werte   *) 
                 ... a = c ... 
           (* FALSE wegen ungleicher Groesse *) 
                 ... b = c ... 
           (* FALSE wegen ungleicher Groesse *) 
 
 
 
'<>' 
   #on("b")#BOOL OP <> (MATRIX CONST l, r) #off("b")# 
   Vergleich der Matrizen 'l' und 'r' auf Ungleichheit. 
 
 
'+' 
   #on("b")#MATRIX OP + (MATRIX CONST m) #off("b")# 
   Monadisches '+'. Keine Auswirkungen. 
 
   #on("b")#MATRIX OP + (MATRIX CONST l, r) #off("b")# 
   Addition zweier Matrizen. Die Anzahl der Reihen und der Spalten muß gleich sein.
   Beispiel: 
 
           MATRIX VAR a :: matrix (3, 43, 1.0), 
                      b :: matrix (3, 43, 2.0), 
                           summe; 
                      summe := a + b; 
           (* Alle Elemente haben den Wert '3.0' *) 
 
 
     FEHLER: 
           MATRIX OP + : COLUMNS l <> COLUMNS r 
           Die Anzahl der Spalten von 'l' und 'r' sind nicht gleich. 
           MATRIX OP + : ROWS l <> ROWS r 
           Die Anzahl der Zeilen von 'l' und 'r' sind nicht gleich. 
 
 
'-' 
   #on("b")#MATRIX OP - (MATRIX CONST m) #off("b")# 
   Monadisches Minus. Beispiel: 
 
 
           MATRIX VAR a :: matrix (3, 4, 10.0) 
           a := - a; (* Alle Elemente haben den Wert '- 10.0' *) 
 
 
   #on("b")#MATRIX OP - (MATRIX CONST l, r) #off("b")# 
   Subtraktion zweier Matrizen. Die Anzahl der Reihen und Spalten muß gleich sein. 
 
   FEHLER: 
           MATRIX OP - : COLUMNS l <> COLUMNS r 
           Die Anzahl der Spalten von 'l' und 'r' sind nicht gleich. 
           MATRIX OP - : ROWS l <> ROWS r 
           Die Anzahl der Zeilen von 'l' und 'r' sind nicht gleich. 
 
'*' 
   #on("b")#MATRIX OP * (REAL CONST r, MATRIX CONST m) #off("b")# 
   Multiplikation einer Matrix 'm' mit einem Skalar 'r'. Beispiel: 
 
 
           MATRIX VAR a :: matrix (3, 4, 2.0); 
                ... 
           a := 3 * a; (* Alle Elemente haben den Wert '6.0' *) 
 
 
   #on("b")#MATRIX OP * (MATRIX CONST m, REAL CONST r) #off("b")# 
   Multiplikation einer Matrix 'm' mit einem Skalar 'r'. 
 
   #on("b")#MATRIX OP * (MATRIX CONST l, r) #off("b")# 
   Multiplikation zweier Matrizen. Die Anzahl der Spalten von 'l' und die Anzahl der
   Zeilen von 'r' müssen gleich sein. Beispiel: 
 
 
           MATRIX VAR a :: matrix (3, 4, 2.0), 
                      b :: matrix (4, 2, 3.0), 
                      produkt; 
           produkt := a * b; 
           (* Alle Elemente haben den Wert '24.0' *) 
 
 
   FEHLER : 
           MATRIX OP * : COLUMNS l <> ROWS r 
           Die Anzahl der Spalten von 'l' muß mit der Anzahl der Zeilen von 'r'
           übereinstimmen. 
 
   #on("b")#VECTOR OP * (VECTOR CONST v, MATRIX CONST m) #off("b")# 
   Multiplikation des Vektors 'v' mit der Matrix 'm'. 
 
   FEHLER : 
            VECTOR OP * : LENGTH v <> ROWS m 
            Die Anzahl der Elemente von 'v' stimmt nicht mit den Anzahl der Zeilen
            von 'm' überein. 
 
   #on("b")#VECTOR OP * (MATRIX CONST m, VECTOR CONST v) #off("b")# 
   Multiplikation der Matrix 'm' mit dem Vektor 'v'. 
 
   FEHLER : 
            VECTOR OP * : COLUMNS m <> LENGTH v 
            Die Anzahl der Spalten von 'm' stimmt nicht mit der Anzahl der Ele­
            menten von 'v' überein. 
 
 
'COLUMNS' 
   #on("b")#INT OP COLUMNS (MATRIX CONST m) #off("b")# 
   Liefert die Anzahl der Spalten von 'm'. Beispiel: 
 
 
           MATRIX VAR a :: matrix (3, 4), 
                      b :: matrix (7, 10); 
           put (COLUMNS a); (* 4 *) 
           put (COLUMNS b); (* 10 *) 
 
 
 
'DET' 
   #on("b")#REAL OP DET (MATRIX CONST m) #off("b")# 
   Es wird der Wert der Determinanten von 'm' geliefert. 
 
   FEHLER : 
           OP DET : no square matrix 
           Die Matrix ist nicht quadratisch, d.h. ROWS m <> COLUMNS m 
 
 
'INV' 
   #on("b")#MATRIX OP INV (MATRIX CONST m) #off("b")# 
   Liefert als Ergebnis die Inverse von 'm' (Achtung: starke Rundungsfehler möglich). 
 
   FEHLER: 
           OP INV : no square matrix 
           Die Matrix 'm' ist nicht quadratisch, 
           d.h. ROWS m <> COLUMNS m 
           OP INV : singular matrix 
           Die Matrix ist singulär. 
 
 
'ROWS' 
   #on("b")#INT OP ROWS (MATRIX CONST m) #off("b")# 
   Liefert die Anzahl der Zeilen von 'm'. Beispiel: 
 
 
           MATRIX VAR a :: matrix (3, 4), 
                      b :: matrix (7, 10); 
                ... 
           put (ROWS a); (* 3 *) 
           put (ROWS b); (* 7 *) 
 
 
 
'TRANSP' 
   #on("b")#MATRIX OP TRANSP (MATRIX CONST m) #off("b")# 
   Liefert als Ergebnis die transponierte Matrix 'm'. 
 
#page# 
'get' 
   #on("b")#PROC get (MATRIX VAR m, INT CONST rows, columns) #off("b")# 
   Einlesen von Werten für die Matrix 'm' vom Terminal mit 'rows'-Zeilen und
   'columns'-Spalten. 
 
 
'put' 
   #on("b")#PROC put (MATRIX CONST m) #off("b")# 
   Ausgabe der Werte einer Matrix auf dem Terminal. 
#page# 
'column' 
   #on("b")#VECTOR PROC column (MATRIX CONST m, INT CONST i) #off("b")# 
   Die 'i'-te Spalte von 'm' wird als VECTOR mit 'ROWS m' Elementen geliefert.
   Beispiel: 
 
 
           MATRIX CONST a :: matrix (3, 4); 
           VECTOR VAR b   :: column (a, 1); 
           (* 'b' hat drei Elemente mit den Werten '0.0' *) 
 
   FEHLER: 
           PROC column : subscript overflow 
           Der Index 'i' liegt außerhalb der Matrix 'm' (i > COLUMNS m). 
           PROC column : subscript underflow 
           Der Index 'i' liegt außerhalb der Matrix 'm' (i < 1). 
 
'idn' 
   #on("b")#INITMATRIX PROC idn (INT CONST size) #off("b")# 
   Erzeugen einer Einheitsmatrix vom Datentyp INITMATRIX. Beispiel: 
 
 
           MATRIX VAR a :: idn (10); 
           (* Erzeugt eine Matrix mit 10 x 10 Elementen, deren
            Werte '0.0' sind, mit der Ausnahme der Diagonalele­
            mente, die den Wert '1.0' haben.*) 
 
   FEHLER : 
           PROC idn : size <= 0 
           Die angeforderte 'size' Anzahl Spalten oder Zeilen muß > 0 sein. 
 
 
'matrix' 
   #on("b")#INITMATRIX PROC matrix (INT CONST rows, columns) #off("b")# 
   Erzeugen eines Datenobjekts vom Datentyp INITMATRIX mit 'rows' Zeilen und
   'columns' Spalten. Alle Elemente werden mit dem Wert '0.0' initialisiert. Beispiel: 
 
 
           MATRIX CONST :: matrix (3, 3); 
 
   FEHLER: 
           PROC matrix : rows <= 0 
           Die angeforderte Zeilenanzahl 'rows' muß > 0 sein. 
           PROC matrix : columns <= 0 
           Die angeforderte Spaltenanzahl 'columns' muß > 0 sein. 
 
   #on("b")#INITMATRIX PROC matrix (INT CONST rows, columns, REAL CONST value)#off("b")# 
   Erzeugen eines Datenobjekts vom Datentyp MATRIX mit 'rows' Zeilen und 'co­
   lumns' Spalten. Alle Elemente der erzeugten MATRIX werden mit dem Wert
   'value' initialisiert. Beispiel: 
 
 
           MATRIX CONST :: matrix (3, 3, 3.14); 
 
   FEHLER: 
           PROC matrix : rows <= 0 
           Die angeforderte Zeilenanzahl 'rows' muß > 0 sein. 
           PROC matrix : columns <= 0 
           Die angeforderte Spaltenanzahl 'columns' muß > 0 sein. 
 
 
'row' 
   #on("b")#VECTOR PROC row (MATRIX CONST m, INT CONST i) #off("b")# 
   Die 'i'-te Reihe von 'm' wird als VECTOR mit 'COLUMNS m' Elementen gelie­
   fert. Beispiel: 
 
 
           MATRIX CONST a :: matrix (3, 4); 
           VECTOR VAR b   :: row (a, 1); 
           (* 'b' hat vier Elemente mit den Werten '0.0'*) 
 
   FEHLER: 
           PROC row : subscript overflow 
           Der Index 'i' liegt außerhalb der Matrix 'm' (i > ROWS m). 
           PROC row : subscript underflow 
           Der Index 'i' liegt außerhalb der Matrix 'm' (i < 1). 
 
 
'sub' 
   #on("b")#REAL PROC sub (MATRIX CONST m, INT CONST row, column) #off("b")# 
   Liefert den Wert eines Elementes von 'm', welches durch die Indizes 'row' und
   'column' bestimmt wird. Beispiel: 
 
 
           MATRIX VAR m :: matrix (5, 10, 1.0); 
           put (sub (m, 3, 7)); 
 
   FEHLER: 
           PROC sub : row subscript overflow 
           Der Index 'row' liegt außerhalb von 'm' (row > ROWS m). 
           PROC sub : row subscript underflow 
           Der Index 'row' liegt außerhalb von 'm' (row < 1). 
           PROC sub : column subscript overflow 
           Der Index 'column' liegt außerhalb von 'm' (column > ROWS m). 
           PROC sub : row subscript underflow 
           Der Index 'column' liegt außerhalb von 'm' (column < 1). 
 
 
'transp' 
   #on("b")#PROC transp (MATRIX VAR m) #off("b")# 
   Transponieren der Matrix 'm', wobei kaum zusätzlicher Speicherplatz benötigt
   wird. 
 
#page# 
'replace column' 
   #on("b")#PROC replace column (MATRIX VAR m, INT CONST column index, VECTOR
                        CONST column value)  #off("b")# 
   Ersetzung der durch 'column index' definierten Spalte in der MATRIX 'm' durch
   den VECTOR 'column value'. Beispiel: 
 
 
           MATRIX VAR a :: matrix (3, 5, 1.0); 
           VECTOR VAR b :: vector (3, 2.0); 
                 ... 
           replace column (a, 2, b); 
           (* Die zweite Spalte von 'a' wird durch die Werte von
              'b' ersetzt *) 
 
   FEHLER: 
           PROC replace column : LENGTH columnvalue <> ROWS m 
           Die Anzahl der Zeilen der MATRIX 'm' stimmt nicht mit der Anzahl der
           Elemente von 'columnvalue' überein. 
           PROC replace column : column subscript overflow 
           Der Index 'columnindex' liegt außerhalb von 'm' 
           (columnindex > COLUMNS m). 
           PROC sub : column subscript underflow 
           Der Index 'columnindex' liegt außerhalb von 'm' (columnindex < 1). 
 
 
'replace element' 
   #on("b")#PROC replace element (MATRIX VAR m , INT CONST row, column, 
                        REAL CONST value) #off("b")# 
   Ersetzung eines Elementes von 'm' in der 'row'-ten Zeile und 'column'-ten
   Spalte durch den Wert 'value'. Beispiel: 
 
 
           MATRIX VAR a :: matrix (5, 5); 
                 ... 
           replace element (1, 1, 3.14159); 
 
   FEHLER: 
           PROC replace element : row subscript overflow 
           Der Index 'row' liegt außerhalb von 'm' (row > ROWS m). 
           PROC replace element : row subscript underflow 
           Der Index 'row' liegt außerhalb von 'm' (row < 1). 
           PROC replace element : column subscript overflow 
           Der Index 'column' liegt außerhalb von 'm' (column > COLUMNS m). 
           PROC replace element : row subscript underflow 
           Der Index 'column' liegt außerhalb von 'm' (column < 1). 
 
 
'replace row' 
   #on("b")#PROC replace row (MATRIX VAR m, INT CONST rowindex, 
                    VECTOR CONST rowvalue) #off("b")# 
   Ersetzung der Reihe 'rowindex' in der MATRIX 'm' durch den VECTOR 'rowvalue'.
   Beispiel: 
 
 
           MATRIX VAR a :: matrix (3, 5, 1.0); 
           VECTOR VAR b :: vector (5, 2.0); 
                 ... 
           replace row (a, 2, b); 
           (* Die 2. Reihe von 'a' wird durch Werte von 'b'ersetzt *) 
 
   FEHLER: 
           PROC replace row : LENGTH rowvalue <> COLUMNS m 
           Die Anzahl der Spalten der MATRIX 'm' stimmt nicht mit der Anzahl der
           Elemente von 'rowvalue' überein. 
           PROC replace row : row subscript overflow 
           Der Index 'rowindex' liegt außerhalb von 'm' 
           (rowindex > ROWS m). 
           PROC sub : row subscript underflow 
           Der Index 'rowindex' liegt außerhalb von 'm' (rowindex < 1). 

6.2  Programmanalyse 
 
Das Packet 'reporter' ermöglicht: 
 
a) Ablaufinformationen ("trace"); 
b) #ib#Häufigkeitszählung#ie# ("frequency count"); 
c) Programmunterbrechung bei Nichterfüllung einer Bedingung ("#ib#assertion#ie#"). 
 
 
'Installation' 
Das Programm befindet sich in der Datei 'reporter' und kann wie üblich insertiert
werden. Jedoch muß es mit 'check off' übersetzt werden, damit keine Zeilennummern
für 'reporter' generiert werden. Dies ist notwendig, damit die Zeilennummern des zu
testenden Programms nicht mit den Zeilennummern des Programms 'reporter' ver­
wechselt werden können. Beispiel: 
 
 
     check off; insert ("reporter"); check on 
 
 
Mit dem Kommando 
 
 
     #ib#generate reports#ie# ("testdatei") 
 
 
werden die oben erwähnten Prozeduraufrufe ('#ib#report#ie#') in das zu testende Programm,
welches in der Datei 'testdatei' steht, geschrieben. Die Prozeduraufrufe werden nach
jedem Prozedur-, Operator- oder Refinement-Kopf eingefügt und erhalten den
entsprechenden Namen als Parameter. Diese Prozeduraufrufe werden gekennzeichnet,
damit sie von der Prozedur 
 
 
     eliminate reports ("testdatei") 
 
 
automatisch wieder entfernt werden können. Beispiel (für die eingefügten Prozedurauf­
rufe): 
 
 
    ... 
    PROC beispiel (INT CONST mist): 
    \#\#report ("PROC beispiel");\#\# 
    ... 
 
 
 
'Automatische Ablaufinformation' 
Ist ein Programm mit 'generate reports' mit 'report'-Aufrufen versehen worden, kann
es wie gewohnt übersetzt werden. Wird das Programm vom ELAN-Compiler kor­
rekt übersetzt und dann gestartet, wird bei jedem Antreffen eines 'report'-Aufrufs der
Parameter (Name der Prozedur, Operator oder Refinement) in eine Datei, die
TRACE-Datei geschrieben. Die TRACE-Datei wird beim Programmlauf automatisch
von 'reporter' unter dem Namen 'TRACE' eingerichtet. 
 
Mit Hilfe dieser Datei kann der Programmablauf verfolgt werden. Es ist damit auch
möglich festzustellen, wo eine "Endlos-Rekursion" auftritt. Die Ablaufinformationen
bestehen nur aus den Namen der angetroffenen Prozeduren und Refinements. Trotz­
dem können die Anzahl der Informationen sehr umfangreich werden. Deshalb gibt es
die Möglichkeit, die Erzeugung der Ablaufinformationen ab- bzw. wieder anzuschal­
ten. Dazu gibt es die Möglichkeit, in das zu testende Programm die Prozeduren 
 
 
     #ib#report on#ie# 
     #ib#report off#ie# 
 
 
einzufügen und das zu testende Programm mit diesen Prozeduraufrufen (erneut) zu
übersetzen. 
 
 
'Benutzereigene Ablaufinformation' 
Zusätzlich zu den von 'generate reports' eingefügten 'report'-Aufrufen kann ein
Benutzer eigene Aufrufe an geeigneten Stellen in ein Programm schreiben. Dafür
werden weitere 'report'-Prozeduren zur Verfügung gestellt, die als ersten Parameter
ein TEXT-Objekt (meist Name des Objekts oder der Ausdruck selbst) und als zwei­
ten ein INT/REAL/TEXT/ BOOL-Objekt (der zu überprüfende Wert oder Ausdruck)
enthalten. Beispiel: 
 
 
    ... 
    PROC beispiel (INT CONST mist): 
    \#\#report ("beispiel");\#\#     (* automatisch eingefuegte *) 
    INT VAR mist :: ...; ... 
    \#\#report ("mist:", mist);\#\#  (* vom Benutzer per Hand einge­
                                    fuegt *) 
    ... 
 
 
Folgende 'report'-Routinen stehen zur Verfügung, damit man sie "von Hand" in ein
zu testendes Programm einfügen kann: 
 
 
     PROC report on 
     PROC report off 
     PROC report (TEXT CONST message) 
     PROC report (TEXT CONST message,  INT CONST value) 
     PROC report (TEXT CONST message, REAL CONST value) 
     PROC report (TEXT CONST message, TEXT CONST value) 
     PROC report (TEXT CONST message, BOOL CONST value) 
 
 
Wichtig: Hier - wie bei allen anderen "von Hand eingefügten" Aufrufen - sollte
ein Nutzer sich an die Konvention halten, diese in "\#\#" einzuklammern. Mit 'eliminate
reports' werden diese Einfügungen automatisch entfernt. Sollen diese Aufrufe aber
immer im Programm erhalten bleiben (jedoch nicht wirksam sein), sollten sie 
 
a) vor 'generate reports'-Aufruf mit jeweils '\#\#\#' eingefaßt werden. Beispiel: 
   \#\#\# report ("...") \#\#\# 
   So steht das 'report'-Statement in einem Kommentar. 'generate reports' wandelt
   '\#\#\#' --> '\#\#\#\#' um, so daß ein solches Statement wirksam wird. 'eliminate
   reports' wandelt ein '\#\#\#\#' --> '\#\#\#' zurück. 
 
b) nach 'generate reports' in '\#\#\#\#' eingefaßt werden. 
 
 
'Häufigkeitszählung' 
Eine Häufigkeitszählung erhält man, in dem man in das zu testende Programm die
Aufrufe 
 
 
     count on 
     count off 
 
 
einfügt. Ist die Häufigkeitszählung eingeschaltet, merkt sich 'reporter' die Anzahl der
Durchläufe für jede Prozedur bzw. Refinement. Mit der Prozedur 
 
 
     #ib#generate counts#ie# ("zu testende datei") 
 
 
werden die vermerkten Häufigkeiten in das zu testende Programm direkt eingefügt.
Die Häufigkeiten werden wie oben beschrieben gekennzeichnet, so daß sie mit 'elimi­
nate reports' entfernt werden können. 
 
 
'Assertions' 
Zusätzlich zu den oben erwähnten Möglichkeiten bietet 'reporter' noch die Prozedur 
 
 
     #ib#assert#ie# 
 
 
an. Diese Prozedur kann von einem Programmierer an einer Stelle in das zu testende
Programm eingefügt werden, an der bestimmte Bedingungen erfüllt sein müssen. Die
Prozedur 'assert' steht in zwei Formen zur Verfügung: 
 
 
     PROC #ib#assert#ie# (BOOL CONST zusicherung) 
     PROC assert (TEXT CONST message, BOOL CONST zusicherung) 
 
 
Ist der Wert von 'zusicherung' nicht TRUE, wird der Programmlauf abgebrochen. 
 
 
 
reporter - Kommandos 
 
 
'count on' 
   #on("b")#PROC count on #off("b")# 
   Schaltet die Häufigkeitszählung ein. 
 
'count off' 
   #on("b")#PROC count off #off("b")# 
   Schaltet die Häufigkeitszählung aus. 
 
'eliminate reports' 
   #on("b")#PROC eliminate reports (TEXT CONST datei) #off("b")# 
   Entfernt gekennzeichnete 'report'-Aufrufe aus der Datei 'datei'. 
 
'generate reports' 
   #on("b")#PROC generate reports (TEXT CONST datei) #off("b")# 
   Fügt 'report'-Aufrufe in die Datei 'datei' ein und kennzeichnet diese mit '\#\#'. 
 
'report on' 
   #on("b")#PROC report on #off("b")# 
   Schaltet die Ablaufinformationen in die Datei 'TRACE' ein. 
 
'report off' 
   #on("b")#PROC report off #off("b")# 
   Schaltet die Ablaufinformationen wieder aus. 
 
'generate counts' 
   #on("b")#PROC generate counts (TEXT CONST datei) #off("b")# 
   Bringt die Häufigkeitszählung (wie oft eine Prozedur oder Refinement durchlaufen
   wurde) in die Programmdatei 'datei'. Mit 'eliminate reports' werden diese wieder
   automatisch entfernt. 
 
'assert' 
   #on("b")#PROC assert (TEXT CONST message, BOOL CONST value) #off("b")# 
   Schreibt 'message' und den Wert von 'value' in die TRACE-Datei. Ist 'value'
   FALSE, wird angefragt, ob das Programm fortgesetzt werden soll. 
#page# 

Referencer 
 
 
'referencer' wird durch 
 
 
     referencer ("ref datei", "referenz liste") 
 
 
aufgerufen, wobei die Datei 'referenz liste' nicht existieren darf. 'referenz liste' enthält
nach Ablauf des Programms die gewünschte Liste, die sogenannte #ib# Referenzliste#ie#. 
 
#ub#Achtung#ue#: 'referencer' arbeitet ausschließlich mit Namen und verarbeitet nur wenige
syntaktische Konstrukte. Darum ist es nur erlaubt, ein PACKET auf einmal von 'refe­
rencer' verarbeiten zu lassen. Verarbeitet man mehrere PACKETs auf einmal, kann es
geschehen, daß gleichnamige Objekte in unterschiedlichen Paketen zu Warnungen
(vergl. die unten beschriebenen Überprüfungen) führen. 
 
In der Referenzliste sind 
 
- alle Objekte mit ihrem Namen (in der Reihenfolge ihres Auftretens im Programm) 
 
- alle Zeilennummern, in der das Objekt angesprochen wird 
 
- die Zeilennummern, in der das Objekt deklariert wurde ('L' für ein lokales und 'G'
  für ein globales Objekt, 'R' für ein Refinement) 
 
verzeichnet. 
 
Die Referenzliste kann u.a. dazu dienen, zu kontrollieren, ob und wie (bzw. wo) ein
Objekt angesprochen wird. Dies lohnt sich selbstverständlich nur bei etwas umfan­
greicheren Programmen (bei "Mini"-Programmen kann man dies sofort sehen). 
 
Bei der Erstellung der Referenzliste nimmt das Programm 'referencer' gleichzeitig
einige Überprüfungen vor, die helfen können, ein Programm zu verbessern: 
 
1. Warnung bei mehrzeiligen Kommentaren. 
 
2. Überdeckungsfehler. Wird ein Objekt global (auf PACKET-Ebene) und nochmals
   lokal in einer Prozedur deklariert, ist das globale Objekt nicht mehr ansprechbar.
   Überdeckungen sind nach der gültigen Sprachdefinition z.Zt. noch erlaubt, werden
   aber bei einer Revision des Sprachstandards verboten sein. 
 
3. Mehrmaliges Einsetzen von Refinements. Wird ein Refinement mehrmals einge­
   setzt (das ist völlig legal), sollte man überlegen, ob sich dieses Refinement nicht
   zu einer Prozedur umgestalten läßt. 
 
4. Nicht angewandte Refinements. Wird ein Refinement zwar deklariert, aber nicht
   "aufgerufen", erfolgt eine Warnung. 
 
5. Nicht angesprochene Daten-Objekte. Werden Daten-Objekte zwar deklariert,
   aber im folgenden nicht angesprochen, wird eine Warnung ausgegeben. Hinweis:
   Alle Objekte, die nur wenig angesprochen werden, also nur wenige Zeilennum­
   mern in der Referenzliste besitzen, sind verdächtig (Ausnahmen: importierte
   Prozeduren, LET-Objekte u.a.m.). 
 
 

referencer - Kommandos
 
 
'referencer' 
   #on("b")#PROC referencer (TEXT CONST check file, dump file) #off("b")# 
   Überprüft 'check file'. In 'dump file' steht nach Abschluß die Referenzliste. 
 
#page# 

6.3  Rechnen im Editor 
 
Das Programm TeCal ermöglicht einfache Rechnungen (ähnlich wie mit einem Ta­
schenrechner) unter der Benutzung des Editors. Gleichzeitig stehen dem Benutzer
aber alle Fähigkeiten des Editors zur Verfügung. TeCal ermöglicht Rechnungen auf
einfache Weise zu erstellen oder Tabellenspalten zu berechnen. Zur Benutzung 
müssen 'TeCal' und 'TeCal Auskunft' insertiert werden. 
 
TeCal wird aus dem Editor heraus durch 'ESC t' oder durch das Editor-Kommando 
 
 
           tecal 
 
 
aktiviert. Dadurch wird in der untersten Zeile des Bildschirms eine Informationszeile
aufgebaut, in der die (Zwischen-) Ergebnisse einer Rechnung zur Kontrolle fest­
gehalten werden. 
 
 
 
Arbeitsweise 
 
 
Wenn TeCal insertiert ist, kann die Taschenrechnerfunktion jederzeit durch <ESC> <t>
aufgerufen werden. Aus der editierten Datei werden Werte mit <ESC> <L> gelesen,
durch <ESC> <+> (bzw. -,*,/) verknüpft und mit <ESC> <S> an die aktuelle Cursor­
position geschrieben werden. 
 
Der von TeCal errechnete Wert wird durch <ESC> <S> derart ausgegeben, daß an der
Stelle an der der Cursor steht die letzte Stelle vor dem Dezimalpunkt geschrieben
wird. 
 
Die Eingabe von Klammern geschieht durch <ESC> <(> <ESC> <)>. 
 
Durch die Hilfsfunktion <ESC> <?> lassen sich die TeCal Funktionen auflisten. 
 
Der Prozentoperator <ESC> <%> erlaubt einfache Rechnungen der Form: 'zahl' <ESC> <+>
<ESC> <%> <ESC> <=> . 
 
Derartige Folgen können natürlich mit der bekannten Editor-Lernfunktion auch ge­
lernt werden, so daß sich z.B. die Mehrwertsteuerberechnung auf wenige Tasten 
reduziert. 
 
Spalten können summiert werden, indem auf der #on("u")#untersten#off("u")# Zahl einer Spalte <ESC> <V>
eingegeben wird. Daraufhin werden alle darüberliegende Zahlen addiert, bis ein
Zeichen auftritt, das nicht in einer Zahl auftritt (Leerzeichen stören nicht!). 
 
____________________________________________________________________________ 
         ............ 
               55.00 
               66.99 
              123.45 
 
               99.99 
 
             9876.54 
         ........... 
 
 Anzeige:            0.00  14.00%  Memory:       0.00 
 
____________________________________________________________________________ 
 
 
TeCal Prozeduren 
 
 
'evaluate' 
   #on("b")#evaluate (TEXT CONST zeile, INT CONST von) #off("b")# 
   Ausdruck 'zeile' ab der Stelle 'von' berechnen. 
 
   #on("b")#evaluate (TEXT CONST zeile) #off("b")# 
   Ausdruck 'zeile' ab Stelle 1 berechnen. 
 
 
'kommastellen' 
   #on("b")#kommastellen (INT CONST stellen) #off("b")# 
   Berechnungen auf 'stellen' Zahlen hinter dem Komma einstellen. 
 
 
'merke' 
   #on("b")#PROC merke (INT CONST zahl)#off("b")# 
   Integer 'zahl' im Merkregister abspeichern. 
 
   #on("b")#PROC merke (REAL CONST zahl)#off("b")# 
   Real 'zahl' im Merkregister abspeichern. 
 
'prozentsatz' 
   #on("b")#PROC prozentsatz (INT CONST zahl) #off("b")# 
   Prozentsatz von 'zahl' Prozent einstellen. Der Wert wird automatisch konvertiert. 
 
   #on("b")#PROC prozentsatz (REAL CONST zahl) #off("b")# 
   Prozentsatz von 'zahl' Prozent einstellen. 
 
 
'tecal' 
   #on("b")#PROC tecal (FILE VAR f) #off("b")# 
   Datei 'f', die mit 'sequential file' assoziiert ist, mit TeCal editieren. 
 
   #on("b")#PROC tecal (TEXT VAR datei) #off("b")# 
   'datei' mit TeCal editieren. 
 
   #on("b")#PROC tecal #off("b")# 
   Zuletzt editierte Datei mit TeCal editieren. 
 
 
'tecalauskunft' 
   #on("b")#PROC tecalauskunft #off("b")# 
   Auskunft zeigen. 
 
   #on("b")#PROC tecalauskunft (TEXT CONST zeichen) #off("b")# 
   Auskunft zu 'zeichen' zeigen.