Enkele OpenCOMAL features
Overzicht ][ Macharsoft | UniCOMAL | COMAL-80
Zie ook OpenCOMAL homepage (website van Jos Visser)
1. PROC en FUNC
variabelen ![]()
Onderstaand enkele features die in ieder geval niet zijn opgenomen in UniCOMAL.
We bekijken allereerst (een blijkbaar, per regel, syntax-correcte) invoer van een
programma in UniCOMAL (versie 3.11):
0010 PROC test(PROC pname) 0020 pname 0030 ENDPROC test 0040 0050 PROC set 0060 PRINT "PROC set was executed" 0070 ENDPROC set 0080 0090 test(set)
scan Illegal use of PROCedure parameter in line 0020 pname
Uit de SCAN van dit programma blijkt dat het gebruik van PROC
voorafgaand aan de procedure-naam pname, binnen PROC test(PROC pname), door UniCOMAL in eerste instantie wordt
geaccepteerd.
Echter, pname als statement, binnen die procedure, geeft
aanleiding tot een foutmelding!
Laten we regel 0020 uit het programma weg, dan krijgen we na SCAN:
Not a simple variable in line 0090 test( set )
Maar nu in OpenCOMAL.
We hebben (echt) hetzelfde programma:
10 PROC test(PROC pname) 20 pname 30 ENDPROC test 40 50 PROC set 60 PRINT "Procedure set was executed" 70 ENDPROC set 80 90 test(set)
$ scan $ run Procedure set was executed
Inderdaad, in OpenCOMAL is het mogelijk PROCedures (en FUNCties) als parameter door te geven.
Nog twee voorbeelden.
| [1] Gebruik van procedures als in bovenstaand voorbeeld. |
[2] Een voorbeeld van het doorgeven van een functie als parameter. |
|
10 d1:
20 DATA 1, 2, 3, 4
30 d2:
40 DATA 10, 11, 12, 13
50
60 PROC rest_d1
70 RESTORE d1
80 ENDPROC rest_d1
90
100 PROC rest_d2
110 RESTORE d2
120 ENDPROC rest_d2
130
140 PROC rp(PROC rest_dx)
150 rest_dx
160 WHILE NOT(EOD) DO
170 READ value
180 PRINT value," ",
190 ENDWHILE
200 PRINT
210 ENDPROC rp
220
230 rp(rest_d2)
240 rp(rest_d1)
$ run 10 11 12 13 1 2 3 4 10 11 12 13 |
10 x:=3 20 FUNC kwad 30 RETURN x^2 40 ENDFUNC kwad 50 60 FUNC double(FUNC fname) 70 RETURN fname*2 80 ENDFUNC double 90 100 PRINT "Result = ",double(kwad) $ run Result = 18 |
Opmerking
Niet duidelijk is of (en hoe) functies met voorzien van een of meer argumenten (dus iets
als FUNC doe(x,y)) eveneens als parameter aan een
PROC/FUNC kunnen worden doorgegeven.
[einde Opmerking]
2. NAME variabelen
![]()
In het onderstaande programma wordt een drietal strings, via een opdracht (SET in regel
270) uit een DATA-regel gelezen.
Een NAME variabele in een procedure maakt het mogelijk een uitdrukking door te geven
aan een PROC/FUNC.
Die uitdrukking wordt niet geevalueerd (van een waarde voorzien) bij de aanroep,
maar pas geevalueerd binnen de procedure zelf, nl.daar waar de NAME variabele in
die procedure voorkomt.
10 n#:=0 // number of strings in data
20
30 PROC set(NAME parm$) CLOSED
40 IMPORT n#
50 FOR t#:=1 TO n# DO PRINT parm$ // evaluate parm$ n# times
60 PRINT parm$ // and print it
70 ENDPROC set
80
90 FUNC fname$ CLOSED
100 IF EOD THEN RETURN "EndOfData"
110 READ a$
120 RETURN a$
130 ENDFUNC fname$
140
150 PROC count(REF n#) CLOSED
160 WHILE NOT(EOD) DO
170 READ a$
180 n#:+1
190 ENDWHILE
200 RESTORE rd
210 ENDPROC count
220
230 rd:
240 DATA "prog1", "prog2", "prog3"
250
260 count(n#)
270 set("String is: "+fname$)
$ run String is: prog1 String is: prog2 String is: prog3 String is: EndOfData
Toelichting
De NAME variabele wordt geevalueerd in de omgeving van de aanroepende uitdrukking.
Dit kunnen we zien aan de uitvoer van het volgende programma.
Nb. De procedure doe2 is CLOSED. pre$
in die procedure is een locale variabele.
10 cml$:="COMAL" 20 doe(pre$+cml$) 30 40 PROC doe(NAME full$) 50 pre$:="Open" 60 PRINT full$ 70 pre$:="Uni" 80 PRINT full$ 85 doe2(full$) 90 ENDPROC doe 100 110 PROC doe2(NAME full$) CLOSED 120 pre$:="Acorn" 130 PRINT full$ 140 ENDPROC doe2
$ run OpenCOMAL UniCOMAL UniCOMAL
3. CASE
![]()
In ieder geval nieuw, in vergelijking met COMAL-80 en UniCOMAL, is de mogelijkheid bij
OpenCOMAL om binnen een CASE statement ook (beperkte) logische uitdrukkingen te evalueren.
10 FOR t:=1 TO 6 DO
15 PRINT t," - ",
20 CASE t OF // op de plaats van t mag ook een uitdrukking staan
30 WHEN 1, 2
40 PRINT "Een of twee"
50 WHEN <=3
60 PRINT "Kleiner gelijk 3"
70 WHEN >5
80 PRINT "Groter dan 5"
81 WHEN <7
82 PRINT "Kleiner dan 7"
90 OTHERWISE
100 PRINT "Tja"
110 ENDCASE
120 ENDFOR t
$ run
1 - Een of twee
2 - Een of twee
3 - Kleiner gelijk 3
4 - Kleiner dan 7
5 - Kleiner dan 7
6 - Groter dan 5
Maar toch blijf ik erbij dat een CASE statement als onderstaand (voor alle bestaande COMAL-versies) duidelijker is en meer mogelijkheden biedt.
10 FOR t:=1 TO 6 DO
15 PRINT t," - ",
20 CASE TRUE OF
30 WHEN t=1, t=2
40 PRINT "Een of twee"
50 WHEN t<=3
60 PRINT "Kleiner gelijk 3"
70 WHEN t>5
80 PRINT "Groter dan 5"
81 WHEN t<7
82 PRINT "Kleiner dan 7"
90 OTHERWISE
100 PRINT "Tja"
110 ENDCASE
120 ENDFOR t
4. Externe procedures
![]()
PROC/FUNC's kunnen tijdens de uitvoering van een programma ook worden geladen.
Afwijkend van UniCOMAL is, dat zo'n procedure door OpenCOMAL niet noodzakelijk als CLOSED
wordt beschouwd.
10 tel:=0
20
30 FOR t:=1 TO 5 DO tellen
40
50 PRINT "" // new line
60
70 PROC tellen EXTERNAL "tellen.prc"
|
10 // External procedure
20
30 PROC tellen
40 tel:+1
50 PRINT tel," ",
60 ENDPROC
|
$ run 1 2 3 4 5 |
Nieuw in OpenCOMAL is dat daarbij kan worden aangegeven of zo'n programmadeel tijdelijk
(DYNAMIC) of blijvend (STATIC) in het geheugen wordt opgenomen.
Wordt de procedure aangeroepen met een string constante (zoals hierboven),
dan beschouwt OpenCOMAL de procedure als STATIC. Via het sleutel woord DYNAMIC kan echter
anders worden beslist.
10 tel:=0 20 30 FOR t:=1 TO 5 DO tellen 40 50 PRINT "" // new line 60 70 PROC tellen DYNAMIC EXTERNAL "tellen.prc" |
De bestandsnaam van de externe procedure kan ook een variabele zijn. In dit geval beschouwt OpenCOMAL de procedure als DYNAMIC, tenzij via STATIC anders wordt aangegeven.
10 pname$:="tellen" 20 tel:=0 30 40 FOR t:=1 TO 5 DO tellen 50 80 PROC tellen STATIC EXTERNAL pname$+".prc"