A REXX ELJÁRÁSNYELV LEÍRÁSA

Készítette : Mocsáry János és Belme Attila

Tartalom

A VM/SP System Product Interpreter és a REXX eljárásnyelv

A REXX elemei

A REXX parancsok ismertetése

ADDRESS ARG CALL DO...END DROP EXIT IF INTERPRET ITERATE LEAVE NOP NUMERIC PARSE PROCEDURE PULL PUSH QUEUE RETURN SAY SELECT...END SIGNAL TRACE UPPER

Beépitett függvények

ABBREV - ABS - ADDRESS - ARG - BITAND - BITOR - BITXOR - CENTER - CENTRE - COMPARE COPIES - C2D - C2X - DATATYPE - DATE DELSTR - DELWORD - D2C - ERRORTEXT - EXTERNALS - FIND - FORMAT INDEX - INSERT - JUSTIFY - LASTPOS - LEFT - LENGTH - LINESIZE - MAX MIN - OVERLAY - POS - QUEUED - RANDOM - REVERSE - RIGHT - SIGN SOURCELINE - SPACE - STRIP - SUBSTR - SUBWORD - SYMBOL TIME - TRACE - TRANSLATE - TRUNC - USERID - VALUE VERIFY - WORD - WORDINDEX - WORDLENGTH - WORDS - XRANGE - X2C X2D

Egyéb függvények

CMSFLAG - DIAG - DIAGRC - STORAGE

Példák

A VM/SP System Product Interpreter és a REXX eljárásnyelv

A REXX (Restructured EXtended eXecutor) a VM/SP CMS alatt mûködik.

A CMS alatt mûködõ EXEC eljárásnyelvek között sorrendben ez már a harmadik, és szinte semmiben sem hasonlít az elõdeihez.

Az interpreter képes végrehajtani a REXX nyelven készült eljárásokat CMS és XEDIT környezetben egyaránt.

A REXX elemei

megnevezés magyarázat

Az utasítások írásmódja ::: Az utasításokat egyenként külön sorba , vagy egy sorba az egymás után következõket ";" -el elválasztva lehet írni. A sor hossza maximum 250 karakter. Ha egy utasítás nem fér ki egy sorba, akkor több soron keresztül is folytathatjuk.

Megjegyzés (Comment) ::: /* és */ karakterek közé írt bármilyen szöveg. A REXX programot megjegyzés sorral kell kezdeni, mert a CMS az elsõ sor alapján választja ki a megfelelõ interpretert.

Változó név (Szimbólum) ::: betûvel kezdõdik, és maximum 250 karakter hosszú. A kis és nagybetûk között nincs különbség. Amíg egy változó értéket nem kap, addig az értéke a saját neve lesz. Ha a változó string-et tartalmaz, akkor annak hosszát csak a virtuális tár mérete korlátozza.

Értékadás ::: Változó = kifejezés Az értékadást tehát egyenlõségjellel jelezzük. A kifejezés tetszõleges aritmetikai, logikai, vagy szöveges (String) mûveleteket tartalmazhat.

String ::: ' vagy " karakterek közé írt tetszõleges szöveg. Hossza maximum 250 karakter. Ha ' jelek között újabb ' -ot akarunk megadni, akkor írjuk ki duplán. Például: 'DATUM:''89.11.12'.

Hexstring ::: Egy string, ami mögé "x" betût írunk. A string csak 0-9, illetve A-F karakrereket tartalmazhat. Pl: "F1F2F3"X A hexstring segítségével hexadecimálisan beírhatunk olyan adatokat is, melyeket egyébként nem tudnánk.

Szám ::: Csak számjegyeket vagy ".+-e" valamelyikét tartalmazó karaktersorozat, vagy string. Pl : 12.3 vagy -32e+3 vagy "+2".

Függvény ::: szimbólum(kifejezés) A "szimbólum" a függvény neve, a "kifejezés" pedig az átadott paraméterek.

String konkatenáció ::: A konkatenáció jele : !! (két függõleges vonal). Az interpreter azonban a konkatenációt minden határolójelnél elvégzi. Pl: V='alma' Z=V'fa' R=V 'a fa' alatt E=v!!'fa' Miután elvégezte a fenti mûveleteket, a változók értéke a következõ lesz : V : "alma". Z és E : "almafa". R : "alma a fa ALATT". R értéke azt is mutatja, hogy ha egy változó (itt: alatt) nem kap értéket, akkor az értéke a saját neve lesz, nagybetûsre alakítva.

Aritmetika ::: + :: összeadás; - :: kivonás; * :: szorzás; / :: osztás; ** :: hatványozás egész számmal; % :: osztás, az eredmény az egész érték lesz; // :: osztás, az eredmény a maradék lesz;

Összehasonlítás::: == :: teljesen egyforma, pl. két string; = :: egyenlõ, pl. két szám, vagy két string (a bevezetõ és záró szóközöket leszámítva); < :: kisebb; > :: nagyobb; <= :: kisebb vagy egyenlõ (^> : u.az) >= :: nagyobb vagy egyenlõ (^< : u. az) <> :: nem egyenlõ (^= és >< u. az) ^== :: nem azonos (nem egyforma)

Logikai mûveletek (Boolean) ::: Csak 0 és 1 logikai értékek között végez mûveleteket. & :: logikai és; ! :: logikai vagy (függõleges vonal); && :: logikai kizáró vagy; ^ :: negáció

Összetett szimbólumok ::: sz1.sz2.sz3 formájúak. Ilyen esetben a szimbólum értékét úgy kapjuk meg, hogy jobbról behelyettesítõdnek a változónevek, és minõsítik a tõlük balra lévõ nevet. Pl: b=2 c=3 a.b.c="palacsinta" mûveletek elvégzése után a "palacsinta" értéket az A.2.3 nevû változó kapja meg

Törzs változó::: szimbólum. A "." jelzi, hogy a szimbólum egy törzs változót jelez. Ilyen pl: A.; ALFA.; Példa a használatukra: ALFA.="zongora" A fenti utasítás az összes lehetséges "ALFA."-al kezdõdõ változónak a "zongora" értéket adja.

Címkék ::: szimbólum: A szimbólum után írt ":"-al jelezhetjük, hogy ez egy címke, amire pl. egy CALL utasítással adhatjuk át a vezérlést.

CMS vagy XEDIT parancs kiadása ::: A HOST rendszernek (azaz annak, amelyikbõl ezt a programot elindították) is kiadhatunk parancsokat. A parancsokat egyszerûen is kiadhatjuk, ha az nem REXX változónév (vagy parancs). Pl.: LISTFILE (D Ha azonban nem vagyunk biztosak abban, hogy a kívánt utasítás nem REXX változó vagy parancs, akkor a következõképpen adhatjuk ki : 'LISTFILE (D' A kiadott parancsot mindig az a rendszer hajtja végre, amelyik alatt a REXX program elindult. Ha ez nem felel meg az elvárásainknak, akkor a végrehajtó rendszert közvetlenül is kijelölhetjük az ADDRESS paranccsal (ld. késõbb).

Aritmetikai és logikai mûveletek esetén a REXX felismeri és kezeli az általános mûveleti hierarchiát.

A REXX-ben van néhány speciális változó, ezekhez fenntartott nevek vannak. Ez természetesen nem jelenti azt, hogy e változóknak nem adhatunk értéket! E változók az alábbiak :

RC - külsõ (CMS, CP stb...) parancsok végrehajtása után ebbe a változóba kerül bele a visszatérési kód.

SIGL - a SIGNAL utasítás használatakor ebbe kerül bele annak a programsornak a száma, ahonnan az ugrás történt.

RESULT - Ha egy eljárást a CALL utasítással hívunk, és az a RETURN-nál paramétereket ad vissza (pl. az összes függvény ilyen), akkor az eredményt a RESULT-ban kapjuk meg.

E leírásban a kulcsszavak nagybetûkkel szerepelnek. Ezeket mindig így, betû szerint kell leírni. A nem kötelezõ paramétereket [] jelek közé tettem. Az így jelölt paraméterek tehát elmaradhatnak. Ahol a leírásban több paraméter egymás alatt <> és ! jelek között áll, az azt jelenti, hogy a felsorolt paraméterek közül egyet meg kell adni, de több nem adható meg egyszerre.

A REXX parancsok ismertetése

A következõ fejezetekben megtalálhatjuk a REXX parancsait, de csak rövidített formában. Bõvebb információt a CMS-ben a HELP REXX MENU parancs kiadása után kaphatunk.
    ADDRESS rendszer [parancs]
A nem REXX parancsok végrehajtásának vezérlése hatása: a kiadott "parancs" -ot a "rendszer" nevû alrendszer fogja végrehajtani. Ha nem adunk "parancs"-ot, akkor az összes, e parancs végrehajtása után következõ, nem REXX parancsot a "rendszer" fogja végrahajtani. Pl.: ADDRESS XEDIT 'Q V'; Ha XEDIT-bõl indítottunk el egy EXEC típusú file-t, akkor a fenti paranccsal a XEDIT-nek adtunk ki egy QUERY VERIFY parancsot (rövidítve : Q V). - Az elindított eljárás argumentumainak átvétele :
    ARG változó nevek
Az elindított eljárás argumentumainak átvétele hatása : az eljárás indításánál átadott változóka nevek" helyén megadott változókba teszi. Ha kevés a megadott változónév, akkor az utolsó változóban lesz az összes maradék paraméter. - Belsõ (REXX) vagy külsõ (pl. gépi kódú) szubrutin hívása :
    CALL név [kif1[,kif2[,kif3...
hatása : a "név" nevû eljárást a "kif1" stb. paraméterekkel meghívjuk. A REXX-ben írt szubrutinok rekurzívak is lehetnek.

- Ciklus vagy utasításcsoport szervezése :

    DO ismétlés feltétel;
      utasítás1;
      utasítás2;
      stb...
    END;
 
        "ismétlés":      név = kif1 [TO kif2] [BY kif3] [FOR kif4]
                         FOREVER
                         kif4
 
        "feltétel":      WHILE kif5
                         UNTIL kif6
hatása : Ha az "ismétlés" még nem járt le, és a "feltétel" is teljesül, akkor az "utasítás1" stb... utasításcsopot végrehajtódik.

"név" : a ciklusváltozó neve.

"kif1" : a ciklusváltozó kezdeti értéke.

"kif2" : a ciklusváltozó végértéke.

"kif3" : a ciklusváltozó értéke ennyivel változik az utasításcsoport végrehajtása után.

"kif4" : a ciklus (legfeljebb) ennyiszer hajtódik végre.

"kif5" : a ciklus végrehajtódik, ha ez a logikai érték igaz.

"kif6" : a ciklus végrahajtódik, ha ez a logikai érték hamis.

A ciklusváltozó és a WHILE feltétel értékét a ciklus elején, m&iac UNTIL feltétel értékét a ciklus végén vizsgálja az interpreter.

Példa :

             DO L=1 BY -2 FOR 3; SAY L ; END;
             a példa eredménye :
             1
             -1
             -3
 
- Változók törlése a tárból :
    DROP név1 [név2...
hatása : a "név1" stb... -vel jelzett változó kitörlõdik a virtuális tárból, és a kezdeti, inicializálatlan állapotot veszi fel ismét (Pl. az értéke egyenlõ lesz önmagával). - REXX program végrehajtás befejezése :
    EXIT kif
hatása : a REXX program "kif" visszatérési kóddal befejezõdik.

- Feltételes vezérlés :

    IF feltétel THEN utasítás1;
                ELSE utasítás2;
hatása : ha a "feltétel" logikai érték igaz, akkor az "utasítás1", ha viszont hamis, akkor az "utasítás2" hajtódik végre. Ha több utasítást akarunk végrehajtatni, akkor szervezzünk DO; ...; END; utasításcsoportot belõlük !

- Kifejezéssel elõállított utasítások végrehajtása :

    INTERPRET kif
hatása : a "kif" kifejezés értéke kiszámítódik, majd egy REXX programsorként végrehajtódik. Igy végrehajthatunk olyan program- részleteket, amelyeket a REXX program dinamikusan állít elõ, és például egy változóban tárol. Pl.: A='SAY'; B='htxt'; C="Boys !"; htxt='Hello'; INTERPRET A B C; Az utasítások hatására az alábbi szöveg íródik ki : Hello BOYS !

- DO ciklus hátralévõ részének átugrása :

    ITERATE [név]
hatása : az utasítás végrehajtása azt eredményezi, hogy a DO ciklus hátralévõ része nem hajtódik végre, hanem az END-ig átugorja a maradék utasításokat. Ha megadjuk a "név" paramétert, annak egyenlõnek kell lennie az aktív ciklus ciklusváltozó névvel. Pl.: DO I=1 TO 4; IF I=3 THEN ITERATE; SAY I; END ; Az utasítások az alábbi sorokat írják ki : 1 2 4

- DO ciklus befejezése

    LEAVE [név]
hatása : az utasítás kiadásakor az aktív DO ciklus befejezõdik, a program a DO - hoz tartozó END után folytatódik. A "név"-re az ITERATE utasításnál leírtakat kell figyelembe venni.

- Üres utasítás

    NOP
hatása : nincs

- Aritmetikai mûveletek és változók pontosságának megadása :

    NUMERIC DIGITS kif1
 
    NUMERIC FORM SCIENTIFIC
                 ENGINEERING
 
    NUMERIC FUZZ kif2
hatása : az aritmetikai mûveletek pontosságát szabályozza. "kif1" kifejezés megadja, hogy hány decimális számjegy pontosan kivánunk számolni, ill. a számokat tárolni. Maximális értékét a virtuális tár mérete szabja meg. "kif2" kifejezés megadja, hogy az összehasonlításnál mennyi jegyet ne vegyen az interpreter figyelembe. A FORM utáni kulcsszavak jelzik, hogy milyen formátumúak legyenek a kiszámított értékek.

- Változók feltöltése valamilyen inputból, azt szétszedve.

                  !ARG             !
                  !EXTERNAL        !
                  !NUMERIC         !
    PARSE [UPPER]  mindenféle
                  !SOURCE               !
                  !VALUE kif WITH !
                  !VAR név         !
                  !VERSION         !
hatása : a megadott forrásból vett karaktersorozatot külön változókra bontja, és szükség esetén ("UPPER" megadása esetén) nagybetûs formára konvertálja.

ARG : az eljárásnak átadott argumentumot szedi szét.

EXTERNAL: a terminál input pufferbõl vett adatokkal dolgozik.

NUMERIC : az utolsó NUMERIC parancs paramétereit adja vissza.

PULL : a program stack következõ sorát emeli ki, és azzal dolgozik.

SOURCE : megadja, hogy milyen módon indítottuk el ezt a REXX programot. (Pl.: CMS COMMAND v. SUBROUTINE, az exec file neve, stb...)

VALUE : a megadott "kif" kifejezés kiértékelõdik és így vesz részt a további mûveletben.

VAR : a "név"-el megadott változó értéke vesz részt a mûveletben.

VERSION : megadja a REXX interpreter verzióját.

"mindenféle" - megadhatunk itt változóneveket, és határolókat. A parancs úgy mûködik, hogy a megadott határolóknál (vagy, ha nem adunk meg ilyet, akkor szóközöknél) szétbontja az input- ot, és a megadott változókba teszi. Ha a határoló string, akkor ott vágja szét az input-ot, ahol e string elõfordul. (Ha változó tartalmazza a határolót, akkor tegyük a változónevet zárójelbe.) Ha szám a határoló, akkor a számmal jelzett pozición, elõjeles szám esetén a jelenlegi pozicióhoz képest ennyivel eltolva vágja el. Pl.:

             PARSE VALUE TIME() WITH A ':' B ':' C;
             PARSE VALUE TIME() WITH x 4 y;
             SAY "A PONTOS IDO :" A "ORA ," B "PERC ," C "MASODPERC";
             SAY "X erteke="X "Y erteke="Y;
                a futás után pl. a következõ eredményt kapjuk :
             A PONTOS IDO : 17 ORA 12 PERC 23 MASODPERC
             X erteke=17: Y erteke=12:23

- A változók védelme belsõ szubrutinok hívása esetén :

    PROCEDURE [EXPOSE vált.nevek]
hatása : a kívánt belsõ szubrutin elején kiadva egy új változókészletet kapunk (lokális változókészlet), és nem érhe el tovább a hívó program változóit. Ha az EXPOSE kulcsszó után felsorolunk változóneveket ("vált.nevek"), akkor a megnevezett változók közösek lesznek a hívó és a hívott számára. A rut való visszatérés után minden változó az eredeti értéket (hív& elõtti értéket) kapja vissza, kivéve azon változókat, melyeket az EXPOSE után felsoroltunk.

- Adatok kiemelése a program stack-bõl :

    PULL mindenféle
hatása : a program stack következõ sora kiemelõdik, és a megadott határolók szerint szétbontódik. "mindenféle" - U. az, mint a PARSE parancsnál.

- Adatok besüllyesztése a program stack-be :

    PUSH kif
hatása : a "kif" kifejezés kiértékelésekor kapott string bekerül a program stack-be, LIFO módszerrel.
    QUEUE kif
hatása : a "kif" kifejezés kiértékelésekor kapott string bekerül a program stack-be, FIFO módszerrel.

- Visszatérés alprogramból :

    RETURN [kif]
hatása : az aktív alprogram befejezõdik, és a hívó program folytatódik. Függvény esetén a visszaadott értéket a "kif" szimbolizálja.

- Szöveg kiiratása a terminálra :

    SAY kif
hatása : az interpreter a "kif" kifejezést kiértékeli majd kiírja a CMS virtuális konzolra.

- Többféle alternatív utasítás feltételes végrehajtása :

    SELECT;
             WHEN kif1 THEN utas1
             WHEN kif2 THEN utas2
             WHEN kif3 THEN utas3
        ... stb ...
             OTHERWISE utasn
    END;
hatása : amennyiben a "kif1,kif2...stb..." logikai kifejezések valamelyikének értéke 1 (igaz), akkor végrehajtódik a kifejezés utáni THEN kulcsszót követõ "utas1,utas2...stb..." utasítás. Ha valamelyik WHEN ágban több utasítást akarunk végrehajtatni, szervezzünk belõlük DO utasításcsoportot. Ha egyik kifejezés sem igaz, akkor az OTHERWISE utáni utasítás(ok) hajtódik végre.

- Feltétel nélküli vezérlés :

    SIGNAL címke
    SIGNAL VALUE kifejezés
hatása : az interpreter abnormális vezérlésátadást hajt végre a "címke" címkére, vagy a "kifejezés" kiértékelése után kapott címkére.
    SIGNAL ON ERROR
              HALT
              NOVALUE
              SYNTAX
hatása : az ON után írt kulcsszóval jelzett esemény bekövetkeztekor a vezérlés a jelzett kulcsszó: címkénél folytatódik (pl. ha szintaktikai hiba van a programban, akkor s SYNTAX: címkénél). Ha az ON helyett OFF-ot írunk a kívánt kulcsszóval, akkor a jelzett esemény figyelése abbamarad, tehát nem jön létre vezérlés, ha az esemény bekövetkezik. Az esemény bekövetkeztekor a SIGL változó azt a sorszámot tartalmazza, ahol az adott feltétel bekövetkezett, ami ezt a vezérlést kiváltotta. A fent megnevezett események az alábbiakat jelentik :

ERROR - egy eljárás vagy HOST parancs befejezésekor nem 0 az RC ;

HALT - a terminálon kiadták a HI parancsot ;

NOVALUE - olyan változót használunk inputként (azaz pl. egy értékadás jobb oldalán), amely még nem kapott értéket ;

SYNTAX - szintaktikai hiba a REXX programban .

- Nyomkövetés :

    TRACE tparm
E parancs segítségével a nyomkövetést kapcsolhatjuk be, vagy ki. Csak 3 paramétert írtam le itt, melyeket a "tparm" helyén kell megadni :

ALL minden utasítás kiíródik a terminálra, amelyet az interpreter végrehajt.

RESULTS az ALL hatásán kívül az utasítások eredményeit is kiírja.

OFF a nyomkövetés kikapcsolása.

Lehetõség van interaktív nyomkövetésre is. Pl: ha kiadjuk, hogy TRACE ?ALL ; akkor az interaktív nyomkövetést kapcsoltuk be. Interaktiv nyomkövetés közben két utasítás között a terminálró kiadhatunk bármilyen REXX, CMS, vagy CP parancsot. Ez a lehetõség nagymértékben megkönnyíti a REXX programok "belövését".

- Konvertálás nagybetûkre :

    UPPER változónevek
hatása : a "változónevek" helyén felsorolt változók tartalma nagybetûs formára konvertálódik.

Beépített függvények

Az alábbiakban röviden leírom a REXX függvényeit. A leírásban az alábbi jelöléseket alkalmazom :

str1, str2,... string típusú paramétert jelöl;

ln hossz paraméter;

num szám típusú paramétert jelöl;

tölt kitöltõ karaktert jelöl, mellyel a mûvelet a végeredményt, vagy valamelyik paramétert a kívánt hosszúságra kiegészíti, feltölti (általában jobbról vagy balról).

n1, n2, ... sorszámot jelöl

    ABBREV(str1,str2[,ln])
megvizsgálja, hogy az "str1" megegyezik-e az "str2"-vel balról kezdve, "ln" hosszúságban ? Ha igen, 1-et ad vissza. Ha nem, akkor 0 az eredmény. A két string közül a rövidebbet (azaz a rövidítést) az "str2" kell hogy tartalmazza.
    ABS(num)
Visszaadja a "num" abszolút értékét.
    ADDRESS()
Visszaadja annak a környezetnek a nevét, amely a HOST parancsokat végre fogja hajtani.
    ARG([n1[,opt]])
Ha nem adunk meg paramétert, akkor visszaadja, hogy az aktív eljárás mennyi paramétert kapott az indulásnál. Ha "opt" nincs megadva, akkor visszaadja az "n1"-ik argumentumot. "opt" helyére "E" vagy "O" írható. "E" esetén 1-et ad vissza, ha az "n1"-ik paraméter létezik, különben 0-t. "O" esetén akkor ad vissza 1-et, ha az "n1"-ik paraméter nem létezik.
    BITAND(str1[,[str2][,tölt]])
    BITOR(str1[,[str2][,tölt]])
    BITXOR(str1[,[str2][,tölt]])
Két string között (értelemszerû) logikai mûveletet végeznek, bitenként. A mûvelet elõtt a rövidebb string a "tölt" karakterrel egészítõdik ki a másik string hosszára.
    CENTER(str1,ln[,tölt])
    CENTRE(str1,ln[,tölt])
Az eredmény egy "ln" hosszúságú string lesz, melyet elõször feltölt a "tölt" karakterrel, majd a közepére beteszi az "str1" stringet.
    COMPARE(str1,str2[,tölt])
A rövidebb string kiegészítése után összehasonlítja a két stringet, és 0-et ad vissza, ha egyenlõek. Egyébként pedig az elsõ nem egyezõ karakter pozicióját adja vissza.
    COPIES(str1,n)
Az eredmény "str1" lesz, "n"-szer egymás után másolva.
    C2D(str1[,n])
Az "str1" -et "n" byte-os bináris számként értelmezi, és decimális számra alakítja. Ha a legfelsõ bitje 1, akkor 2-es komplemensben tárolt negatív számról van szó, egyébként pozitív.
    C2X(str1)
Az "str1"-et hexadecimálisan adja vissza.
    DATATYPE(str1[,típus])
Ha nem adjuk meg a "típus"-t, akkor megvizsgálja, hogy az "str1" értéke milyen típusú ? Ha szám, akkor visszaadja, hogy NUM. Ha nem szám, akkor "CHAR" az eredmény. Ha megadjuk a "típust", akkor megvizsgálja, hogy "str1" megfelel-e a megadott típusnak. Ha igen, 1-et ad vissza. Ha nem, akkor 0-t. "típus" helyére az alábbi betûket írhatjuk :
    DATE([opció])
Visszaadja a mai dátumot, Pl. : 15 Nov 1989 - ha nem adjuk meg az "opció" paramétert. Ha az "opció" alábbi értékei esetén a következõket adja vissza :
    DELSTR(str1,n[,ln])
"str1" -bõl kitörli az "n"-ik karaktertõl kezdõdõ, "ln" hosszúságú részt. Ha nem adunk meg "ln"-t, akkor a string hátralévõ része törlõdik.
    DELWORD(str1,n[,ln])
"str1" -bõl kitöröl az "n"-iktõl kezdve "ln" darab szót.
    D2C(num[,ln])
A "num" számot "ln" hosszúságú karaktersorozattá alakítva adja vissza (bináris tárolás). Ha "num" negatív szám, akkor "ln" megadása kötelezõ !
    D2X(num[,ln])
A "num" számot "ln" hosszúságú hexadecimális számként adja vissza. Ha "num" negatív, akkor "ln"-t kötelezõ megadni.
    ERRORTEXT(n)
Visszaadja az "n"-ik hibaüzenetet.
    EXTERNALS()
Visszaadja, hogy a terminál input puffer mennyi elemet tartalmaz.
    FIND(str1,str2)
Az "str2"-ben lévõ, esetleg több szóból álló szöveget megkeresi az "str1"-ben. A szavakat egymástól egy vagy több szóköz választhatja el, de a szóközök száma a keresés szempontjából közömbös. Az eredmény egy szám, amely azt adja meg, hogy "str1"-ben hányadik szótól kezdve található meg "str2".
    FORMAT(num[,[n1][,n2]])
Kerekítve és formázva adja vissza a "num" számot. "n1" jelzi a szám egész részének számára az output (eredmény) mezõben fenntartott byte-okat, míg "n2" a tizedespont utáni rész hosszát írja elõ.
    INDEX(str1,str2[,n])
Megkeresi "str2"-t "str1"-ben, és visszaadja, hogy hányadik poziciótól kezdve találta meg. Ha "n"-et magadjuk, akkor a keresés "str1" "n"-ik pozicióján kezdõdik.
    INSERT(str1,str2[,[n][,[ln][,tölt]]])
Elõször "str1"-et kiegészíti "ln" hosszúságúra "tölt" karakterekkel, majd beszúrja "str2" "n"-ik karaktere után. Az így kapott string lesz a függvény eredménye.
    JUSTIFY(str1,ln[,tölt])
"str1"-et kiegésziti "ln" hosszúságban, majd a benne lévõ szavakat úgy helyezi el, hogy az összes szóköz a szavak közé kerüljön egyenletesen elosztva, de közben minden szóközt "tölt" karakterrel helyettesít.
    LASTPOS(str1,str2[,n])
megkeresi "str1"-et "str2"-ben visszafelé, és visszaadja azt, hogy hol találta meg. Ez az érték tehát az utolsó elõfordulás helye lesz. Ha "n"-et megadjuk, akkor nem "str2" legvégétõl, hanem csak az "n"-ik karakterétõl kezd keresni, természetesen visszafelé.
    LEFT(str1,ln[,tölt])
"str1" baloldali "ln" hosszú részével tér vissza. Ha szükséges, akkor az eredményt "ln" hosszra "tölt" karakterrel egészíti ki.
    LENGTH(str1)
Visszaadja "str1" hosszát.
    LINESIZE()
A terminál sorhosszát adja vissza, ha az be van állítva a CP TERM LINESIZE paranccsal.
    MAX(n1[,n2]...)
Megkeresi és visszaadja a felsorolt "n1,n2,...stb..." numerikus értékek közül a legnagyobbat. Legfeljebb tíz szám adható meg.
    MIN(n1[,n2]...)
Megkeresi és visszaadja a felsorolt "n1,n2,...stb..." számok közül a legkisebbet.
    OVERLAY(str1,str2[,[n][,[ln][,tölt]]])
"str1"-et "ln" hosszúságban (esetleg "tölt"-el kiegészítve) beleteszi "str2" "n"-ik karakterétõl kezdve "str2"-be,annak eme poziciókon lévõ karaktereit felülírva.
    POS(str1,str2[,start])
"str1"-et megkeresi "str2"-ben, majd visszaadja azt a poziciót, ahol megtalálta. (U. az, mint az INDEX függvény, csak a paraméterek sorrendje van megfordítva.)
    QUEUED()
Visszaadja, hogy hány sor van még a program stack-ben.
    RANDOM([min][,[max][,indít])
Egy "min" és "max" közé esõ pszeudo-véletlenszámot ad vissza. "min" és "max" nem lehet negatív, és a különbségük nem lehet nagyobb, mint 100000. Ha megadjuk az "indít" értéket, az arra jó, hogy késõbb reprodukálni tudjuk a sorozatot, ugyanezen érték megadásával.
    REVERSE(str1)
"str1"-et adja vissza, fordítva. Az utolsó karakter lesz az elsõ, az utolsó elõtti a második, stb.
    RIGHT(str1,ln[,tölt])
"str1" jobboldali "ln" karakterével tér vissza, szükség esetén balról "tölt" karakterekkel kiegészitve.
    SIGN(num)
Értéke : -1, ha "num" negatív; 0, ha "num" nulla; 1, ha "num" pozitív;
    SOURCELINE([n])
Az éppen aktív REXX program "n"-ik sorát adja vissza string-ként. "n" nem lehet nagyobb, mint ahány sor van a programunkban. Ha nem adjuk meg "n"-et, akkor visszaadja az utolsó sor számát.
    SPACE(str1[,[n][,tölt]])
"str1"-ben a szavak között lévõ szóköz karakterek eltávolítása ut&a "n" darab "tölt" karaktert tesz be a szavak közé. "n" lehet 0 is.
    STRIP(str1[,[opció][,chr]])
Eltávolítja "str1"-bõl a vezetõ és/vagy záró "chr"-el megegyezõ karaktereket, az "opció"-tól függõen. "chr" alapértelmezése szóköz (blank). "opció" értékei az alábbiak lehetnek : L - vezetõ karaktereket távolítja el; T - záró karaktereket távolítja el; B - (alapértemezés) a vezetõ és a záró karaktereket is eltávolítja.
    SUBSTR(str1,n[,[ln][,tölt]])
Az "str1"-bõl az "n"-ik karaktertõl kezdõdõen kivág egy "ln" hosszú karaktersorozatot (ha rövidebb, akkor "tölt"-el egészíti ki), és ezt adja vissza.
    SUBWORD(str1,n[,ln])
Az "str1" "n"-ik szavától kezdõdõen kivág "ln" darab szót, majd ezt adja vissza.
    SYMBOL(str1)
Ha az "str1" nem egy REXX szimbólum, akkor "BAD" -ot ad vissza. Ha az egy szimbólum, és változó név, akkor az eredmény "VAR". Ha szimbólum, de nem változó, akkor az eredmény "LIT".
    TIME([opció])
Ha nem adunk opciót, akkor a 24 órás napi idõt adja vissza a következõ formában : ==:PP:MM; Ha az opció értéke az alábbiak valamelyike, akkor a mellé írt eredményt adja vissza :
    TRACE([opció])
Visszaadja, hogy milyen REXX TRACE aktív.
    TRANSLATE(str1[,[tabo][,[tabi][,tölt]]])
"str1" karaktereit más karakterekre cseréli le. A folyamat a következõképpen zajlik le : "str1" karaktereit egyenként megkeresi "tabi" stringben (melynek alapértelmezése : XRANGE('00'X,'FF'X), majd ahányadik pozición megtalálta, "tabo" annyiadik karakterével helyettesíti ("tabo"-t szükség esetén "tölt"- el egészíti ki). Az így kapott string lesz az eredmény.
    TRUNC(num[,n])
"num" egész részét, és "n" darab tizedes jegyet ad vissza.
    USERID()
A felhasználó azonosítóját adja vissza.
    VALUE(név)
A "név" nevû szimbólum értékét adja vissza.
    VERIFY(str1,str2[,['M'][,n]])
Megvizsgálja, hogy "str1" minden egyes karaktere megtalálható-e "str2"-ben. Ha minden karaktert megtalált, akkor 0 a függvény értéke. Ha olyan karakter van "str1"-ben, mely nem található meg "str2"-ben, akkor a kérdéses karakter "str1"-beli pozicióját adja vissza eredményként. Ha megadjuk az 'M' paramétert, akkor "str1" azon karakterének az "str1"-en belüli pozicióját adja vissza, amelyik benne van az "str2"-ben. "n" az összehasonlítás kezdetét jelzi, mindkét stringben.
    WORD(str1,n)
Visszaadja "str1" "n"-ik szavát. Megegyezik a SUBWORD(str1,n,1) eredményével.
    WORDINDEX(str1,n)
Megadja, hogy "str1"-ben az "n"-ik szó hanyadik pozición kezdõdik.
    WORDLENGTH(str1,n)
Megadja, hogy "str1"-ben az "n"-ik szó hány byte hosszú.
    WORDS(str1)
Megadja, hogy "str1" hány szóból áll.
    XRANGE([start][,end])
Visszaad egy olyan stringet, melynek az elsõ karaktere "start", és a karakterek kódját egyenként növelve, "end"-ig tart. Ha "start" nagyobb, mint "end", akkor a hexadecimális FF kódú karakter után a 0 kódú következik, majd sorban növekszik míg el nem éri "end" értékét.
    X2C(str1)
"str1" hexadecimális számot karaktersorozattá konvertálja. "str1" egyes byte-jai csak 0-9, vagy A-F karaktereket tartalmazhatnak.
    X2D(str1[,n])
"str1" hexadecimális számot decimálisra konvertálja. Ha "n"-et nem adjuk meg, akkor "str1" egy elõjel nélküli számot reprezentál. "str1" egyes byte-jai csak 0-9, vagy A-F karaktereket tartalmazhatnak.

Egyéb függvények

Az eddig felsoroltakon kívül létezik még néhány REXX függvény, melyeket nem túl gyakran használunk. Ilyen pl. az RXSYSFN függvénycsomag. Ezek leírása megtalálható a CMS HELP-ben. Itt csak néhányat soroltam fel :
    CMSFLAG(flag)
Visszaadja, hogy a "flag"-al jelzett CMS SET érték aktuális-e. "flag" helyére a következõket írhatjuk : ABBREV, AUTOREAD, CMSTYPE, DOS, EXECTRAC, IMPCP, IMPEX, PROTECT, RELPAGE, SUBSET.
    DIAG(n[,str1,str2...])
    DIAGRC(n[,str1,str2...])
Segítségével kiadhatjuk az "n" hexadecimális értékkel jelzett DIAGNOSE utasítást. Az utasítás eredményét adja vissza. A DIAGRC abban különbözik a DIAG-tól, hogy az eredmény elsõ 16 byte-ján a CP visszatérési és feltételkódját is visszaadja, és az eredmény csak a 16. karakternél kezdõdik. CP parancs kiadása: DIAG(8,str1), ahol "str1" tartalmazza a CP parancsot. Ilyenkor a függvény a CP parancs eredményét adja vissza egy stringben úgy, hogy a sorok végét '15'X karakter jelzi.
    STORAGE()
Visszaadja hexdecimális számként, hogy mekkora a virtuális tárunk.
    STORAGE(cím,hossz)
Visszaadja a virtuális tárunk tartalmát (string-ként) "cím" hexadecimális címtõl kezdõdõen, "hossz" hosszúságban.
    STORAGE(cím,hossz,adat)
Az elõzõ funkciót hajtja végre, de utána felülírja a jelzett tárrészt "adat"-al (mely egy string).

PÉLDÁK

 
 
        Az elsõ példa azt mutatja be, hogy hogyan készithetünk egy
  számológép eljárást REXX nyelven :
 
 
  /* Kalkulator */
 
  Arg x;            /* Az argumentum eloallitasa az X valtozoba */
  Interpret 'z=' x; /* A kivant muvelet vegrehajtasa */
  Say x'='z;        /* A vegeredmeny kiiratasa */
 
  Ha a fenti eljárást beirjuk a PP EXEC nevû file-ba, akkor a
  következõképpen használhatjuk :
 
  PP 5+4*3
              És az eredmény :
  5+4*3=17
 
 
  A fenti eljárást kiegészitve elérhetjük, hogy XEDIT-bõl kiadva ne törölje
  le a képernyõt :
 
  /* Kalkulator */
 
  Arg x;
  Interpret 'z=' x;
  Address 'XEDIT' 'MSG' x'='z; /* Kiiratas a XEDIT MSG parancsaval */
  If rc = -3 then Say x'='z;   /* Kiiratas, ha nincs XEDIT */
 
  A fenti eljárást bármely CMS felhasználó megtalálhatja a CALC EXEC S2 nevû
  file-ban.
 
  Az alábbi példa egy XEDIT makró. Ha pl. a PP XEDIT nevû file-ba tesszük,
  és a XEDIT parancs-sorban kiadjuk hogy PP, akkor az aktuális sor tartalmát
  a sor közepére helyezi, feltéve, hogy egy sor a képernyõn 72 karakteres
  (általában annyi) :
 
  /* Pelda */
 
  'EXTRACT /CURLINE /LINE /SIZE'; /* A jelzett XEDIT valtozok elohozasa */
 
  /* Ha az aktualis sor a "TOP OF FILE" vagy "END OF FILE", akkor kilep : */
 
  if line.1<1 ! line.1>size.1 then exit;
 
  /* Egyebkent elvegzi a kivant funkciot, es ezzel vege : */
 
  'REPLACE' centre(strip(curline.3),72);
 
 
        A következõ eljárással egy ideiglenes lemezt definiálhatunk, és
  formázhatunk meg egyszerre. Az eljárás neve a példában TDEF EXEC :
 
 
 
  /* Temporalis diszk definialo eljaras */;
 
    arg nnn ccc m tobbi; /* argumentum szetszedese parameterekre */
 
  if arg()=0 ! nnn="" ! ccc="" ! m="" then
    do;                                         /* Ha keves parametert */
     say 'Keves a parameter.     Hivasmod :';   /* adtunk meg, akkor   */
     say 'TDEF nnn ccc m';                      /* ezeket a sorokat    */
                                                /* irja ki             */
     say '("nnn" a virtualis cim,"ccc" a cilinderszam,"m" a cms diszk jele)'
     exit 4;
     end;
 
  'desbuf'; /* CMS program stack kitörlése */
 
  'query disk' m '(stack'; /* Megkérdezzük a CMS-t, hogy letezik-e ez a
                              diszk ? */
 
   rrc=queued(); /* eltaroljuk, hogy hány sor van a stack-ben */
 
   'desbuf'; /* újra töröljük a program stack-et */
 
  if rrc^=1 then do; /* Ha nem 1 sor volt a stack-ben, akkor a diszk
                        ACCESS-alva van, hibajelzest adunk : */
 
                  say 'A(z) 'm' jelu cms diszk mar letezik  ';
                  exit 8;
                  end;
 
  /* Ha nem volt ilyen cms diszk, akkor megprobaljuk definialni : */;
 
  'cp define t3350' nnn ccc;
 
  if rc^=0 then do; /* Ha RC erteke nem 0, akkor nem sikerult definialni */
                 say 'A(z)' nnn 'cimu egyseg nem definialhato  ';
                 exit 12;
                 end;
 
  'set cmstype ht'; /* A CMS kiirasokat letiltjuk */
 
  queue 'yes';    /* Betesszuk a program stack-be a FORMAT parancsnak  */
  queue 'tmp'nnn; /* adando valaszokat egymas utan, FIFO modszerrel    */
 
  'format' nnn m; rrc=rc; /* Kiadjuk a FORMAT parancsot a CMS-nek */
 
  'set cmstype rt'; /* A FORMAT lefutasa utan ujra engedelyezzuk a CMS
                       terminal output-ot */
 
  if rrc=0 then do; /* Ha a FORMAT sikeres volt : */
 
        'query disk' m '(stack';
        pull; /* fejlec eltavolitasa */
        pull a; a=word(a,words(a)); /* az utolso szo kiszedese */
 
        say 'A(z)' nnn'/'m 'diszk formazasa kesz. Merete :',
        ccc 'cilinder ('a 'Blokk).';
        exit;
        end;
 
           else do; /* Ha viszont nem sikerult : */
 
               say 'A(z)' nnn 'diszk formazasa nem sikerult  ';
               exit 16;
               end;
 
        Az alábbi példán azt szeretném bemutatni, hogy hogyan irhatunk olyan
  eljárást REXX nyelven, ami kiment egy CMS minidiszket szalagra. Az eljárás
  neve a példában : DMP EXEC .
 
 
 
  /* Szalagra menti a megadott lemezt */
 
  /* A kovetkezo utasitas szetszedi az argumentumot parameterekre,
     mikozben nagybetus formara konvertalja : */
 
  parse upper arg diszk szalag '(' miegymas
 
  /* Most megvizsgaljuk, hogy eleg parametert adtak-e meg ? */
 
  if diszk='' ! szalag='' then
 
      do ;    /* keves a parameter */
        say 'Tul keves parametert adtal'
        say 'Helyes hivasmod :'
        say 'DMP diszk szalag'
        say '("diszk","szalag" - a minidiszk es a szalag virtualis cimei)'
        exit 4;
        end;
 
  /* Most megvizsgaljuk szintaktikailag a parametereket */
 
  if datatype(diszk,x) then
             if datatype(szalag,x) then nop;
                                   else do;
                                   say 'Hibas a szalagcim  '
                                   exit 8;
                                   end;
 
                       else do;
                       say 'Hibas a lemezcim  '
                       exit 8;
                       end;
 
  /* Itt megkerdezzük a CP-t, hogy tud-e ilyen cimu virt. eszkozokrol ? */
 
  parse value diag(8,'Q V' szalag) with mindegy tobbi;
 
  if mindegy^='TAPE' then do;
        say 'A(z)' szalag 'cimu egyseg nem szalag (vagy nincs is ilyen)';
        exit 12;
        end;
 
  /* Ezután leolvassuk a szalag cimkejet, es megkerdezzuk
     a T. felhasznalot, hogy megfelelo szalag van-e fent ? */
 
  do until v='I' ! v='N'
 
  'tape dvol1 ('szalag; 'tape fsf ('szalag;
     say 'Jo a kiirt szalagcimke ? (I-igen, N-nem)';
     pull v
     end;
 
  if v='N' then do; Say 'Akkor nem bantom'; exit 16; end;
 
  */ Itt megkerjuk a CP-t, hogy arulja el a virtuális diszk meretet... */
 
  parse value diag(8,'Q V' diszk) with mindegy ' ' 26 cylno tobbi;
 
  if mindegy^='DASD' then do;
        Say 'A(z)' szalag 'cimu egyseg nem lemez (vagy nincs is ilyen)';
        exit 12;
        end;
 
  /* Betesszuk a DDR utility vezerlo parancsait a program stack-be */
 
  queue 'input' diszk '3350';
  queue 'output' szalag '3420 (compact leave';
  queue 'dump 0 'cylno-1 ; queue 'yes';
  queue ; queue ;
 
  /* Letiltjuk a terminal outputot, meghivjuk a DDR -t, majd
     ujra engedélyezzük a terminal outputot */
 
  'set cmstype ht';
  'ddr'; rrc=rc; desbuf;
  'set cmstype rt';
 
  /* Megvizsgaljuk, hogy sikerült-e a mentes ? */
 
  if rrc^=0 then do;
              say 'A mentes nem sikerult  '
  file: dmp      exec     a   vm/sp cms on 4361 at elte szk
                          page 00002
              exit rrc;
              end;
 
  /* Ha a mentes sikerult, ezt meguzenjuk a felhasznalonak,
     és irunk egy TAPE MARK-ot (szalagjelet) a szalagra,
     a mentes utan. */
 
  say 'A mentes sikerult'
 
  'tape wtm ('szalag;
 
  /* Megkerdezzük a felhasznalotol, hogy letekerhetjük-e a szalagot ? */
 
  do until valasz='I' ! valasz='N';
 
 
      Say 'Letekerjem a szalagot ? (I-igen, N-nem)';
 
      parse upper pull valasz;
 
      if valasz='I' then do;
                        'tape run ('szalag ;
                        say 'A szalagot letekertem...';
                        exit;
                        end;
      end;
 
  exit;