I.  

ZÁKLADNÍ  POJMY


Přesný předpis pro výkon nějaké činnosti, prováděné procesorem počítače, se nazývá program. Program je procesoru předkládán ve tvaru kódu, tj. jako posloupnost instrukcí procesoru — elementárních příkazů, které je daný procesor schopen přímo provádět. Autor formuluje program pomocí vhodného (a jemu známého) programovacího jazyka, ve tvaru zdrojového textu programu, jehož konverzi na proveditelný kód příslušného procesoru zajišťuje překladač.

Podle celkové strategie překladu lze překladače klasifikovat kompilační a interpretační — kompilátoryinterprety. Kompilátor je konverzní program, který přeloží hotový zdrojový text programu na cílový kód. Podmínkou získání spustitelného programu je bezchybné ukončení překladu v celém jeho rozsahu. Cílový kód je pak provozován nezávisle na kompilátoru, pokud však je třeba jeho činnost modifikovat, je nutné znovu přeložit celý zdrojový text. Interpret má pro spouštěný program funkci operačního prostředí — postupně čte, překládá a ihned vykonává jednotlivé příkazy (nebo větší jednotky) zdrojového textu. Výskyt jakékoliv chyby v textu je zjištěn až v okamžiku překladu chybného příkazu za běhu programu. Pokud se tentýž (bezchybný) příkaz provádí vícekrát, je před každým provedením znovu přeložen.

Výhody a nevýhody obou koncepcí překladu jsou zřejmé. Interpretovaný program umožňuje interaktivní modifikaci rozsahu dat nebo dokonce zdrojového textu přímo za běhu, je však relativně pomalý a spustitelný pouze prostřednictvím překladače. Kompilátor připraví efektivní nezávislý program, který udržuje v operační paměti počítače pouze svůj kód a svá data, jehož prostředky pro interaktivní změny jsou však značně omezené.

Turbo Pascal   Je nejrozšířenější implementací jazyka Pascal. Na rozdíl od prvních implementací původního Pascalu, navrženého v roce 1971 profesorem N. Wirthem především pro výuku programování (viz například publikaci [Jinoch]), je Turbo Pascal značně výkonnější prostředek.

Vývojové prostředí Turbo Pascalu integruje textový editor (pro pořizování a úpravy zdrojových textů), kompilační překladač, linker (prostředek pro sestavení cílového kódu z produktů překladu jednotlivých modulů programu) a debugger (ladicí prostředek). Podrobný popis ovládání vývojového prostředí lze nalézt v jeho nápovědě i v řadě příruček (viz například publikaci [Mikula]), tento text se jím nezabývá.

I.1. 

Lexikální elementy a jejich oddělovače

Zdrojový text programu v jazyku Turbo Pascal je posloupností lexikálních elementů, vzájemně oddělených oddělovači. Lexikální elementy jsou nedělitelné v tom smyslu, že se uvnitř nich nesmí vyskytovat žádný oddělovač. Lze je klasifikovat do následujících skupin:

Speciální symboly   Speciální symboly jsou následující znaky a dvojice znaků. Jejich význam je jazykem pevně stanoven (některé symboly mají více významů, aktuální význam v takovém případě vyplývá z kontextu).

Jednoznakové speciální symboly:

+  -  *  /  =  <  >  [  ]  (  )  {  }  .  ,  :  ;  ^  @  $  #
Dvouznakové speciální symboly:
<=  >=  <>  :=  ..  (.  .) (*  *)
Rezervovaná slova a direktivy   Rezervovaná slova slouží jako oddělovače různých konstrukcí v deklaracích a příkazech, jako operátory, ohraničení jistých úseků zdrojového textu apod. Syntax jazyka nepřipouští jejich předefinování. Rovněž direktivy jazyka mají pevně stanovený význam, na rozdíl od rezervovaných slov však není zakázáno je předefinovat. Rezervovaná slova i direktivy se skládají vesměs z písmen anglické abecedy, velikost písmen není rozlišována. Zapisují se obvykle minuskami.

rezervovaná slova:

and

end

nil

shr
asmfilenotstring
arrayforobjectthen
beginfunctionofto
casegotoortype
constifpackedunit
constructorimplementationprocedureuntil
destructorinprogramuses
divinlinerecordvar
dointerfacerepeatwhile
downtolabelsetwith
elsemodshlxor

direktivy:

absolute

far

interrupt

private
assemblerforward nearvirtual
external

Identifikátory   Identifikátory jsou používány jako označení (jména) programů, programových jednotek, návěští, konstant, typů, proměnných, komponent záznamů, procedur a funkcí. Identifikátor je posloupností „písmen“ a „číslic“, začínající „písmenem“. Mezi „písmena“ patří velká i malá písmena anglické abecedy a podtržítko (_), „číslicemi“ jsou dekadické číslice (0 až 9). Délka identifikátorů není jazykem omezena, identifikátor se však nesmí shodovat s žádným rezervovaným slovem a je rozlišován pouze podle prvních 63 znaků, přičemž nejsou rozlišována písmena malá od velkých (identifikatorIDENTIFIKATOR jsou totožné identifikátory). Verzálky se však zpravidla uvádějí jen na začátku dílčích slov identifikátoru (například BarvaRamecku).

Obrázek 1: Syntax identifikátoru


Popis syntaxe identifikátoru, uvedený na obrázku 1, se nazývá syntaktický diagram. Přípustný tvar definovaného prvku (v tomto případě identifikátoru) lze získat každým průchodem syntaktického diagramu zleva doprava, při respektování naznačeného směru v jednotlivých větvích. Elementární symboly jsou uvedeny v oválech, odvozené v rámečcích.

Návěští   Návěští označují ve zdrojovém textu příkaz, na nějž je směřován příkaz skoku goto. Návěštím může být buď identifikátor nebo celé číslo z intervalu <0, 9999>.

Číselné literály   Používají se ve zdrojovém textu jako nepojmenované číselné konstanty bez znaménka v dekadickém nebo hexadecimálním zápisu. Případné znaménko před číslem je (na rozdíl od znaménka exponentu) samostatný lexikální element (speciální symbol), proto se mezi ním a číslem může vyskytovat oddělovač. Celočíselný literál musí spadat do rozsahu hodnot celočíselného typu LongInt, reálný pak do rozsahu hodnot reálného typu Extended.

Obrázek 2: Syntax číselných literálů






Následují příklady správně zapsaných číselných literálů (hodnota prvních tří je celočíselná, zbývajících reálná):

123      $7B    $7b
123.00   123.   123E0   0.123e3   1230E-1   123e-
Řetězcové literály   Řetězcový literál je nepojmenovaná řetězcová konstanta, tedy posloupnost žádného nebo více libovolných znaků, uzavřená v apostrofech a uvedená na jediné řádce zdrojového textu programu. Dvojice sousedících apostrofů uvnitř zápisu řetězce má význam jediného znaku apostrof v hodnotě řetězce.

Pro konstrukci řetězcových literálů jsou navíc k dispozici speciální konstruktory # a ^, určené především pro zápis tzv. řídících znaků. Ty totiž nelze v řetězci zapsat přímo, neboť jejich výpisu na displeji neodpovídá „obrázek znaku“, nýbrž nějaká činnost (například posun kurzoru). Za symbolem # se uvádí ASCII kód znaku, který má být takto zkonstruován, kdežto symbol ^, následovaný libovolným zobrazitelným znakem, má význam znaku, který by jinak byl generován po stisku příslušné klávesy s přeřazovačem CTRL.

Obrázek 3: Syntax řetězce znaků

Ze syntaktického diagramu na obrázku 3 je zřejmé, že v zápisu řetězcového literálu je dovoleno kombinovat všechny způsoby konstrukce jeho znaků. „Znak řetězce“ je libovolný zobrazitelný znak vyjma apostrofu a konce řádky (zápis celého řetězce musí být uveden na jediné řádce zdrojového textu), celé číslo bez znaménka musí být z intervalu <0, 255>.

'řetězcový literál'
'''řetězcový literál'''
'první řádka'#10#13'druhá řádka'
#7'akustický signál'
^G'akustický signál'
Oddělovače lexikálních elementů   Oddělovače se mohou vyskytovat ve zdrojovém textu programu v libovolném počtu, avšak pouze mezi lexikálními elementy (nikoliv uvnitř lexikálních elementů). Pokud není alespoň jeden z dvojice sousedních lexikálních elementů speciálním symbolem, musí být mezi nimi uveden nejméně jeden oddělovač, mezi jinými dvojicemi lexikálních elementů jsou oddělovače nepovinné. Lze použít kterýkoliv z oddělovačů

Komentář je posloupnost libovolných znaků, ohraničená buď složenými závorkami {} nebo symboly (* a *) a neobsahující symbol, kterým je označen její konec:

{libovolný text, neobsahující pravou složenou
 závorku}
(*libovolný text, neobsahující hvězdičku
  a bezprostředně následující pravou oblou závorku*)
{toto (* je *) dovoleno}
(* a { toto } také*)
{toto není dovoleno*)
(*a toto také ne}
Pokud je bezprostředně za počátečním symbolem komentáře uveden znak $, je následující text komentáře chápán jako direktiva kompilátoru. Těmito direktivami lze řídit a modifikovat činnost překladače programu. Seznam direktiv a popis jejich vlivu na proces překladu obsahuje závěrečná kapitola Řízení překladu.

Komentáře, záměrně umístěné z dokumentačních důvodů ve zdrojovém textu programu, je výhodné důsledně ohraničovat jediným typem komentářových závorek a druhý typ používat při ladění programu k dočasné eliminaci vybraných částí zdrojového textu, které pak mohou obsahovat komentářové závorky prvního typu.

Vzhledem k rovnocennosti konce řádky a ostatních oddělovačů lexikálních elementů nezáleží na dělení zdrojového textu na jednotlivé řádky. Oddělovače se také mohou uvádět vícenásobně, neboť kde je povolen výskyt jednoho oddělovače, je současně povolen výskyt libovolného počtu oddělovačů. Tato pravidla poskytují pro formální úpravu zdrojových textů poměrně široký prostor, umožňující lámat řádky textu a odsazovat jednotlivé prvky řádek se zřetelem na přehlednost zápisu. V každé řádce může být celkem uvedeno až 128 znaků, zpravidla se však uvádí jen tolik, aby text nepřesáhl šíři obrazovky. Pro pozdější ladění programu krokováním po jednotlivých řádkách je výhodné uvádět na každé z nich nejvýše jeden příkaz (resp. na společné řádce uvádět jen takové příkazy, které nebude třeba provést v oddělených krocích).

I.2. 

Struktura zdrojového textu programu

Zdrojový text programu se skládá z hlavičky programu, klauzule uses, blokuzávěrečné tečky. Hlavička programu a klauzule uses jsou však nepovinné.

Obrázek 4: Struktura programu

Hlavička programu   Je nepovinná, pokud je však uvedena, musí být uvedena jako první (mohou ji předcházet pouze komentáře, direktivy kompilátoru a jiné oddělovače). Obsahuje rezervované slovo program a identifikátor programu, ukončena je středníkem.

Obrázek 5: Hlavička programu

V Turbo Pascalu má hlavička programu pouze dekorativní význam — na identifikátor programu se není možno nijak odkazovat.


POZNÁMKA: Ve standardním Pascalu obsahuje hlavička za identifikátorem programu ještě seznam jeho parametrů — souborů dat, se kterými program pracuje. V Turbo Pascalu je mechanismus zpracování datových souborů odlišný. Hlavička programu sice smí (pro zachování kompatibility) seznam parametrů obsahovat, ten však nemá žádný význam (je překladačem ignorován).

Klauzule uses   Je nepovinná, pokud je však uvedena, musí být uvedena před blokem programu. Obsahuje seznam identifikátorů všech externích programových jednotek (například knihoven podprogramů), jejichž prostředky program využívá. Identifikátory jsou v seznamu odděleny čárkami, klauzule je ukončena středníkem.

Obrázek 6: Klauzule uses

Blok   Poslední částí programu před závěrečnou tečkou je blok, obsahující deklaračnípříkazovou část. Za závěrečnou tečkou může následovat libovolný další text, ten však již není při překladu brán v úvahu.

Obrázek 7: Blok

V deklarační části bloku musí být deklarovány veškeré dosud neznámé objekty (návěští, konstanty, datové typy, proměnné a podprogramy), použité v jeho části příkazové. Deklarací je (kromě jiného) přidělen deklarovanému objektu identifikátor, prostřednictvím nějž je možno se v následujícím textu bloku na objekt odkazovat. Pořadí deklarací jednotlivých objektů není předepsáno, podmínkou však je, aby každá deklarace nového objektu obsahovala odkazy pouze na objekty již deklarované.

Deklarační část je rozčleněna na několik úseků. V každém z těchto úseků jsou uvedeny deklarace objektů stejného druhu. Ze syntaktického hlediska sice není nutné, aby všechny objekty stejného druhu (například všechny proměnné) byly deklarovány v jediném společném deklaračním úseku, je to však prospěšné pro přehlednost zdrojového textu. Syntaxe jednotlivých úseků jsou dále popsány v kapitolách, zabývajících se odpovídajícími programovými objekty.

Obrázek 8: Deklarační část bloku

Příkazovou část bloku tvoří předpis pro vlastní výpočet — posloupnost jazykem definovaných příkazů, vzájemně oddělených středníky, ohraničená rezervovanými slovy beginend.

Obrázek 9: Příkazová část bloku

V následujícím zdrojovém textu je uvedena hlavička, klauzule uses chybí (program nevyužívá žádné externí programové jednotky), deklarační část obsahuje pouze úsek deklarací proměnných, příkazová část šest příkazů.

{======================================================================}
program Vypocet_souctu;
{======================================================================}

 var Scitanec1, Scitanec2, Soucet: Integer;

begin { program }
 Write ('první sčítanec: ');                        { zadání hodnoty   }
 ReadLn (Scitanec1);                                { prvního sčítance }
 Write ('druhý sčítanec: ');                        { zadání hodnoty   }
 ReadLn (Scitanec2);                                { druhého sčítance }
 Soucet := Scitanec1 + Scitanec2;                   { výpočet součtu   }
 WriteLn (Scitanec1, ' + ', Scitanec2,              { tisk výsledku    }
          ' = ', Soucet)
end. { program }

I.3. 

Konstanty

Hodnota konstant je známa už při psaní zdrojového textu programu a v průběhu jeho výpočtu se nemění. Do zdrojového textu je možno konstanty vkládat přímým zápisem jejich hodnoty nebo jim deklarací přidělit symbolické jméno — identifikátor — a namísto nepojmenované konstanty dále používat identifikátor. Náhradou nepojmenovaných konstant (především vícenásobného výskytu) konstantami pojmenovanými se zvyšuje srozumitelnost zdrojového textu a zjednodušuje jeho modifikace. Konstanty jsou deklarovány v úsecích deklarací konstant.

Obrázek 10: Úsek deklarací konstant

Větev syntaktického diagramu, v níž chybí typ konstanty, popisuje deklaraci „pravé“ konstanty — uvedenému identifikátoru konstanty je přidělena konstantní hodnota, získaná vyhodnocením výrazu. Typ takto získané hodnoty smí být v zásadě libovolný, podmínkou však je, aby výraz byl konstantním výrazem — jeho hodnota musí být vyčíslitelná již kompilátorem v okamžiku kompilace. Konstantní výraz proto nesmí obsahovat jednak nekonstantní operandy a jednak operace a funkce, které kompilátor vyhodnotit nedokáže. V tomto smyslu je zakázaným operátorem pouze adresní operátor @, funkce jsou naopak zakázány téměř všechny, vyjma následujících:

Abs, Chr, Hi, Length, Lo, Odd, Ord, Pred, Ptr, Round, SizeOf, Succ, Swap, Trunc
Pokud v deklaraci typ konstanty uveden je, je deklarována konstanta s udaným typem (typová konstanta). Označení konstanta je v názvu objektů tohoto druhu uvedeno pouze proto, že jsou deklarovány v úsecích deklarací konstant. Ve skutečnosti představují nikoliv konstanty, nýbrž proměnné s inicializovanou počáteční hodnotou. Těmto proměnným je na začátku výpočtu programu přiřazena specifikovaná počáteční hodnota a dále je s nimi možno nakládat jako s kterýmikoliv jinými proměnnými (stejného typu). Počáteční hodnota typové konstanty může mít buď tvar konstantního výrazu nebo některý z dalších tvarů, uvedených v syntaktickém diagramu na obrázku 6, podle deklarovaného typu. Syntax těchto tvarů je dále rozvedena v kapitolách, zabývajících se odpovídajícími typy.

V níže uvedeném úseku deklarací konstant jsou prvními třemi deklaracemi deklarovány konstanty, čtvrtou deklarací proměnná. Pokus o deklaraci konstanty PocetZnaku způsobí při překladu chybu — výraz za rovnítkem totiž není konstantní (PocetRadek je proměnná).

const DelkaRadky   = 80;
      Nadpis       = 'Deklarace konstant';
      PoziceVypisu = (DelkaRadky - Length(Nadpis)) div 2 + 1;
      PocetRadek   : Word = 25;
      PocetZnaku   = PocetRadek * DelkaRadky;

I.4. 

Proměnné

Proměnná je datový objekt, jehož hodnota se může v průběhu výpočtu programu měnit. Proměnné jsou deklarovány v úsecích deklarací proměnných (proměnné s definovanou počáteční hodnotou v úsecích deklarací konstant). Deklarací je proměnné přidělen datový typidentifikátor, prostřednictvím kterého je možno se na proměnnou dále odkazovat. Podle uvedeného typu je proměnné přiděleno paměťové místo odpovídající velikosti a identifikátor má význam symbolické adresy tohoto místa. Přidělením typu je také definován obor přípustných hodnot proměnné a množina jazykem definovaných operací, které lze nad těmito hodnotami provádět. Typ lze uvést souhrnně pro více proměnných (tohoto typu) v jediné deklaraci. Použitím direktivy absolute lze alokovat proměnnou na zvolené místo v operační paměti (viz absolutní proměnné).

Obrázek 11: Úsek deklarací proměnných

var I, J, K : Integer;
    L       : Integer;
    P1, P2  : array [1..10] of Real;
    P3      : array [1..10] of Real;
Definice hodnoty proměnné   Deklarací není proměnné (pokud se nejedná o typovou konstantu) přidělena hodnota. Hodnota proměnné zůstává nedefinovaná, dokud není určena například přiřazovacím příkazem. Definovanou a nedefinovanou hodnotu proměnné nelze v Turbo Pascalu nijak rozlišit. Proměnná prostě má nějakou hodnotu, danou interpretací náhodného nebo programem již definovaného obsahu paměťového úseku, který jí byl přidělen.

Hodnotu proměnné lze definovat především přiřazovacím příkazem. Na levé straně symbolu přiřazení (:=) je uvedena proměnná a na pravé výraz, jehož hodnota bude vypočtena a proměnné přiřazena (dosazena do proměnné). Přitom musí být respektována kompatibilita typu proměnné a přiřazované hodnoty (není možné například číselné proměnné přiřazovat znakovou hodnotu).

var I    : Integer;
    R, S : Real;
...
I := 7;
R := 77.0;
S := R * R;
...