Enkele OpenCOMAL features

Overzicht  ][  Macharsoft | UniCOMAL | COMAL-80


Overzicht terug

  1. PROC en FUNC variabelen
  2. NAME variabelen
  3. CASE
  4. Externe procedures

Zie ook OpenCOMAL homepage (website van Jos Visser)


1. PROC en FUNC variabelen terug
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 terug
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 terug
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 terug
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"

begin pagian
[opencomal1.htm] laatste wijziging op: 21-09-08