Icon

Beépített adattípusok

Az Icon erõsen -de nem statikusan- típusos nyelv, automatikus tipuskonverzióval rendelkezik. Például ha egy integer típusú változót egy string műveletben alkalmazunk, akkor az automatikusan stringgé konvertálódik. Az adatértékeknek van típusa, magának a változónak nincs! Bármilyen érték bármikor bármely változóhoz hozzárendelhetõ.

logikai típus

Az Iconban nincsen logikai típus, helyette egy kifejezés vagy kiértékelhetõ (true-nak felelne meg), vagy pedig nem (false-nak felelne meg).

null(n)

Azt jelenti, hogy nem definiált még a változó típusa. Kezdetben minden azonosítónak ez a típusa, kivéve a függvényeknek.

real(r)

A lebegõpontos számok az Iconban az adott platform által biztosított legnagyobb pontosságú típust jelenti (általában dupla pontosságú). Ha egy integert és egy valós számot akarunk összeadni, akkor az integert automatikusan valós számmá konvertálja. Ha túllépjük az ábrázolási korlátot, akkor az értéke végtelen lesz (INF).

integer(i)

Megszokott egész típus, azzal a különbséggel, hogy az Iconban nincs korlátozva a mérete. A platform által adott legnagyobb integer típust használja (ez általában legalább 32 bit), de ha valamely művelet alkalmazása után túlcsordulna, akkor a program automatikusan áttér large integerre. Ezt szoftveresen kezeli és a használata teljesen automatikus a program futása közben.

Az Iconban két prefix operátor van, a +N (ez az N értékét adja) és a -N (ez pedig a -1-szeresét). A szokásos aritmetikai műveletek pedig a következõk:

kifejezés művelet precedencia asszociatívitás
N1 ^ N2 hatványozás 3 jobbról balra
N1 % N2 maradékképzés 2 balról jobbra
N1 / N2 osztás 2 balról jobbra
N1 * N2 szorzás 2 balról jobbra
N1 - N2 kivonás 1 balról jobbra
N1 + N2 összeadás 1 balról jobbra

Összehasonlító operátorok:

N1 < N2 kisebb
N1 <= N2 kisebb egyenlõ
N1 > N2 nagyobb
N1 >= N2 nagyobb egyenlõ
N1 = N2 egyenlõ
N1 ~= N2 nem egyenlõ

Az Iconban öt beépített függvény létezik, amelyekkel bitszintű műveleteket végezhetünk. Ezek a következõk:

iand( i1, i2 ) bitenkénti ÉS
ior( i1, i2 ) bitenkénti VAGY
ixor( i1, i2 ) bitenkénti kizáró VAGY
icom( i ) bitenkénti komplemens
ishift( i, j ) i eltolása j pozícióval

Beépített matematikai függvények:

sin(r) szinusz
cos(r) koszinusz
tan(r) tangens
asin(r) arkusz szinusz
acos(r) arkusz koszinusz
tan(r1,r2) arkusz tangense r1 / r2 -nek
dtor(r) fok átszámítása radiánba
rtod(r) radián átszámítása fokba
sqrt(r) gyökvonás
exp(r) exponenciális
log(r,alap) logaritmus

Álvéletlen számokat a ?i operátorral tudunk generálni. Ha az i egy pozitív egész, akkor a generált szám 1 és i közötti egész szám lesz. Ha 0, akkor egy 0.0 és 1.0 közötti valós számot kapunk. Az álvéletlen számot lineáris kongruenciával generálja, a random magot a &random tartalmazza.

karakter

Az Iconban nincs külön karakter típus, csak a karakterekbõl képzett string és cset (karakter halmaz).

string(s)

Ezek 8 bites karakterekbõl állnak és mind a 256 karakter elõfordulhat a stringben. A stringliterálokat idézõjelek közé kell tenni és a karakterláncok hossza szintén nincs korlátozva (kivéve persze a rendelkezésre álló memóriát). Mivel néhány rendszer alatt nem lehet minden karaktert megadni, így azokat escape szekvenciákkal érhetjük el. Ezek, mint a C-ben, a backslash-el adhatóak meg:

\b visszatörlés (backspace)
\e escape
\f lapdobás
\n soremelés
\r kocsivissza
\t vízszintes tabulálás
\v függõleges tabulálás
\' aposztróf
\" idézõjel
\\ backslash
\ddd ASCII karakter oktálisan
\xdd ASCII karakter hexadecimálisan

Lehetõségünk van továbbá több sorba tördelni a stringet, ezt az aláhúzás jellel tehetjük meg:

s := "Ez egy _ néhány soros _ szöveg."

Az ord és a char függvénnyel egy karakter ASCII kódját kaphatjuk meg, illetve ez alapján adhatunk meg egy karaktert. A karakterláncok hosszát a * operátorral kérdezhetjük le. Például a

*"Hello World!"

kifejezés 12-t ad vissza.

Két karakterláncot lexikografikusan is összehasonlíthatunk:

s1 << s2 lex.grafikusan kisebb
s1 <<= s2 lex.grafikusan kisebb vagy egyenlõ
s1 >> s2 lex.grafikusan nagyobb
s1 >>= s2 lex.grafikusan nagyobb vagy egyenlõ
s1 == s2 lex.grafikusan egyenlõ
s1 ~== s2 lex.grafikusan nem egyenlõ

Két stringet a || operátorral tudunk összefűzni. Például:

"alma" || "fa" == "almafa"

Érdemes megjegyezni hogy az összefűzés operátorral is összekombinálható az értékadás:

szoveg ||:= "valami"

Ez a szoveg változóhoz hozzáfűzi a "valami" karakterláncot.

Mivel az Icon alapvetõen szövegmanipulációs nyelv, így rengeteg beépített stringkezelõ függvénnyel rendelkezik:

right(s1, i, s2) s1-t jobbra igazítja i karakteren és s2-vel
kitölti a vezetõ szóközöket
left(s1, i, s2) s1-t balra igazítja i karakteren és s2-vel
kitölti a végén levõ szóközöket
center(s1, i, s2) s1-t középre raigazítja i karakteren és s2-vel
kitölti a két szélen levõ szóközöket
entab(s,i1,i2,...,in) a szóközöket tab karakterekre cseréli
detab(s,i1,i2,...,in) tab karaktereket szóközökre cseréli
repl(s,i) i-szer egymás után fűzi s-t
reverse(s) s fordítottját adja vissza
map(s1,s2,s3) s1-ben elõforduló s2-beli karaktereket lecseréli
az s3-ban adottakkal
trim(s,c) s-bõl levágja a vezetõ és befejezõ c-ben elõforduló karaktereket
*s s hossza
s[i:j] s-nek i-tõl j-dik pozicíójáig tartó részlánca

cset(c)

Karakterhalmaz. Az alkalmazható műveletek:

c1 ++ c2 unió
c1 ** c2 metszet
c1 -- c2 különbség
~c komplementer

Több elõre definiált karakterhalmaz áll a rendelkezésünkre a programozás közben. Ezek közül néhány:

&cset az összes ASCII karakter
&ascii az elsõ 128 ASCII karakter
&digits a számjegyek
&lcase angol kisbetűk
&ucase angol nagybetűk
&letters angol kis- és nagybetűk

record types(R)

Ez a szokásos rekord típus. A rekordokat -éppúgy, mint az eljárásokat- csak globálisan deklarálhatjuk (egy eljárás törzsében nem szerepelhet rekord deklaráció). Itt jegyzem meg, hogy a struktúrákat mind pointer sematika szerint kezeli az Icon. Egy N mezõt tartalmazó rekordot a következõképp adhatunk meg:

record név(mezõ1,mezõ2,...,mezõN)

A mezõkre többféleképp is hivatkozhatunk. Például a complex(re,im) rekorddal reprezentált komplex szám képzetes részére:

c.im c[2] c["im"]

A mezõk értékeit egyszerre is megadhatjuk a konstruktorral:

record szemely(nev,fizetes) sz := szemely( "Kiss Pista", 123456 )

list(L)

A listáknak az Iconban két alapvetõ szerepük van. Az egyik, hogy egydimenziós vektoroknak számítanak és indexeléssel hivatkozhatunk az elemeire. Másrészrõl viszont sorként és veremként is kezelhetjük õket. Többdimenziós tömböket listákból álló listákkal reprezentálhatunk.

A list(i,x) kulcsszóval deklarálhatunk i elembõl álló listát, elemeinek kezdõértéke x lesz. Továbbá szögletes zárójelek közt felsorolva az elemeit is megadhatunk egy tömböt:

tomb = ["alma", 1, ["korte", 2.0] ]

Mint ahogy a fenti példában is látszik a tömbök elemei tetszõleges típusúak lehetnek (akár mind más-más típusú is).

Műveletek:

lista1 ||| lista2 a két lista egymás után fűzése
lista[ i ] a lista i. elemére hivatkozás
lista[ i:j ] a lista i..j indexű elemeibõl álló részlistája
put(L,x) az x elem betétele L-be (mint sor)
get(L) egy elem kivétele L-bõl (mint sor)
push(L,x) az x elem betétele L-be (mint verem)
pop(L) egy elem kivétele L-bõl (mint verem)

set(S)

A halmaz különbözõ értékek rendezés nélküli gyűjteménye. Halmazt a set(L) utasítással deklarálhatunk, ahol L egy lista, vagy pedig felsorolhatjuk az elemeit szögletes zárójelek között. Természetesen különbözõ típusú elemek is lehetnek a halmaz elemei.

Műveletek:

S1 ++ S2 unió
S1 ** S2 metszet
S1 -- S2 különbség
member(S,x) x eleme-e az S halmaznak?
insert(S,x) x-t beteszi az S halmazba
delete(S,x) x-t kiveszi az S halmazból

table(T)

Az Inconban a tábla típus elempárokat tartalmazó asszociatív táblát valósít meg. Csupán annyiban különbözik a listától, hogy tetszõleges típust használhatunk indexelésre (az elemek indextípusa különbözõ is lehet). A deklaráció a table(X) utasítással történik, ahol az X az új elemek kezdeti értéke. Példa:

szavak := table(0) szavak[ "egy" ] := 1

Ez az "egy" elemhez az 1 értéket rendeli. Kezdetben a tábla mérete nulla, és minden egyes új elem növeli a méretét. Az elemek kezelése teljesen automatikus.

Műveletek:

member(T,x) van-e x kulcsal rendelkezõ elem?
insert(T,x,y) elem beszúrása, gyk. T[x]:=y
delete(T,x) elem törlése

co-expression(C)

A szokásos kifejezés kiértékelésnél a kifejezés értékének felhasználása a program azon részére van korlátozva, ahol az elõfordul. Ezt a korlátozást léphetjük át a segédkifejezéssel, amely ú.m. eltárolja magát a kifejezést, így a program tetszõleges részén bármikor folytathatjuk annak kiértékelését. Valójában a segédkifejezés egy referenciát tárol egy adott kifejezésrõl és annak a kiértékelési környezetérõl. Létrehozásuk a következõ utasítással lehetséges:

create expr

Itt nem értékelõdik ki a kifejezés és a visszaadott referenciát eltárolhatjuk egy változóban, vagy átadhatjuk egy függvénynek illetve függvény visszatérési értéke is lehet segédkifejezés. Továbbá fontos, hogy a segédkifejezés nemcsak ezt a referenciát tartalmazza, hanem a kifejezésben szereplõ dinamikus lokális változók másolatát is, azokkal az értékekkel, amikkel a create meghívásakor rendelkeztek. Ezáltal függetleníthetjük a kifejezést és környezetét a deklarálás helyétõl. A segédkifejezés kiértékelésének folytatása (aktiválása) a @ operátorral történik:

szamnevek := create( "egy" | "ketto" | "harom" ) write( @szamnevek )

Ez kiértékeli a kifejezést és visszaadja a vezérlést a write-nak, ami kiírja az értéket ("egy").