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"