12. ZPRACOVÁNÍ TABULEK 12.1. Příkaz SET Příkaz SET má tři formáty. První formát se používá k přesunům, jichž se zúčastňují speciální indexy (viz 4.5.9.3.) a položky s USAGE INDEX (viz 4.5.5.; nazýváme je zde zkráceně "UI-položky"). Druhý formát se používá pro změny hodnot speciálních indexů a ostatních údajů. Třetí formát příkazu SET nesouvisí se speciálními indexy, nýbrž slouží pro změny hodnot jednotlivých bitů v UPSI-bytu. Formát 1: - - - - | speciální-index | | speciální-index | SET < UI-položka > ... TO < UI-položka > | celočíselná-položka | | celočís.num.literál | - - | celočíselná-položka | - - Formát 2: - - - - - - | speciální-index | | UP BY | | speciální-index | SET < UI-položka >... < > < UI-položka > | celočís.položka | |DOWN BY| | celočís.num.literál | - - - - | celočíselná-položka | - - V obou formátech musí být numerický literál celočíselný, čímž je míněno, že jeho počet cifer za desetinnou tečkou musí být nulový. (Vyhovuje např. 5, +7, 0, -12, -1.234E+3, nevyhovuje např. 5.0 nebo 1.2E+2.) Poznámka: Každý speciální index je definován v klauzuli OCCURS (s podklauzulí INDEXED) v popisu nějaké položky, jejímž opakováním se vytváří pole (zvané též tabulka). Takto je každému speciálnímu indexu přiřazena délka opakujícího se úseku paměti, což jest délka té položky, v jejímž popisu je tento speciální index definován. Pro další výklad uvažujme speciální index I, jemuž přísluší délka di a speciální index K, jemuž přísluší délka dk. Ve vzorcích budou písmena I a K označovat hodnoty speciálních indexů, tj. binární obsahy jim přidělených slov paměti. Funkce: Příkaz SET formátu 1 způsobí přesun údaje uvedeného za slovem TO do všech údajů uvedených mezi slovy SET a TO. Následující tabulka ukazuje, které přesuny jsou přípustné a k jakým přepočtům hodnot při těchto přesunech dochází: Tabulka 15: Povolené typy přesunů v příkazu SET. ------------------------------------------------------------ |vysílající || příjmový údaj (uvedený před slovem TO) | | údaj ||---------------------------------------------| |(uvedený za|| | |celočíselná | | slovem TO)|| speciální index | UI-položka| položka | |___________||____________________|___________|____________| |-----------||--------------------|-----------|------------| | || pořadí určené příj-| | hodnota po-| | || movým speciálním | přesun | ložky bude | | speciální || indexem bude rovno | hodnoty | rovna pořa-| | index || pořadí určenému vy-| beze změny| dí určenému| | || sílajícím speciál- | | speciálním | | || ním indexem | | indexem | |-----------||--------------------|-----------|------------| | || přesun | přesun | | |UI-položka || hodnoty | hodnoty | nepovoleno | | || beze změny | beze změny| | |-----------||--------------------|-----------|------------| | || pořadí určené příj-| | | |celočíselná|| movým speciálním | nepovoleno| nepovoleno | | položka || indexem bude rovno | | | | || hodnotě celočíselné| | | | || položky | | | |-----------||--------------------|-----------|------------| | || pořadí určené příj-| | | |celočíselný|| movým speciálním | | | | numerický || indexem bude rovno | nepovoleno| nepovoleno | | literál || hodnotě celočísel- | | | | || ného num.literálu | | | ------------------------------------------------------------ Přesun jednoho speciálního indexu do druhého (SET I TO K) Hodnota příjmového speciálního indexu I bude naplněna tak, aby pořadí odpovídající této hodnotě bylo stejné jako pořadí odpovídající hodnotě vysílajícího speciálního indexu K: a) Je-li di = dk, provede se přesun hodnoty beze změny (I = K). b) Je-li di NOT= dk, přičemž di/dk je celé číslo, pak se provede I = K * (di/dk), kde dělení di/dk je provedeno během překladu. c) Je-li di NOT= dk, přičemž dk/di je celé číslo, pak se provede I = K / (dk/di), kde dělení dk/di je provedeno během překladu. d) Je-li di NOT= dk, přičemž ani di/dk ani dk/di nejsou celá čísla, pak se provede I = (K / dk) * di. Poznámka: Při normální práci se speciálními indexy bude hodnota K dělitelná délkou dk, takže všechna dělení vyjdou beze zbytku a výsledná hodnota I bude dělitelná délkou di. Pokud by hodnota K nebyla dělitelná délkou dk, bere se v případech c) a d) celá část podílu a případný zbytek se ignoruje. Přesun speciálního indexu do UI-položky, přesun UI-položky do speciálního indexu, přesun jedné UI-položky do druhé Obsah slova přiděleného vysílajícímu údaji se beze změny přesune do slova přiděleného příjmovému údaji. Přesun položky resp. literálu do speciál.indexu (SET I TO N) Zde N označuje celočíselnou numerickou položku nebo celočíselný numerický literál. Hodnota příjmového speciálního indexu I bude naplněna tak, aby pořadí odpovídající této hodnotě bylo rovno hodnotě N. Bude tedy I = (N - 1) * di, přičemž v případě literálu se tato hodnota vypočítá již při překladu. Přesun speciálního indexu do položky (SET N TO I) Zde N označuje pouze celočíselnou numerickou položku. Do příjmové položky N bude dosazeno pořadí odpovídající hodnotě vysílajícího indexu I. Bude tedy N = I / di + 1. Pokud by hodnota I nebyla dělitelná délkou di, bere se celá část podílu a případný zbytek se ignoruje. Poznámka: Je-li příjmovým údajem v příkazu SET binární numerická položka (USAGE COMP), ukládá se do ní vypočítaná hodnota I/di+1 přímo bez odřezávání případných přebývajících platných cifer vlevo, a to i při zadání parametru CBL TRUNC. (Má-li příjmová položka např. PIC 99 COMP, může při provádění příkazu SET vzniknout v této položce výsledná hodnota v rozmezí -32768 až 32767; neprovádí se tedy změna záporného znaménka ani odřezání stovek, tisíců a desetitisíců.) Poznámka: Je-li za slovem TO uvedena indexová položka provede se její indexování pouze jednou před začátkem naplňování příjmových údajů uvedených mezi slovy SET a TO. Např.příkaz SET I J TO N(I) se překládá tak, jako kdyby byl rozepsán způsobem MOVE N(I) TO POM resp. SET POM TO N(I) SET I TO POM SET J TO POM což do J uloží jinou hodnotu, než by učinily příkazy SET I TO N(I) SET J TO N(I). Funkce: V příkazu SET formátu 2 (s UP/DOWN) jsou přípustné právě ty kombinace údajů, které jsou přípustné ve formátu 1 (s TO; viz tabulku 15). Příkaz způsobí zvětšení (při UP) resp. zmenšení (při DOWN) hodnot všech údajů uvedených za slovem SET dle následujících pravidel: a) Stojí-li za SET speciální index a za UP (DOWN) též speciální index, zvětší (zmenší) se hodnota speciálního indexu uvedeného za slovem SET o hodnotu speciálního indexu uvedeného za slovem UP (DOWN) vynásobenou resp. vydělenou poměrem příslušných délek. Uvažujeme-li (při témže značení jako výše) příkaz "SET I UP BY K", pak - při di = dk se provede I = I + K, - při di NOT= dk, přičemž di/dk je celé číslo, se provede I = I + K * (di/dk) s výpočtem di/dk během překladu, - při di NOT= dk, přičemž dk/di je celé číslo, se provede I = I + K / (dk/di) s výpočtem dk/di během překladu, - při di NOT= dk, přičemž ani di/dk ani dk/di není celé číslo, se provede I = I + (K / dk) * di, přičemž není- li K dělitelno pomocí dk, bere se celá část podílu K/dk. K původní hodnotě I se tedy přičte přesně ta hodnota, která by se při "SET I TO K" do I dosadila. Při DOWN bude ve vzorcích místo znaménka + znaménko -. Je-li I dělitelno di a K dělitelno dk, dosadí příkaz "SET I UP BY K" do I hodnotu I + (K/dk)*di, takže pořadí bude I/di + K/dk + 1, zatímco příkaz "SET I DOWN BY K" dosadí do I hodnotu I - (K/dk)*di, takže pořadí bude I/di - K/dk + 1. b) Stojí-li za SET nebo za UP (DOWN) nebo na obou těchto místech UI-položka, zvětší (zmenší) se hodnota údaje za SET o hodnotu údaje za UP (DOWN). (Např. je-li U UI-položka, příkaz "SET I UP BY U" dosadí do I hodnotu I+U, příkaz "SET U DOWN BY I" dosadí do U hodnotu U-I). c) Stojí-li za SET speciální index a za UP (DOWN) celočíselná numerická položka nebo celočíselný numerický literál, zvětší (zmenší) se hodnota speciálního indexu uvedeného za SET tak, aby se pořadí odpovídající této hodnotě zvětšilo (zmenšilo) o hodnotu údaje uvedeného za UP (DOWN). (Např. je-li N celočíselná numerická položka nebo celočíselný numerický literál, příkaz "SET I K UP BY N" dosadí do I hodnotu I + N*di a do K hodnotu K + N*dk, čímž zvětší obě odpovídající pořadí o N; příkaz "SET I DOWN BY N" dosadí do I hodnotu I - N*di, čímž zmenší odpovídající pořadí o N. Je-li N celočíselný numerický literál, provede se jeho vynásobení délkou di resp. dk již během překladu.) d) Stojí-li za SET celočíselná numerická položka a za UP (DOWN) speciální index, zvětší (zmenší) se hodnota této položky o hodnotu speciálního indexu uvedeného za UP (DOWN) vydělenou příslušnou délkou (bere se celá část podílu). (Např. je-li N celočíselná numerická položka, pak příkaz "SET N UP BY I" dosadí do N hodnotu N + I / di a příkaz "SET N DOWN BY K" dosadí do N hodnotu N - K / dk). Příklad: 77 N PIC S9(3) COMP-3 VALUE 15. 77 U USAGE INDEX. 01 A. 02 B PIC X(7) OCCURS 100 INDEXED I J. 02 C OCCURS 200 INDEXED K. 04 D PIC X(3). 04 E PIC 99. Zde je di = dj = 7 (délka B), dk = 5 (délka C). Příkaz SET K TO N dosadí K = (15 - 1) * 5 = 70, takže odpovídající pořadí je 15. Příkaz SET I U TO K dosadí I = (70 / 5) * 7 = 98, takže odpovídající pořadí je 15, a dále U = 70. Příkaz SET J TO U dosadí J = 70, takže odpovídající pořadí je 70 /7 + 1 = 11 (pozor, neobvyklý obrat!!!). Příkaz SET N TO J dosadí N = (70 / 7) + 1 = ll. Příkaz SET I DOWN BY 6 dosadí I = 98 - (6 * 7) = 56, takže odpovídající pořadí je 56 / 7 + 1 = 9. Příkaz SET K UP BY N dosadí K = 70 + (11 * 5) = 125, takže odpovídající pořadí je 125 / 5 + 1 = 26. Formát 3: SET UPSI TO řetězec Pravidlo: Údaj "řetězec" uvedený za slovem TO musí být tvořen nejvýše osmiznakovou posloupností znaků 0, 1 a X, která může být uvedena v apostrofech anebo i bez apostrofů. Má-li "řetězec" délku menší než 8 znaků, bude zpracováván tak, jako kdyby byl vpravo doplněn do 8 znaků samými znaky X. Funkce: Příkaz SET formátu 3 provádí nastavení jednotlivých bitů v UPSI-bytu. První znak řetězce určuje nastavení prvního bitu v UPSI-bytu (hex. 80), druhý znak řetězce určuje nastavení druhého bitu v UPSI-bytu (hex. 40) atd., až osmý znak řetězce určuje nastavení osmého bitu v UPSI-bytu (hex. 01). Znak 0 v řetězci způsobí nastavení příslušného bitu na hodnotu 0, znak 1 v řetězci způsobí nastavení příslušného bitu na hodnotu 1, znak X v řetězci způsobí, že původní hodnota příslušného bitu zůstane beze změny. (Má-li řetězec méně než 8 znaků, zůstanou tedy poslední bity v UPSI-bytu beze změny). Příklady: Příkaz "SET UPSI TO 00000000" vynuluje celý UPSI-byte. Příkaz "SET UPSI TO XXXX1" nastaví 5.bit v UPSI-bytu (hex. 08) na hodnotu 1; ostatní bity v UPSI-bytu zůstanou beze změny. Příkaz "SET UPSI TO X10X0XX1 nastaví bity 40 a 01 na hodnotu 1, bity 20 a 08 na hodnotu 0; ostatní bity v UPSI-bytu zůstanou beze změny.