Programovací jazyk Ada: formátování čísel, výjimky a úvod do Eclipse

2. 7. 2015
Doba čtení: 10 minut

Sdílet

Minule jsme rozšířili jednoduchou verzi procedury pro výpočet kořenů kvadratické rovnice na komplexní kořeny a ukázali si použití formátovaných výstupů pro numerické hodnoty. Dnes se podíváme na další možnosti formátování numerických výstupů a na řešení výjimek. Díl zakončíme úvodem do vývojového prostředí Eclipse.

Když už jsme v minulém dílu narazili na formátování číselných výstupů, ukážeme si ještě jednu zajímavou možnost. Změníme náš kód a přidáme několik nových příkazů:

  1. do úvodní sekce přidáme kód:
    with Ada.Integer_Text_IO;
  2. do deklarací přidáme dva řádky:
    package IIO renames Ada.Integer_Text_IO;
    int : Integer := 10;
  3. na konec přidáme několik příkazů na zobrazení nové celočíselné proměnné:
    TIO.New_Line;
    TIO.Put("INT-B10 = ");
    IIO.Put(Item => Int, Width => 3, Base => 10);
    
    TIO.New_Line;
    TIO.Put("INT-B2 = ");
    IIO.Put(Item => Int, Width => 8, Base => 2);
    
    TIO.New_Line;
    TIO.Put("INT-B8 = ");
    IIO.Put(Item => Int, Width => 8, Base => 8);
    
    TIO.New_Line;
    TIO.Put("INT-B16 = ");
    IIO.Put(Item => Int, Width => 8, Base => 16);

Kód přeložíme a spustíme novou aplikaci, které zobrazí tyto výsledky:

Vysledky reseni: R
K1 =  -0.381966   0.000000 i
K2 =  -2.618034   0.000000 i
INT-B10 =  10
INT-B2 =  2#1010#
INT-B8 =    8#12#
INT-B16 =    16#A#

Jak je vidět, podařilo se nám zobrazit jedno zadané celé číslo ve čtyřech různých číselných soustavách bez jakéhokoliv explicitního převodu či konverze. Tímto uzavřeme kapitolu o formátování výstupů a pustíme se do avizovaného zpracování výjimek. V našem konkrétním příkladu jsme již vyloučili problém se záporným diskriminantem a zůstalo nám pouze jedno riziko – hodnota koeficientu A = 0. Pokud bychom toto riziko nechali být a zkusili tento případ přeložit a spustit, bude výsledek následující:

  • překlad proběhne bez problémů, protože typy formálního a aktuálního parametru jsou stejné
  • spuštění vyhodí pro koeficienty 0.0, 3.0 a 1.0 tento výsledek:
    Vysledky reseni: R
    K1 = NaN*******   0.000000 i
    K2 = -Inf******   0.000000 i

Jak je vidět, výpočet proběhl, ale dělení nulou se projevilo zobrazením extrémních hodnot. V daném případě je určitě zřejmé, že se přihodilo něco divného. Bylo by ale lepší tuto situaci řešit nějak jinak – obecněji a naprosto jednoznačně. K tomu je samozřejmě možné použít běžnou podmínku, ale my si ukážeme systém pro zachycení a zpracování výjimek, který je v každém programovacím jazyce dost důležitý pro rozumnou práci. Jazyk Ada disponuje poměrně rozsáhlými možnostmi pro zpracování výjimek. Je zde možné použít jednak standardní předefinované typy výjimek nebo výjimky uživatelsky definované. My si v rámci článku ukážeme zase spíše trochu násilný a velmi jednoduchý příklad, který bude stačit pro základní ilustraci. Ve výukovém kurzu bude řešení výjimek probráno mnohem podrobněji včetně konkrétních příkladů pro terminálové i grafické aplikace. Více se případní zájemci mohou o zpracování výjimek dozvědět třeba zde:

My si uděláme pár změn v souboru kvadrov.adb a jednu v souboru solve.adb. V následujících příkladech kódu budou označené pouze nově přidané řádky:

with Ada.Numerics.Elementary_Functions; use  Ada.Numerics.Elementary_Functions;

package body kvadrov is

procedure Quadra (A, B, C : in  Float; R1, R2, I1, I2 : out Float; Result : out Character) is
   D, Z : Float;
   chyba : exception;                                           --1
begin

    if A = 0.0 then                                         --2
        raise chyba;                                        --3
    end if;                                             --4

   D := B**2 - 4.0 * A * C;
   Z := 2.0 * A;
   if D < 0.0 then
      Result := 'K';
      R1 := -B / Z;
      R2 := R1;
      I1 := Sqrt (-D) / Z;
      I2 := -Sqrt (-D) / Z;
   elsif D = 0.0 then
      Result := 'D';
      R1 := -B / Z;
      R2 := R1;
      I1 := 0.0;
      I2 := I1;
   else
      Result := 'R';
      R1 := (-B + Sqrt (D)) / Z;
      R2 := (-B - Sqrt (D)) / Z;
      I1 := 0.0;
      I2 := I1;
   end if;

    exception                                           --5
      when chyba => Result := 'E';                                   --6
            return;                                     --7

   end Quadra;

begin

   null;

end kvadrov;
  • 1. řádek – deklarována uživatelsky definovaná výjimka
  • 2. – 4. řádek – před začátkem výpočtů je proveden test a případné zachycení výjimky
  • 5. řádek – zahájeno zpracování zachycené výjimky
  • 6. řádek – výstupní parametr nastaven na hodnotu E
  • 7. řádek – ukončeno provádění procedury

Do souboru solve.adb se přidají pouze čtyři řádky, kde se testuje hodnota výsledkového parametru, vypisuje se chybové hlášení a ukončuje běh procedury:

if vysledek = 'E' then
    TIO.Put_Line(" Vypocet prerusen z duvodu spatneho zadani koeficientu!");
    return;
end if;

Pokud přeložíme a spustíme aplikaci se stávajícím zadáním, skutečně dostaneme očekávaný výsledek:

 Vypocet prerusen z duvodu spatneho zadani koeficientu!

Výsledný kód všech tří použitých souborů je v přílohách solv.adbkva­drov.ads a kvadrov.adb.

Nyní už nic nebrání tomu, abychom se pustili do avizovaného prostředí Eclipse. Jeho instalaci zahájíme stažením všech potřebných souborů a pro aktuální verzi GNAT 2014 si stáhneme balíček – GNATbench. Konkrétně je to vidět na prvním obrázku v první galerii. Po stažení balíček jako root rozbalíme do nově vytvořeného adresáře /opt/gnatbench.

Samotné vývojové prostředí Eclipse asi není nutné nijak podrobně představovat a proto rovnou přikročíme k jeho stažení, instalaci a zprovoznění pluginu GNATbench. Jako první si otevřeme stránku Eclipse Download a stáhneme si verzi Eclipse IDE for C/C++ Developers pro Linux 64 bit – balíček eclipse-cpp-luna-SR1a-linux-gtk-x86_64.tar.gz (nebo nějaký jiný, aktuálnější). Jako běžný uživatel tento balíček rozbalíme např. do adresáře $HOME/Apps/eclipse. Z tohoto adresáře Eclipse spustíme opět jako běžný uživatel. Ještě před startem se objeví formulář s nastavením pracovního adresáře Eclipse. Necháme v něm přednastavenou hodnotu a zaškrtneme volbu pro standardní nastavení tohoto adresáře bez následných dotazů – viz druhý obrázek první galerie. Po spuštění Eclipse použijeme menu Help → Check for Updates a necháme proběhnout hledání aktualizací. Pokud se nějaké aktualizace objeví, tak je instalujeme. V našem případě ale v daném čase žádné k dispozici nebyly.

Nyní tedy můžeme přistoupit k instalaci pluginu GNATbench. K tomu budeme potřebovat znovu hlavní menu: Help → Install New Software. Otevře se formulář, který je na třetím obrázku v první galerii. V něm musíme přidat adresář, který obsahuje GNATbench. Klikneme na tlačítko Add… vpravo nahoře a otevřeme další formulář – viz čtvrtý obrázek v galerii. Do formuláře doplníme jméno a pomocí tlačítka Local… najdeme a otevřeme adresář /opt/gnatbench. Výsledek je vidět na pátém obrázku první galerie. Přidání adresáře potvrdíme tlačítkem OK. Následně se v dostupných možnostech objeví tři varianty – viz šestý obrázek. Z nich se zaškrtne ta první – AdaCore Plugins for Eclipse/CDT a klikne na tlačítko Next >. Poté se objeví detaily instalace – viz sedmý obrázek v první galerii a my pokračujeme znovu tlačítkem Next >. Na dalším formuláři odsouhlasíme licenci a zahájíme instalaci tlačítkem Finish. V jejím průběhu se ještě objeví požadavek (viz osmý obrázek v první galerii) na potvrzení důvěryhodnosti certifikátu AdaCore, což samozřejmě provedeme. Po ukončení instalace se zobrazí možnost restartu Eclipse, kterou využijeme.

Nyní máme nově spuštěné Eclipse, které již obsahuje námi požadovaný plugin. O jeho přítomnosti se můžeme přesvědčit dvěma způsoby. První z nich si ukážeme hned. Spustíme položku hlavního menu Window → Open Perspective → Other → Ada a zavřeme okno Welcome. Uvidíme před sebou hlavní okno Eclipse s nastavenou perspektivou Ada, jak to ukazuje předposlední obrázek první galerie. Druhou možnost nám nabízí hlavní menu File → New, pod kterým se skrývá několik variant pro práci s projekty a soubory Ada. Jak ukazuje poslední obrázek v první galerii, jsou mezi nimi dokonce i takové, se kterými jsme se doposud nesetkali – AJIS (oboustranné propojení Ada ↔ Java) a Android. To zase trochu demonstruje možnosti jazyka a systému Ada…

Ve vývojovém systému tedy máme k dispozici dvě vývojová prostředí – GPS a Eclipse + GNATbench plugin. GPS je samozřejmě primárně zaměřené na jazyk Ada, ale je možné v něm využívat i další jazyky. Naopak Eclipse je velmi obecné a široce pojaté prostředí, kde je možný vývoj snad ve všem, na co si člověk vzpomene. Přizpůsobení konkrétním požadavkům se potom děje instalací různých pluginů, které jsou k dispozici přímo na stránkách projektu nebo na webech tvůrců. Na první pohled je zřejmé, že celé prostředí je velmi komplexní a tím pádem docela komplikované. Je zde samozřejmě jasná výhoda pro ty, kteří sice nikdy nepoužili jazyk Ada, ale jsou obeznámeni s prostředím Eclipse. Pro ty ostatní je k dispozici značné množství různých návodů jak na samotné Eclipse, tak i na GNATbench. Nemá asi smysl zde všechny možnosti vyjmenovávat, proto uvedeme jenom jeden zdroj, kterým je přímo AdaCore. Tam je možné najít online verzi dokumentace ke GNATbench: GNATbench online dokumentace. Je zde také k dispozici PDF verze, která na cca 290 stranách přináší mnoho důležitých a zajímavých informací: GNATbench PDF dokumentace

Asi nejlogičtější začátek s novým vývojovým prostředím představuje vytvoření jednoduchého projektu, který bude obsahovat pouze „obvyklé“ Hello World. Začneme tedy tím, že si spustíme Eclipse a pokud to již nemáme, přepneme si do perspektivy Ada. To je možné jak z hlavního menu, tak pomocí ikony v pravém horním rohu (zde jsou k dispozici dvě perspektivy – C/C++ a Ada). Výše v textu jsme se dozvěděli, že nový projekt je možné založit pomocí menu File → New. Je tu ale i druhá možnost, která je o něco jednodušší a rychlejší – použít spouštěcí ikony pod hlavním menu. Jejich přehled je vidět na první pohled do otevřeného hlavního okna Eclipse. Kompletní nabídka (totožná s výše uvedenou položkou hlavního menu) se skrývá pod ikonou úplně vlevo. Pak následují tři ikony pro ukládání a tisk souborů. Pak následuje druhá sekce tří ikon, které nás budou zajímat nejvíce. Zleva se jedná o tyto akční ikony: New Ada Project, New Ada Source File a New Ada Source Folder.

My nyní použijeme první z nich a založíme si nový projekt. Jak vidíme na prvním obrázku druhé galerie, objeví se formulář, kde se zadá název projektu a může se nastavit cílový adresář. My necháváme přednastavený cíl a pokračujeme tlačítkem Next >. Na dalším obrázku druhé galerie vidíme, že se objevil následující formulář, kde je již přednastavené jméno projektové jednotky, shodné s názvem projektu. Necháme vše beze změny a můžeme pokračovat buď pomocí Next > nebo Finish. My kvůli příkladu volíme Next >. Objeví se další formulář, kde se zadává název hlavního podprogramu Ada (obdoba Main Files v GPS) – viz třetí obrázek druhé galerie. Pokud nějaký název zadáme, objeví se možnost generování souboru, který tento podprogram obsahuje. Pokud tuto možnost zaškrtneme, objeví se ještě jedna další – generovat hlavní podprogram, který obsahuje přímo aplikaci Hello World. My vybereme obě možnosti – viz další obrázek ve druhé galerii a pokračujeme dalším Next >. V dalším formuláři – viz pátý obrázek ve druhé galerii, můžeme nastavit adresáře pro uložení objektových, spustitelných a zdrojových souborů. Ponecháme zde vše, jak je přednastaveno, a pokračujeme Next >.

Pak následuje formulář, kde se nastavují parametry pro sestavení. Jsou zde jednak volby pro verzi jazyka Ada (2012, 2005 a 1995) a možnost generování scénáře pro produkci a ladění. V dolním okně je pak přehled tzv. Toolchains (pokud jich tedy existuje víc. Jedná se vlastně o možnost nastavení různých verzí překladače Ada a dalších důležitých součástí systému) a možnost volby nástrojů pro překlad. Jak je vidět na šestém obrázku druhé galerie, je zde k dispozici pouze jedna sada – native ve verzi 4.8.2. Toto nastavení odpovídá prapůvodně instalované verzi balíku gcc-gnat. Vpravo je vidět sadu čtyř ikon pro manipulaci s těmito nástroji (Scan, Add, Modify a Remove). My si zatím ukážeme jenom tu první a spustíme příkaz Scan. Bohužel se ukáže pouze chybové hlášení o tom, že je vyžadována novější verze aplikace GPRbuild (viz další obrázek). Zatím nemá smysl tento problém řešit, takže necháme vše tak, jak to je a ukončíme vytvoření projektu tlačítkem Finish. Na posledním obrázku druhé galerie pak vidíme prostředí Eclipse, kde došlo k vytvoření projektu a jeho celá struktura je viditelná v levém okně Project Explorer. V hlavním okně je pak vidět otevřený soubor main.adb. Ve spodním okně Console je pak vidět, že při založení projektu proběhl automatický překlad a byla vytvořena spustitelná aplikace.

Než se pustíme dál, jenom krátce se podíváme na vygenerovaný kód v souboru main.adb:

with GNAT.IO;  use GNAT.IO;  --1
procedure main is        --2
begin                    --3
   Put_Line ("Hello World!");    --4
end main;                --5

Vidíme, že kód má pouze 5 řádků, které na první pohled můžeme považovat za důvěrně známé. Pokud bychom ho srovnali s kódem, který jsme vytvořili hned v prvním dílu našeho seriálu, uvidíme odlišnosti jasněji:

with Ada.Text_IO;  use Ada.Text_IO;    --  1
procedure Hello is                     --  2
begin                                  --  3
   Put_line ("Hello world from ADA!"); --  4
end Hello;                             --  5

Když pomineme název procedury a text, který se zobrazuje při spuštění, tak je zásadní rozdíl pouze na prvním řádku. Původní příklad používá pro výstup na konzoli knihovnu Ada.Text_IO a ten nový knihovnu GNAT.IO. O té se můžeme dočíst v ALRM asi toto:

bitcoin_skoleni

12.80. GNAT.IO (g-io.ads)
A simple preelaborable input-output package that provides a subset of simple Text_IO functions for reading characters and strings from Standard_Input, and writing characters, strings and integers to either Standard_Output or Standard_Error.

O celé knihovně je zda samozřejmě také řeč, takže pro případné zájemce: knihovna GNAT

V dnešním dílu jsem si ukázali další možnosti formátování numerických výstupů a velmi jednoduchý příklad na zachytávání a zpracování výjimek. Díl jsme pak ukončili instalací a zprovozněním vývojového prostředí Eclipse s příslušným pluginem včetně vytvoření jednoduchého projektu. V příštím dílu se budeme vývojovým prostředím Eclipse zabývat podrobněji.

Autor článku