A Sather programozási nyelv

Vezérlési szerkezetek



A legegyszerűbb szerkezet természetesen a szekvencia, jelölése a pontosvessző. Az Eiffeltől eltérően (ahol ez opcionális: ha kiírjuk nem gond, de az sem, ha elhagyjuk) itt ki kell írnunk.

Értékadások, kifejezések

Az értékadások szignatúráját és jelentését, valamint egyszerű kifejezések megadásának módjait az előző fejezetben a változók deklarációs lehetőségei kapcsán már bemutattuk.

Elágazások

A feltételes elágazás a szokásos szemléletnek megfelelően van a Satherben: egy boolean kifejezés aktuális értékétől függ egy-egy utasítássorozat végrehajtása. Az általános ‘then’ és ‘else’ ágakon túl természetesen lehet ‘elsif’ ágakat is írni. Példák:

i:INT :=-15 if i < 0 then i:=-i end #OUT + i;                      -- kiírás: 15 j:INT :=15 if j < 0 then j:=-j end #OUT + j;                      -- kiírás: 15     if x < 0 then y := 0; elsif x < 100 then y := x; elsif x < 200 then y := 200 – x; else y := 0; end;

Elágazás másik formája a szokásos case szerkezet: egy kifejezés értéke szerinti (több ágú) elágazás. Természetesen itt is megadható egy ‘else’ ág. Érdekesség, hogy nem csak egész kifejezésre alkalmazható, hanem tetszőleges típusú kifejezésre, amelyre definiálva van az egyenlőség-vizsgálat (is_eq, azaz az = jel) operátor.

i:INT := 7; case i   when 1,2,3 then j := 3   when 4,5,6 then j := 4   when 7,8,9 then j := 5   else j := 10 end #OUT + j;                      -- kiírás: 5

Az egyetlen különbség a két elágazás között, hogy ha egyik ág feltétele sem teljesül és nincs else ág, akkor a ‘case’ elágazás ‘run-time error’ hibával megáll. A feltételek kiértékelése ‘rövidzár’ elv alapján történik (mint a C-ben), azaz ha egy tag meghatározza a kifejezés értéket, a többit már nem értékeli ki. Például:

p:POINT; if p.x < 3 then #OUT + p.x; end;    -- Run-time error, ha p void Ezért helyette ezt írhatjuk: if ~void(p) and p.x < 3 then   -- a ~ szimbólum a logikai negáció műveletet jelöli   #OUT + p.x; end;

Itt ha void(p), akkor p.x > 3 feltétel nem is értékelődik ki. Azonban ezt is felülbírálhatjuk a BOOLEAN osztály and_rout eljárásával, amelynél a következő tag is mindig kiértékelődik (megjegyzés: ez azonban eljárás, nem nyelvi elem).

if ~void(p).and_rout(p.x < 3) then ...

A ‘typecase’ kulcsszóval lehetőségünk van olyan elágazások írására is, amelyekben a feltételek típus összehasonlítások, például:

a:$OB := 5; -- ... valamilyen egyéb kód ... res:STR; typecase a   when INT then                -- ebben az ágban 'a' INT típusú     #OUT + "Integer result:"+a;   when FLT then                -- ebben az ágban 'a' FLT típusú     #OUT + "Real result:"+a   when $STR then               -- itt 'a' $STR típusú, támogatja a '.str'-t     #OUT + "Other printable result: " + a.str;   else     #OUT + "Non printable result"; end;

Ciklusok

Ciklust a ’loop’ kulcsszóval írhatunk, amely alap esetben egy végtelen ciklust definiál, amit iterátorokkal módosíthatunk. Satherben csak olyan ciklusok vannak, amelyek valamilyen iterátorok segítségével megfogalmazott „bejárásokat” hajtanak végre. Ezek azonban jóval általánosabbak, jóval több lehetőséget biztosítanak a szokásos for vagy while ciklusoknál, ugyanis egy ciklus több iterátor hívást is tartalmazhat. Ha bármelyik iterátor terminál, akkor az egész ciklus terminál, és a végrehajtás a ciklus után következő utasítással folytatódik. Például:

loop i ::= 0.upto!(100);   loop j ::= 0.upto!(10);     sum := sum + i * j;   end; -- loop j end; -- loop i

A Sather ciklusfogalmának érdekessége, hogy iterátor a ciklus törzsben bárhol szerepelhet. Ilyenkor is ugyanúgy meghatározza azt, hogy meddig fusson a ciklus. Például:

sum:INT := 0; loop   sum := sum + 1.upto!(10); end; #OUT + sum + ’\n’;       -- kiírja 1-től 10-ig az egész számok összegét

Vannak beépített iterátorok (while!, until!, break!) továbbá az INT típushoz megvalósított jól használható  iterátorok (upto!, times!, step!, step_upto!) is, amelyek segítségével minden szokásos ciklus-szerkezetet meg tudunk fogalmazni. Ezeket részletesebben az itárátorokról szóló 5.3 részben mutatjuk be.