Programmeren in PL/1/Procedures
Declareren van procedure
[bewerken]Hierin wordt aangegeven hoe de procedure of functie kan aangewend worden. Een functie is een procedure die een bepaalde resultaatwaarde teruggeeft na uitvoering. Samen met een procedure kunnen argumenten meegegeven worden, die kunnen dienen om een resultaat te berekenen:
PL/1-code: Oppervlakte van een driehoek berekenen op basis van de lengte van twee zijden en de tussenliggende hoek.
pgm: PROCEDURE OPTIONS(MAIN); DECLARE (zijde1, zijde2, hoek) FLOAT; PUT LIST('De datum is vandaag: ', DATE()); CALL vraagstelling; BEGIN; PUT SKIP LIST('De driehoek met als zijden ', zijde1, ' en ', zijde2); PUT SKIP LIST(' en met tussenliggende hoek ', hoek, '°'); PUT LIST('heeft als oppervlakte ', oppervlakte(zijde1, zijde2, hoek), ' cm2.'); END; vraagstelling: PROC; PUT SKIP LIST('Geef de lengte van twee zijden (in cm) en de tussenliggende hoek (in °)'); GET LIST(zijde1, zijde2, hoek); END vraagstelling; oppervlakte: PROC (a, b, h) RETURNS (FLOAT); DCL (a, b, h) FLOAT; RETURN (a*b*sin(h)/2); END oppervlakte; END pgm;
Bovenstaand voorbeeld bevat ook een ingebouwde functie DATE() die de huidige datum als resultaatwaarde teruggeeft. De functie PUT drukt zijn argumenten af en GET zorgt voor input door de ingetypte waarden toe te kennen aan de vermelde argumenten. Een RETURN-waarde kan zowel een variabele als een nog uit te rekenen wiskundige uitdrukking bevatten.
Bereik van variabelen
[bewerken]Variabelen zijn enkel maar bekend binnen de procedure waarin ze gedeclareerd werden. Variabelen van het hoofdprogramma zijn ook gekend binnen subprocedures die zich binnen het hoofdprogramma bevinden (zie procedure 'vraagstelling'). Bestaat er binnen die procedure echter een variabele met een identieke naam, dan is enkel de inhoud van de variabele van die subprocedure binnen die procedure beschikbaar.
PL/I laat toe om variabelen niet te declareren (dit is een zogenaamde 'contextual declaration'). In dat geval geldt de situatie alsof ze in het hoofdprogramma werden gedeclareerd.
Een speciaal soort procedure is het BEGIN-blok dat in tegenstelling tot een echte procedure niet noodzakelijk een label en nooit parameters meekrijgt.
Externe programma's
[bewerken]Externe programma's kunnen op dezelfde manier opgeroepen worden. Omdat het belangrijk is dat in alle oproepende programma's de declaraties identiek zijn, wordt gebruik gemaakt van een interface die bij het compileren opgeroepen wordt door %INCLUDE.
PL/1-code: interface
DCL 01 parameters, 03 invoer, 05 rek_num CHAR(10), 03 uitvoer, 05 controlegetal_RC CHAR(07) INIT (''), 05 controlegetal_fout DEC FIXED(05), 05 ctr_gtl DEC FIXED(3); DCL 01 parpointr POINTER INIT (ADDR(parameters));
Een POINTER zorgt ervoor dat enkel het pointeradres moet doorgegeven worden van het hoofdprogramma naar het externe programma, en niet alle bijhorende variabelen.
PL/1-code: hoofdprogramma
DCL ADDR BUILTIN; DCL controlegetal ENTRY; %INCLUDE interface; ... ber_ctr_gtl: PROC; parameters = ''; /* INITIALISATIE INTERFACE */ parameters.rek_num = rekeningnummer; /* INVULLEN INVOERWAARDE */ CALL controlegetal(parpointr); /* MODULE UITVOEREN */ IF parameters.controlegetal_RC ^= '' /* CONTROLE UITVOERWAARDEN */ THEN ctr_gtl = 99; END ber_ctr_gtl;
Bovenstaand programma roept onderstaand programma op. Alleen de pointer moet doorgegeven worden. De parameters worden op de oorspronkelijke geheugenplaats gelezen, en het resultaat wordt ook op die plaats teruggezet. Merk op dat het declaratiegedeelte bijna identiek is aan de interface. enkel de plaats van POINTER en BASED is verschillend, omdat in het hoofdprogramma de pointer het adres van de parameters overneemt, terwijl in het externe programma de pointer binnenkomt en het adres van de parameters bepaalt.
PL/1-code: oproepend extern programma
/* BEREKENEN CONTROLEGETAL */ controlegetal: PROC (parpointr) OPTIONS(MAIN); DCL 01 parpointr POINTER; DCL 01 parameters BASED (parpointr), 03 invoer, 05 rek_num CHAR(10), 03 uitvoer, 05 controlegetal_RC CHAR(07) INIT (''), 05 controlegetal_fout DEC FIXED(05), 05 ctr_gtl DEC FIXED(3); DCL MOD BUILTIN; /* ************* */ ctr_gtl = MOD (rek_num, 97); IF ctr_gtl = 00 THEN ctr_gtl = 97; END controlegetal;
Ingebouwde functies
[bewerken]- stringfuncties
- SUBSTR('123456789', 2, 3) = '234'
- STRING('a','bc','def') = 'abcdef'
- REPEAT('ab', 2) = 'ababab' Herhaalt een string n + 1 maal.
- LENGTH('alfabet') = 7
- TRANSLATE('7654321','1234','ACTG') = '765GTCA': Kan een code teken per teken omzetten
- VERIFY('678A','0123456789') = '0'b controleert of een string enkel de vermelde tekens bevat (Geeft een bitstring '1'b voor TRUE en '0'b voor FALSE terug)
- LOW(2) = x'0000' Geeft een aantal keer de laagste tekenwaarde (uit de EBCDIC-tabel)
- HIGH(3) = x'FFFFFF' Geeft een aantal keer de hoogste tekenwaarde (Hier weergegeven als hexadecimale waarden)
- LBOUND()
- HBOUND()
- numerieke functies
- ROUND(3.6666,2) = 3.67
- SUM(1, 2, 3) = 6
- MOD(9796197741, 97) = 28 geeft de Euclidische rest (rest bij gehele deling)
- SQRT(49) = 7
- LOG(1000) = 4
- SIN(90) = 0
- COS(90) = 1
- datum en tijd
- DATE() = '20001231' (31 december 2000)
- TIME() = '235900' (23u59)
- DATETIME() = '20001231235900'
Vooraf kunnen ingebouwde functies gedeclareerd worden met BUILTIN:
PL/1-code: Oppervlakte van een driehoek berekenen op basis van de lengte van twee zijden en de tussenliggende hoek.
DCL (ADDR, DATE, INDEX, SUBSTR, STRING, VERIFY) BUILTIN;