Értékadás, üres utasítás
A Clair-ben az értékadás jele a :=, példa értékadásra:
x := 34, y := 12
A
C-ben megismert rövidebb írásforma is használatos kifejezések értékadásának
leírására, például
x := x + 1 helyett
x :+ 1 írható. De tetszőleges
operátorra alkalmazhatjuk a
:op kifejezést.
Van párhuzamos értékadás a nyelvben, a tuple segítségével írhatunk ilyen
kifejezéseket. Például:
(x,y) := tuple(y,x)
felcseréli
x és
y értékét. A
tuple a függvények
visszatérési értékénél is hasznos, ha az akarjuk, hogy a függvényünknek több visszatérési
értéke legyen. Például írhatjuk a következőt:
let (x,y) := f() in ...
Az értékadás kifejezés is egyben, írhatjuk elágazás vagy ciklus feltételébe. Megjegyezzük,
hogy nem azonos a
C-beli szemlélettel az ilyen értékadás, ugyanis
if(1)
és
if(0) is igazzal tér vissza.
A
let utasítás egy speciális formája, a
when vezérlő struktúra
kiértékeli a feltételt, s csak akkor hajtja végre a törzs részében lévő kódot, ha
a lokális változója nem
unknown. Egyéb esetben
unknown-nal
tér vissza, kivéve, ha megadunk
else ágat. Például:
when f := get(father, x) in printf("his father is ~S\n",f)
else printf("his father is not known at the present time \n")
Az üres utasítást ki kell írni, ugyanis például az alábbi érdekes dolgot tapasztalhatjuk.
Tekintsük a következő programrészletet:
if (true)
else
printf("else ág\n")
if (false)
else
printf("else ág\n")
Az első esetben az
else értékkel tér vissza a program, nyilván nem ezt
várnánk, míg a második esetben kiírja az
else ág mondatot, s
unknown-nal
tér vissza, helyesen.
Szekvencia
Szekvenciát a , segítségével hozhatunk létre, az egyes utasításokat a
, választja el. A blokkok után nem kell kitenni a ,-t, viszont
más nyelvektől eltérően a ciklusok és elágazások után ki kell tenni. Mint már láthattuk,
a más nyelvekben megszokott ; itt megjegyzést jelent. Blokkutasítást
a ( ) segítségével hozhatunk létre. Deklarációs utasítást a let
segítségével helyezhetünk el a blokkban, például a következőképpen:
let x := 1, y := 3 in (z := x + y, y := 0)
Elágazás
Az elágazás szintaxisa a következő:
if (exp) x else y
Az
exp kifejezés kiértékelődik, és ha az értéke nem
false,
nil vagy
{}, akkor az
x ág hajtódik végre, egyébként
az
y ág. Ha nem volt megadva
else rész, akkor az alapértelmezett
false értékkel fog visszatérni az
if kifejezés.
Az
if kifejezéseket egymásba is ágyazhatjuk, azaz a többirányú elágazás
is megengedett. Fontos, hogy az
if kifejezéseknek egy blokkon belül kell
lenniük, ami azt jelenti, hogy ha egy szekvencián belül nincs körülvéve zárójellel,
akkor körül kell venni. Ha nem lehet eldönteni, melyik
else ág hova tartozik,
akkor blokkokkal kell egyértelművé tenni.
A case szerkezet is használható többirányú elágazásra. Ennek szintaxisa:
case var
(
{var1,var2, ..., varn} x1,
...
{vark1,vark2, ..., varkm} xk,
any x
)
A
case szerkezet halmaz-alapú: a
Claire teszteli a halmazokat
a
case ágaiban, s az elsőt, amelyben szerepel a változó aktuális értéke,
végrehajtja, és kilép a további ágak tesztelése nélkül. A
default ág
az
any halmaz. Amint az
if-nél is, a visszatérési érték
nil,
ha semelyik ág se hajtódik végre. A fordító nem engedélyezi a változó megváltoztatását
a
case ágon belül, ha az nem konzisztens az adott belépési halmazzal
(például:
case y ({1} x := 2) ). A
case kifejezése leggyakrabban
egy változó, de lehet bármilyen kifejezés is.
Ciklus
A Claire-ben található nem ismert lépésszámú, illetve ismert lépésszámú
ciklus, s van elől- illetve hátultesztelős ciklus is. Az előre ismert lépésszámú
ciklus a for, amely bármilyen kollekció elemein végigfuthat, lásd az
alábbi példákat:
for x in (1..3) a[x] := a[x+3]
for x in list{x in class | size(x.ancestors)>=4) printf("~S \n",x)
Előltesztelős ciklus a
while, hátultesztelős az
until. Mindkettőnél
blokkba kell ágyazni a logikai kifejezést. Erre példák:
while(x>0) x := 1
until(x = 12) x := 1
while not(i = size(l)) (l[i] := 1, i :+ 1)
Végtelen ciklus esetén a
break(x) kifejezés használható a ciklusból való
kilépésre. Viszont a
try ... catch blokkból nem léphetünk ki a
break-kel.
Vezérlésátadó utasítások
ld. 5. fejezet