Íme néhány példa, miképp írjunk használható CLU programokat, s mik
a CLU igazán egyedi és egyben hasznos nyelvi elemei.
Ha az általad kiválasztott példa neve melletti kis kék gömbre
kattintasz, megjelenik a példa (HTML formátumú ) tárgyalása magával a példaprogrammal
és megjegyzésekkel együtt. A (CLU forrás)hivatkozásokkal
a CLU forráskódok szöveges állományként tölthetők le. A fordító által generált
állományokat sehol sem mellékeltük!
Szögletes zárójelek között az adott példára
jellemző nyelvi elemek és szerkezetek nevei szerepelnek.
Hello World! a végtelenségig
Az iterátorok használatát is bemutató verzója az előbbi programnak.
[stream] (CLU
forrás)
Legnagyobb közös osztó meghatározás
Két pozitív szám legnagyobb közös osztójának meghatározása.
[while] (CLU
forrás)
Faktoriális számolás
Egy pozitív egész faktoriálisát számolja ki.Van hozzá specifikáció
is!
[while; specification] (CLU
forrás)
Faktoriális számolás II.
Egy pozitív egész faktoriálisát számolja ki rekurzivan, hibakezeléssel.
[recursion; signals] (CLU
forrás)
Logaritmikus keresés
A paraméterként kapott tömbben a logaritmikus keresést megvalúsítú
eljárás.
[while; if-then-elseif-else; variable-declaration] (CLU
forrás)
Logaritmikus keresés specifikációval
Ugyanaz, mint a korábbi log-ker, de van hozzá specifikáció is.
[while; if-then-elseif-else; variable-declaration; specification] (CLU
forrás)
Duplikáció-ellenőrzés
A paraméterként kapott tömbben megszünteti az esetleges duplikációkat.
[while; type-definition] (CLU forrás)
Vektorösszegzés
Vektorösszegzés egy paraméterként megadott függvény kompozíciójával.
[array,proctype parameter] (CLU forrás)
Elem-iterátor
A CLU egyik igen hasznos eszköze az iteráció.
Íme egy egyszerű példa, ami egy egész
típusú tömb - mint formális paraméter
- elemeit sorolja fel indexük sorrendjében.
[iter; array-parameter] (CLU
forrás)
Prím-iteráció
A CLU egyik igen hasznos eszköze az iteráció. Itt két, prímszámokat
szolgáltató iteráció példaprogramját láthatjuk, két különféle módon megoldva.
[iter] (CLU forrás I.)(CLU
forrás II)
Iteráció szűrővel
Iteráció, melynek formális paramétere egy függvény és egy iteráció
is!
[iter; function-parameter] (CLU
forrás)
Bináris fa inorder bejárása
Részlet egy bináris fa implementációból (önállóan nem fordítható).
A fa reprezentációja persze rekurzív, s erre láthatunk egz igen elegáns
inorder bejáró iterátort.
[iter; record; variant] (CLU
forrás)
String-szám konverzió streamből
Az eljárás a paraméterként kaptt stream-ből
kiolvassa az első számjegy-sorozatot, majd
kiírja az output-ra az egésszé alakítása
után.
[stream] (CLU
forrás)
Összegzés stream-ből
A program stream-ből (file vagy billentyűzet)
olvas szóközzel elválasztott egészeket, majd kiírja a standard input-ra
az összegüket.
[stream; exception] (CLU
forrás)
Komplex szám típus
Egy egyszerű példa a típus-implementációra:
a komplex típus cluster-e.
[cluster; struct; rep; equal; similar;
exception] (CLU
forrás)
Halmaz típus az elem-típussal paraméterezve
A példa a generikus halmazra ad példát, valamint megmutat egy általános
copy-similar kapcsolatot. A paraméter típus megszorított. Van benne egy
lista-iterátor is...
[cluster; where; array; rep; cvt; up; down; iter; type-parameter] (CLU
forrás)
Lista típus az elem-típussal paraméterezve
Technikailag hasonló a listához: generikusság,
copy-similar kapcsolat, stb. De a
reprezentáció már érdekesebb, az ugyanis
rekurzív! Itt a paraméter típus csak egynéhány
művelet esetében megszorított
[cluster; rep; cvt; up; down; null; struct; oneof; iter; type-parameter;
where] (CLU forrás)
Egy összetettebb példa: fa típus
A példa egy rekurzióra épített fa típust valósít meg. A rekurzió abban
nyilvánul meg, hogy a típus egyszerre reprezentál egy csomópontot és az
alatta található részfát, egy teljes fa és a részfái között nincs semmi
különbség csak az, hogy a gyökérnek nincs
szülője. A megvalósítás rekurzív típusdefiníciót és rekurzív eljáráshívásokat
használ.
Több modulból álló fordítóprogram
Egy nem túl bonyolult, de eléggé összetett
fordítóprogram, amiben megtalálható egy tömb elemü, láncolt szerkezetű
verem, egy kiterjesztett művelethalmazzal ellátott, ugyancsak láncolt szerkezetű
verem (mindkettő természetesen generikus a tárolt elemek típusát illetően),
egy szimbólumtábla típust megvalósító
modul, végül az igen egyszerű struktúrájú nyelvet fordítani képes compiler.
[cluster]
Kép típus
A példa egy egyszerű kép típust valósít meg. Egy kép képpontokból áll,
és minden képpontot a színével reprezentálunk, ami egy 0
es 256 közötti egész szám. A képpontokat mátrix formában adjuk meg.
A kép alakjára nincs kikötés.
[cluster, stream, iter] (CLU
forrás)
Megjegyzések:
A csupán néhány példaprogramnak van interaktív felülete, ami azt jelenti, hogy önállóan nem futtathatók, viszont hibaüzenet nélkül lefordíthatók. Az egyes programok/típusok ilyetén kiegészítése legyen az olvasó feladata!
A példaprogramok megtalálhatók az examples.tar.gz és examples.zip archív állományban.
A tar letöltése után adjuk ki a következő
parancsot: tar
xzf examples.tar.gz
Erre kicsomagolja az aktuális könytárba a benne található állományokat.
A Winzip is ismeri ezt a formátumot.
Az forrásnyelvi programokból a CLU2C ("CLU to C") fordítóval
lehet C forrásnyelvi programot készíteni, majd abból futtatható programot.
A fordító használatát az CLU2C fordító
című rész írja le. (A fa típus moduljait és a prímiterációkat Unix alatt
teszteltük, míg a többit DOS alatt készítettük.)
Néhány személyes megállapítás: (avagy tapasztalatok
a Unix-os CLU2C fordítóról)
A fordító nagyon jó. Nem találkoztam "nincs
vagy csak félig van implementálva", "hibásan működik", stb jelenségekkel.
A kiegészítések az eredeti nyelvhez képes hasznosak. A példaprogramban
éltem az objektum-eljárása
típusú hivatkozás lehetőségével, ez jelentősen lerövidítette a forrás szövegét
és könnyebben olvasható kódot ad az oop-hoz szokott szemeknek. (Típus-eljárása
típusú hivatkozás nem túl gyakori a programozási nyelvekben, bár néhány
esetben ez lenne a logikusabb.) A Tree programban van egy rekurzív definíció.
A fellehető dokumentációk szerint a CLU "korlátozott mértékben" támogatja
a rekurzív típusdefiníciókat, ennél
pontosabbat nem sikerült megtudnom. Az első fordítási kísérletnél (a definíció
valójában hibás volt) olyan hibaüzeneteket adott, hogy "rekurzív típusdefiníció",
"típus újradefiniálása", "a típusdefiníció sikertelen". Ezt akár lehet
félrevezető hibaüzenetnek is nevezni, de végül is a példában található
forma probléma nélkül használható. A rekurzív típusdefiníció "korlátainak"
kiderítését nem vállaltam. A Hello program futtatható változata az Augustán
683.376 byte lett. A négy programot nem lehet egyszerre lefordítani, mert
közben elfogy a kvóta. (Talán lehetne a C fordítónak átadható paraméterekkel
bűvészkedni.) Közben a Valerie-n is "lett" CLU2C fordító, itt csak 228.256
byte lett a mérete, valószínűleg a gcc
eltérő paraméterezése miatt. (Itt a kvóta is magasabb.) Van egy specialitása
a CLU szintaxisának, ami engem többször megviccelt:
is_null = proc (n : int) return (bool) return (n = 0) end is_nullEzzel az a gondja a fordítónak, hogy típust (bool) használunk ott, ahol nem lehet, és egyébként is, miért akarunk értéket visszaadni, valamint máshol, ahol hivatkozás van erre az eljárásra, miért várunk visszaadott értéket, amikor az nincs. Ugyanis a fejlécben lévő return szintaktikai hiba, mert returns lenne helyesen, az eredmény (a fentivel azonos program):
is_null = proc (n : int) returns (bool) return (n = 0) end is_null(yields-yield esetén hasonló a helyzet.)