Beépített adattípusok
A beépített adattípusok két csoportba sorolhatók:
- Primitív típusok: byte, int, big, real, string
- Referencia típusok: tömb, lista, sor, absztrakt adattípus,modul, csatorna
Primitív típusok
A bájtok (byte) előjel nélküli 8-bites egységek.
Az egészek (int) 32-bites előjeles egységek kettes komplemensben lévő számábrázolással.
A nagyméretű egészek (big) 64-bites előjeles mennyiségek kettes komplemensben lévő számábrázolással.
A valós számok (real) 64-bites egységek IEEE long lebegőpontos számábrázolással.
A byte,int,big, and real típusokat egységesen aritmetikai típusoknak nevezik.
A sztringek (string) Unicode karakterekből álló
sorozatok (tömbök). Minden Unicode karakter 16 bit.
Példa:
s := "Inferno";
Karakterenként összefűzhetők és kiegészíthetők.
A nyelvben nincs külön karakter típus. A karaktereket az int értékükkel reprezentálták.
Példa:
c := 'I'; # c értéke 73 (az I betű int értéke)
Sztringből képezhetünk részsztringeket (lásd: tömböknél).
Referencia típusok
A Limbo referencia típusai hasonlóak más nyelvek (pl. C,
C++) mutató típusaihoz. A különbség elsősorban az, hogy a Limbo nem engedi meg referenciákon matamatikai műveletek végzését. Ez biztosítja a "pointer biztonságot" a nyelvben, mivel a referencia sohasem mutathat illegális címre. Mégis, az értéke lehet
nil.
A nil speciális érték, ami eltünteti a hivatkozást és a hozzátartozó területet. Ha ez az utolsó hivatkozás az adatra, akkor a szemétgyűjtő automatikusan és azonnal felszabadítja az általa foglalt helyet.
Tömb típus
A tömbök rendezett, indexelt, homogén adatokból állnak. Az indexelés 0-val kezdődik.
Alap tömb deklaráció a következő módon néz ki:
buf : array of byte; # buf változó byte típusú elemekből álló tömb
Helyfoglalása és a változónak értékül adás:
buf = array[80] of byte; # a buf tömb 80 db, byte típusú elemekből áll
Lehetőség van a deklarációban 0-re inicializálni a tömböt:
buf := array[80] of byte;
A tömb mérete nem a típusnak, hanem az értékének a része. Az elemek típusa is lehet tömb, ilymódon írhatók többdimenziós tömbök.
A tömbökből és sztringekből képezhetünk ún. szeleteket, melyek összefüggő részét képezik az eredetinek.
A kivágandó rész kezdetét és végét jelző indexet zárójelben adhatjuk meg, vesszővel elválasztva. Az kezdeti index által mutatott elem igen, a vég által mutatott nem kerül bele a
szeletbe.
Példa:
s := "Inferno";
# s szelete a 2-tól a 6. karakterig: s2 := s[2:6];
# s2 értéke: "fern".
Lista típus
A listák rendezett, nem indexelt, homogén elemekből állnak. A lista első eleme a
fej, a maradéka pedig a törzs.
Deklaráció:
line: list of string; # line azonosító sztringekből álló lista
Lista készítéséhez használható a lista konstruktor ( :: operátor):
line = "First" :: line; # "First" a lista feje
A lista konstruktor jobbasszociatív. A bal oldali elem típusának meg kell egyezni a lista elemtípusával. A
jobb oldali elem a lista azonosítója.
Alternatív konstruktor a list of:
triple := list of {1, 2, 3}; # tripel lista három eleme:1, 2 és 3
A lista veremszerű szerkezet, melyet a következő műveletre optimalizáltak: fej lekérdezése, törzs lekérdezése, elem beszúrása az első helyre.
Lista fejének lekérdezéséhez használhatjuk a hd operátort. Ekkor nem jön létre új lista és a régi sem változik.
Példa: a fent létrehozott line listát használva:
sys->print("A lista feje a következő: %s", hd line);
utasítás eredménye a következő sor:
A lista feje a következő: First
A lista törzse maga is egy lista, melynek típusa megegyezik az eredeti listáéval. A
tl operátort használva az eredeti lista első eleme elhagyható:
line = tl line;
és így akár új lista is létrehozható:
args := tl line;
Sor típus
A sor típus kettő vagy több objektum rendezett együttese,
melyek
saját adattípussal rendelkeznek. A tagok típusa az egyes sorokban rögzített és megegyezik.
Példa:
retcode := (0, "Érték"); # a retcode sor két eleme 0 és "Érték" sztring
A sor egyes tagjainak értékét értékül adhatjuk más azonosítóknak:
Példa:
err: int;
msg: string;
(err, msg) = retcode;
# inicializálás, az err változó értéke 0, az msg változó értéke "Érték" lesz
(err, msg) := retcode; # értékadás
A nil kulcsszó használatával figyelmen hagyhatjuk a sor egy részét:
Példa:
(err, nil) = retcode; # az err változót 0-ra inicializáljuk
Mutatók
A Limbo nyelvben nincsenek mutatók, csak referenciák, amik a ref kulcsszóval hozhatók létre. Nincs & (cím) operátor, nincs mutatóaritmetika, és a referenciák csak absztrakt adattípusú (ADT) objektumra mutathatnak.
Ha e egy ref ADT típusú kifejezés, akkor az ADT értékét a * e utasítással kérdezhetjük le. Az
e értéke nem lehet nil.
A szemétgyűjtés automatikus.
Típusok ekvivalenciája
Két alap típus akkor és csak akkor ekvivalens egymással, ha azonosak.
Két sor típus akkor és csak akkor ekvivalens egymással, ha azonos típusú elemekből állnak, és azok sorrendje megegyezik.
Két tömb típus akkor és csak akkor ekvivalens egymással, ha azonos típusú elemekből állnak. A tömb mérete nem része a típusnak.
Két lista típus akkor és csak akkor ekvivalens egymással, ha azonos típusú elemekből állnak.
Két csatorna típus akkor és csak akkor ekvivalens egymással, ha azonos típusú elemek közlekednek rajtuk.
Két ADT típus akkor és csak akkor ekvivalens egymással, ha adattagjaik neve azonos és típusuk ekvivalens. A tagok deklarálásának sorrendje közönbös, és a tagfüggvények, a konstansok és az ADT típusának neve sem vesznek részt az összehasonlításban.
Példa:
A: adt { x: ref B; };
B: adt { x: ref A; };
esetén A és B típusok ekvivalensek
Két ref ADT típus akkor és csak akkor ekvivalens egymással, ha ekvivalens ADT típusokra hivatkozó referenciák.
Két modul típus akkor és csak akkor ekvivalens egymással, ha a tagfüggvényeik és adataik neve megegyezik és típusuk azonos; a deklarálási sorrend közönbös. A konstansok és típusok nem számítanak az összehasonlításban.
Két függvény típus akkor és csak akkor ekvivalens egymással, ha visszatérési értékük azonos típusú és
paramétereik ekvivalens típusúak.
Típuskonverziók
A nyelvben nincs automatikus típuskonverzió, minden típuskényszerítést explicit meg kell adni.
Változók, konstansok
Változók
A deklaráció általános alakja:
azonosító-lista : típus ;
azonosító-lista : típus = kifejezés ;
Azonosítók vesszővel elválasztott listáját kettőspont, majd a típus
neve követi. Ha a deklarációban szerepel = és kifejezés, a típus adattípus
kell legyen, és minden objektum a kifejezés értéke szerint inicializálódik.
A legfelső szintű (függvényen kívüli) deklaráció során a kifejezés
lehet konstans vagy olyan tömb, melyet konstans kifejezéssel hoztunk létre.
A listák és ref ADT típusok nem inicializálhatók a legfelső szinten. Ha
egy objektumot nem inicializáltuk explicit, és referencia típusú, akkor nil-re
inicializálódik. Ha aritmetikai típusú, a legfelső szinten 0-ra inicializálódik,
függvénybeli előfordulása esetén pedik az értéke definiálatlan lesz.
Példa:
i, j: int = 1;
r, s: real = 1.0;
A fenti deklaráció hatására i és j egész, r és
s valós változók; i és j
értéke 1, r és s értéke 1.0.
A deklaráció másik formája a gyorsírás.
azonosító := kifejezés ;
( azonosító-lista ) := kifejezés ;
A bal oldali azonosítók mindegyikét a a kifejezés típusát felhasználva
deklaráltuk, és a kifejezés értéke alapján inicializáltuk. A második
esetben a kifejezés sor vagy ADT lehet, és az változók típusa és értéke
megegyezik a sor megfelelő tagjával vagy az ADT megfelelő adattagjával. Példa:
x: int = 1;
x := 1;
A fenti két utasítás ugyanazt eredményezi. Hasonlóan:
(p, q) := (1, 2.1);
a baloldali p ill. q változókat egész ill. valós értékűre
deklarálja, értékük 1 ill. 2.1 lesz. A :=-vel jelölt deklarációk kifejezések
is lehetnek.
Láthatóság, elérhetőség
Egy változó láthatósága attól függ, hogy hol lett deklarálva.
-
Ha modul deklarációban deklaráltuk, a modul összes függvénye számára elérhatő, vagyis a modulon belül globális. A modul adatok kezdeti értéke 0 vagy
NULL. Ha modul interfész fájlban deklaráltuk, akkor publikus, vagyis minden, a modult betöltő program számára elérhető.
-
Ha az adatot nem modul deklarációban és nem függvényben deklaráltuk, akkor a modulon belül globális, de privát.
-
Ha az adatot függvényen belül deklaráltuk vagy ott adtunk neki kezdeti értéket, akkor a függvényen belül elérhető. A függvény adatait átadhatja más függvényeknek. Nem érhető el más programokból, hacsak explicit át nem adjuk.
-
Ha az adatot blokkszerkezetben deklaráltuk vagy ott adtunk neki kezdeti értéket, akkor csak ebben a blokkban érhető el.
Konstansok
Primitív típusú, konstans értékkel rendelkező azonosítók a
con kulcsszóval deklarálhatók.
Példák:
data: con "/data/user.dat"; # sztring konstans
block: con 512; # egész konstans
pi: con 3.1415926535897932; # valós konstans
Konstans felsorolások
A C felsorolás típusához hasonló típust hozhatunk létre, ha a
con kulcsszót a speciális iota értékkel kombináljuk:
Példa:
Sun, Mon, Tue, Wed, Thu, Fri, Sat: con iota;
A fenti utasítás hatására a Sun konstans értéke 0 lesz, a Mon konstansé 1, és így tovább.
A kezdeti érték megváltoztatására ill. az érték növelésére az iota mellett más operátorokat használunk. A leggyakrabban használt operátorok az összeadás(+), szorzás(*), és bitenkénti léptetés (<< és >>).
Példák:
Ten, Eleven, Twelve: con iota+10;
Zero, Five, Ten, Fifteen: con iota*5;
Two, Four, Eight, Sixteen, ThirtyTwo: con 2<<iota;
Kifejezések, operátorok
Kifejezések
A kifejezés általános alakja:
kifejezés:
bináris-kifejezés
balérték-kifejezés értékadó-operátor kifejezés
( balérték-kifejezés-lista ) = kifejezés
send-kifejezés
declare-kifejezés
load-kifejezés
Egyoperandusú kifejezések
Az egyoperandusú kifejezés egyoperandusú operátort
tartalmazó kifejezés.
Általános alakja:
egyoperandusú-kifejezés:
term
egyoperandusú-operátor egyoperandusú-kifejezés
array [ kifejezés ] of adat-típus
array [ kifejezésopt ] of { init-lista }
list of { kifejezés-lista }
chan of adat-típus
adat-típus egyoperandusú-kifejezés
Egyoperandusú operátorok
- |
negatív előjel, aritmetikai típusra alkalmazható |
+ |
pozitív előjel, aritmetikai típusra alkalmazható |
! |
logikai negáció, int típusú operandusra, ha az
érték 0, akkor 1-re állítja, különben 0-ra |
~ |
int vagy byte típusú operandusa egyes
komplemensét adja vissza |
ref |
adt típusú e kifejezésből ref adt típusú
kifejezést hoz létre, melynek értéke referencia egy e értékű
névtelen objektumra |
* |
* e a ref adt típusú e kifejezés
értéke. Az e értéke nem lehet nil. |
++ |
prefix v. postfix inkrementálás |
-- |
prefix v. postfix dekrementálás |
<- |
lásd: csatorna kommunikáció |
hd |
lásd: listáknál |
tl |
lásd: listáknál |
len |
sztring, tömb vagy lista elemeinek a száma |
Bináris kifejezések
A bináris kifejezés vagy egyoperandusú kifejezés vagy
olyan kétoperandusú, melyben szerepel egy infix operátor.
Általános alakja:
bináris-kifejezés:
egyoperandusú-kifejezés
bináris-kifejezés bináris-operátor bináris-kifejezés
Bináris operátorok
A bináris, kétoperandusú operátorok precedencia szerinti csökkenő
sorrendben:
*, /, % |
szorzás, osztás, maradékképzés
Az operandusok azonos aritmetikai típusúak, az eredmény megegyezik az
operandusok típusával.
A % nem alkalmazható a real típusra.
A túlcsordulás és 0-val való osztás eredménye definiálatlan.
|a%b| < |b|; (a/b)*b + a%b értéke a ; a >= 0, b >= 0 esetén
(a%b) >= 0 |
+, - |
összeadás, kivonás
Az operandusok típusa azonos kell legyen, az eredmény megegyezik az
operandusok típusával.
Alul- és túlcsordulás esetén az eredmény definiálatlan.
A + operátor sztringek esetén konkatenációt jelent. |
<<, >> |
bal-, ill. jobboldali léptetés
A bal oldali operandus típusa lehet big, int vagy byte,
a jobb oldali int típusú. Az eredmény típusa megegyezik a bal oldali
operanduséval. A jobb oldali operandus értéke nem lehet negatív, és
kevesebb kell legyen, mint a bal oldali operandus bitjeinek száma.
<< operátor esetén a kitöltött bitek értéke 0, >> operátor
esetén int esetben a jelek másolata, byte esetben 0. |
<, >, <=, >= |
kisebb, nagyobb, kisebb vagy egyenlő, nagyobb vagy
egyenlő
Csak aritmetikai típusokra és sztringekre alkalmazhatók. Az
operandusoknak azonos típusúnak kell lenni, a sztring értéke lehet nil.
A sztringen végzett összehasonlítás lexikografikus az Unicode
karakterkészleten. Egy inicializálatlan vagy nil-re inicializált
sztring megegyezik a "" üres sztringgel minden összehasonlító
operátornál. |
==, != |
egyenlő, nem egyenlő
Az operandusok típusa lehet aritmetikai, sztring vagy referencia típus.
Általában az operandusok típusának egyeznie kell, de a sztringek és
referencia típusok értéke lehet nil. Referencia típusú
objektumok akkor egyenlők, ha ugyanarra az objektumra mutatnak, vagy
mindkettő értéke nil. |
& |
bitenkénti logikai és
Operandusai azonos típusúak. Ez a típus lehet: byte, int
vagy big.
Az eredmény bitenkénti végrehajtás útján jön létre. |
^ |
bitenkénti logikai kizáró vagy
Operandusai azonos típusúak. Ez a típus lehet: byte, int
vagy big.
Az eredmény bitenkénti végrehajtás útján jön létre. |
| |
bitenkénti logikai vagy
Operandusai azonos típusúak. Ez a típus lehet: byte, int
vagy big.
Az eredmény bitenkénti végrehajtás útján jön létre. |
:: |
lista konkatenáció |
&& |
logikai és
Először a bal oldali operandus értékelődik ki. Ha ez az érték 0,
az egész kifejezés értéke 0 (int típusú). Különben a jobb
oldali operandus is kiértékelésre kerül, és ha értéke 0, az egész
kifejezés értéke is 0 lesz, különben 1. Az operandusoknak azonos
aritmetikai típusúnak kell lenniük. |
|| |
logikai vagy
Először a bal oldali operandus értékelődik ki. Ha ez az érték nem
nulla, az egész kifejezés értéke 1 (int típusú) lesz. Különben
a jobb oldali operandus is kiértékelésre kerül, és ha értéke nem
nulla, az egész kifejezés értéke is 1 lesz, különben 0. Az
operandusoknak azonos aritmetikai típusúnak kell lenniük. |
A :: operátort kivéve (mely jobbasszociatív) a
fenti operátorok mindegyike balasszociatív.