A nyelv első szintű vezérlése -- mint már említettük -- az RPG programcikluson keresztül történik, amelyet indikátorokkal, ill. C kártyákon op-code-okkal befolyásolhatunk. Az RPG IV ez utóbbi lehetőséghez -- a hamarosan ismertetésre kerülő -- factor1, factor2-típusú hagyományos op-code-ok mellé nyelvi elemek újabb tárházát kínálja a programozóknak: az extented factor-os C kártyákat, ill. (akár szabadon indentálható) kifejezések használatát.
Előljáróban az RPG sor szerkezeteről:
CL0N01N02N03FACTOR1+++OPCDEFACTOR2+++RESULTLENDHHILOEQCOMMENTS++++++++++++
Egy utasítást tartalmazó sor elején indikátorok vagy negáltjaik szerepelhetnek, ezután az utasítás első faktora, majd az utasítás kódja, ezután a második faktor, majd az eredmény, annak hossza, típusa, az eredménytől függő indikátorok, végül megjegyzés szerepelhet.
Pl.
C N21 FAKT1 ADD FAKT2 RESULT EZ EGY OSSZEADAS C FAKT3 COMP FAKT4 101112OSSZEHASONLIT, 11 IND. 1 HA FAKT3< COMP (Compare)
Az eredmény indikátorok állítódnak be az összefüggés alapján.
Az utasítás első és második faktorban adott változókra végzi el az xx műveletet, vagy ha nincs xx megadva, akkor összehasonlítja őket és a Hi, Lo, Eq poziciókon álló indikátorok közül beállítja a megfelelőt, majd a Result pozícióban lévő cimkére ugrik. xx lehet pl. EQ, LT, GT, LE, GT
Pl.
C FLD1 CABLTFLD2 TAG1 14
Strukturált programokban altalaban ez sem szerepel.
Teljesen hasonló a fentihez, de ez szubrutint hív és ezt használják is. Az xx értéke lehet: GE, GT, LE, LT, EQ, NE, melyek jelentése: >=, >, <=, <, =, #.
Pl.:
CL0N01N02N03Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments++++++ C FIELDA CASGEFIELDB SUBR01 C FIELDA CASEQFIELDC SUBR02 C CAS SUBR03 C ENDCS
Az első példa FIELDA és FIEALDB kapcsolatát vizsgálja, FIELDA >= FIELDB esetén SUBR01 subrutint futtatja, hasonlóan a második sorban FIELDA = FIELDC esetén SUBR02 kerül végrehajtásra, majd a program az ENDCS utáni utasításokkal folytatódik. FIELDA # FIELDC teljesülésekor a CAS utasítás a SUB03 végrehajtását eredményezi.
Az itt leírtak nagyrészt az RPG procedurális működési módjára igazak, ez felel meg a szokványos procedurális nyelvek működésének. A szekvenciális végrehajtás itt annyiban más, hogy indikátorokkal vezérelhetőek a végrehajtások. Pl.
C WSIDNO CHAINRCOMCO 20 C 20 EXSR ERRSR
Az első sorban WSIDNO kulcs szerint olvasunk az RCOMCO rekordszerkezetű fájlból, ha nem sikerült, akkor beállítódik a 20-as indikátor, és az alatta lévő sor végrehajtásra kerül, itt például egy hibakezelő szubrutin hívódik meg.
Tehát a CHAIN parancs alkalmas arra, hogy fájlokat kulcs szerint direkt olvashassunk. Amennyiben nincs a megadott kulccsal rekord az állományban, akkor az első eredmény indikátor '1' értékre változik, egyébként '0' marad az értéke.
Hagyományos kifejezés kiértékelés, az és a paraméter viszonyát vizsgálja, amennyiben a feltétel igaz, akkor az ezt követő utasítások hajtódnak végre, egyébként az IF-hez tartozó ELSE utasítást követő utasítások. Kicsit nehezen olvasható, pl. if (a<=d) and (c>=d) or (x=y) leírása a következő alakú:
C A IFLT B C C ANDGED C X OREQ Y
Az ELSE az előtte lévő legközelebbi lezáratlan IF-hez tartozik. Az IFxx ágat ENDIF paranccsal kell lezárni, tehát ez blokkosítva van. (ELSE használata opcionális.)
pA többirányú elágaztatásra használható, erőssége, hogy bármilyen változók bármilyen összehasonlitása állhat a WH** utasitásnál, pl.
C SELEC C YEARS WHLT 2 EZ URES AG, ENDSL-RE UGRIK C YEARS WHLE 3 C ADD 5 DAYS C YEARS WHLE 10 C ADD 10 DAYS C OTHER C ADD 20 DAYS C ENDSL
Ez felel meg a FOR ciklusnak.
C START DO END COUNTR . . C ENDDO INC
Ha nincs kezdőérték megadva, akkor 1 lesz, a COUNTR a ciklusváltozó (mint minden változó, ez is globális), a ciklus végén adható meg a lépték, közben is változtatható a ciklusváltozó értéke, sőt lehet indikátort tenni az ENDDO sor elé, így azon esetleg túl is futhat a program.
Elől tesztelő ciklus, az IFxx-hez hasonló felépitéssel.
Hátul tesztelő ciklus, felépitése hasonló az IF-hez, azaz az az érdekes helyzet áll fönn, hogy hátultesztelő a ciklus, de a tesztelendő feltétel a ciklus elején van.
A GOTO cimkére ugorhat szubrutinon belül, a programok strukturaltak, ritkán használják, általában szubrutinból való kiugrásra. Használata: A 2. Operandusban megadott cimkére ugrik.
A CALL segítségével az RPG programból külső program hívható alprogramként. A paramétereket az utasítást követő PARM utasítások, vagy az eredménymetőben megadott PLIST-ben felsorolt paraméterek adják meg. A hívandó program neve literálként, vagy változóként is megadható. A változóban a programnevet könyvtárnévvel is ki lehet egészíteni.
A RETRN segítségével léphetünk vissza a programból. (A program normál befejeződése is visszatérést eredményez.)
(A FREE használatával, a második operandusban megadott, korábban CALL-lal hívott és tárban maradt programok törölhetők az aktív programlistából.)
A DO ciklusnál az ENDDO utasitásra ugrik, és inkrementál.
Bármilyen ciklusnál a ciklus utáni első utasitásra ugrik.
Erről azért írok külön, mert az RPG programok elsődlegesen fájlokkat foglalkozó programok megírására jött létre. A fájl vagy I/O müveletek szolgálnak a diszkek, a képernyők és más perifériák müködtetésére. Az itt megemlítésre kerülő utasítások az RPG ciklustól függetlenül, számítái időben fejtik ki hatásukat.
Az RPG újabb változatai támogatják néhány tíz beépített függvény használatát is, amelyek az op-code-októl (utasításoktól) eltérően visszatérési értékeket használnak eredménymezők helyett. A beépített függvények nevei a "%" jellel kezdődnek. Általános alakjuk:
function-name{(argument{:argument...})}
A paraméterek lehetnek változók, konstansok, beépített függvények és ezekből épített kifejezések; és tetszőleges kifejezés tartalmazhat beépített függvényeket.
néhány jellemző beépített függvény