2.1. Változók
2.2. Értékek
2.3. Deklaráció
2.3.1. Konstansok
2.3.2. Hatáskörök
2.4. Kifejezések
2.5 Értékadás
2.6. Eljáráshívás
A CLU szigorúan típusos nyelv, egy változó csak olyan típusú értékeket tartalmazhat, amilyen típust a deklarációjában megadtunk. Minden változó kaphat deklaráláskor kezdeti értéket. Ha olyan változóra történik hivatkozás, amelyik még nem kapott a deklarálása óta értéket az mindig futási hibát okoz.
Egy sajátosság, hogy az eljárások (iterációk) is típusok, illetve a megírt eljárás valójában egy literálnak (értéknek) felel meg, a fejléce határozza meg a típusát. Ennél fogva lehetnek ilyen változók, értéket kaphatnak, paraméterként átadhatók, és ezek a változók - megfelelő paraméterezéssel végrehajthatók.
A változók deklarálása a név és a típus megadását jelenti a következő módon:
<variable name> : <type>
b : array[int] := a
A mutable objektumok valódi objektumok, a rájuk hivatkozó változóban csak a hivatkozás (referencia) tárolódik. (Olyasmi, mint egy pointer.) Egy mutable objektumra több hivatkozás is mutathat egyszerre - ekkor osztott objektumnak hívjuk. Ilyen típusú változók értékadásakor mindig csak hivatkozás adódik át, ha a teljes objektumot szeretnénk átadni, akkor arra többnyire valamilyen copy eljárás szolgál. A mutable objektumokat egy konstruktor művelettel kell létrehozni.
Az immutable objektumoknak nem a hivatkozása tárolódik, hanem maga az egész objektum. (Klasszikus példák az egyszerű típusok, pl. az egész vagy logikai értékek.) Egy immutable objektumra nem történhet többszörös hivatkozás, azaz nem lehetnek osztottak. Az ilyen típusú változók értékadásakor mindig lemásolódik az érték. Az immutable objektumoknak deklaráláskor - egy nem specifikált - default értékkel létrejönnek maguktól.
A konstansok csak immutable objektumok lehetnek, ez garantálja, hogy értékük nem változik meg.
Az egyszerű alaptípusoknak csak immutable, az típuskonstukciókkal definiáltaknak van immutable és mutable változata is.
A CLU típusellenőrző mechanizmusa biztosítja, hogy minden konstans illetve változó csak a típusának megfelelő típusú objektumra hivatkozhat.
A konstansokat egyenlőséggel definiálhatjuk (pl.: x = 3). A CLU-konstansok csak beépített immutable típusokra hivatkozhatnak. Ez a megszorítás garantálja, hogy a konstans tényleg nem változhat meg, azaz mindig ugyanarra az objektumra hivatkozik, és a hivatkozott objektum értéke sem változik az idő folyamán. A konstans értékét definiáló kifejezés csak konstansokat, literálokat és beépített operátorokat tartalmazhat (pl.: 6*(4+c) ). A konstans típusát nem kell explicit módon megadni, mivel az egyenlőség jobb oldala alapján egyértelműen meghatározható.
Az említetteken kívül a CLU nyelv megenged ún. típus-konstansokat is
(pl.: ai = array [ int ] ). A típus-konstansok a definiáló típus helyett
használhatók (az x : ai és az x : array [ int ] deklarációk ekvivalensek).
A konstansdeklaráció jobb oldala nem hivatkozhat sem közvetlenül sem közvetve
a jobboldalon definiált típusra. Ilyen módon nem írhatók le rekurzív típusok,
tehát ezekhez nem lehet típuskonstanst definiálni.
Változódeklarációt a törzsön belül bárhol, elhelyezhetünk. A definiált változó hatásköre közvetlenül a deklarálása után kezdődik és a deklarációt tartalmazó törzs végéig tart. A konstansokat definiáló egyenlőségeket a törzs elején kell elhelyezni.
Mivel a törzsek egymásba ágyazhatók, a
hatáskörök is egymásba ágyazhatók. Viszont a belső hatáskörben nem definiálhatók
át a külső hatáskörben definiált azonosítók.
Más nyelvekhez hasonlóan a CLU-banis használhatók az aritmetikai, összehasonlító operátorok, a tömbindexelés, és a rekordok mezőszelekciója, ezek azonban csak az eljáráshívások rövidített formái.
Sajátosság, hogy a típusban definiált eljárásokat mindig típus-eljárása formában kell megadni.(pl.t$proc(...) - t a típus neve, proc az eljárásé). A kód olvasahatósága kedvéért, bevezették a szintaktikus cukor fogalmát. Ez lehetővé teszi, hogy a hagyományos algebrai kifejezéseket a megszokott formában adjuk meg: pl. a + b. Az ilyen kifejezéseket egy előfordító a szintaktikai ellenőrző számára megkövetelt fomába alakítja ("cukortalanítja", desugaring) , és a fordítást azon végzi el. A cukoratalanítás során nincs típusellenőrzés, de ha az adott típusnak nincs megfelelő alakú függvénye, akkor a fordító hibát jelez.
A "cukorkák" a prioritás sorrendjében:
6: (, ), ~, -,
~ a logikai nem, - a negatív előjel
5: **,
4: //, /, *,
3: ||, +, -,
2: <, <=, =, >=, >, ~<, ~<=, ~=, ~>=, ~>,
1: &, cand,
0: |, cor
Példák:
3+2 int$add( 3, 2 ) b : bool := (i=j) b : bool := int$equal( i, j ) x : int := a[i] x : int := array[int]$fetch( a, i ) a[i] := x array[int]$store( a, i, x )
argl op arg2 <-- T$opname( argl, arg2 )
A CLU rendelkezik a 'cand' és a 'cor' logikai operátorokkal, amelyek viszont sem rövidítésként sem szintaktikailag nem feleltethetők meg eljárásoknak. Hasonlóak a '&' és a '|' logikai operátorokhoz, de a második argumentumuk csak abban az esetben értékelődik ki, ha szükséges. Hasznosak a futási hibák megelőzésére:
i <= ai$low( a ) cand i <= ai$high( a ) cand ai[ i ] = x
a := b a := <kifejezés>
Ha a és b immutable objektumok, akkor érték szerinti értékadás történik. A második esetben nem jön létre új objektum. Az a változó korábbi értéke felülíródik.
A CLU támogatja a szimultán értékadást is, melyben tetszőleges sok változó szerepelhet az egyenlőség bal oldalán.
a, x := b, y
x, y := y, x
Egy függvény adhat vissza több értéket, de ezeket csak a szimultán értékadás tudja fogadni, azaz nem szerepelhet aktuális paraméterként. További megszorítás, hogy ha egy szimultán értékadás jobb oldalán többértékű függvény szerepel, akkor más kifejezés nem állhat a jobb oldalon, s a baloldalon pontosan annyi változó-kifejezésnek kell szereplni, mint a függvény visszatérési értékeinek száma.
<procedure name> [ generic params] ( <formal params> )Amennyiben az eljárásnak nincsenek formális paraméterei, akkor is ki kell rakni egy üres zárójel-párt. Ha nincs generikusság, a szögletes zárójel elhagyható.