A Cecil programozási nyelv

Üzenetek

Üzenetek

A Cecil terminológiája szerint egy x objektum m metódusának meghívása azt jelenti, hogy az x objektumnak az m üzenetet küldjük. Tehát az

m(x);

utasítás az x objekutmnak az m üzenetet küldi.

A Cecilben egy objektum valamely mezőjét kizárólag a hozzá tartozó, un. hozzáférési metódusokkal lehet elérni, amelyek viszont minden mezőhöz automatikusan

object obj;
var field x(@obj);

Az obj objektum x nevű mezőjéhez itt automatikusan generálódnak a

method x(v@obj) { prim rtl { }
method set_x(v@obj, value) { prim rtl { := value; } }

hozzáférési metódusok. (A metódusok törzsében un. primitív metódusok vannak, amelyek segítségével rtl vagy c++ kódrészleteket lehet a Cecil kódba ágyazni.) A fentieket a nyelv készítői úgy fogalmazzák meg, hogy az objektumok állapotát (példány- és osztályváltozók) a Cecil a mező fogalmával valósítja meg. Egy mezőhöz hozzá vannak rendelve a hozzáférési műveleti, és ha az x műveletet küldjük az obj objektumnak, akkor az objektum megtalálja és meghívja a lekérdező hozzáférési metódust és visszaadja a rejtett változó tartalmát, így úgy működik, mintha hivatkozás lenne az obj objektum x példányváltozójára.

Az üzenetküldés általános szintaxisa:

message ::= msg_name ``('' [exprs] ``)''
exprs ::= expr { ``,'' expr }
unop_msg ::= op_name unop_expr
binop_msg ::= binop_expr op_name binop_expr

Tehát üzenetet három formában lehet írni:

Általában egy olyan üzenetet, melynek neve betűvel kezdődik, névvel jelölt formában írnak, míg egy valamilyen írásjel szimbólummal (punct) kezdődő nevű üzenet pre- ill. infix formában íródik. De minden névvel jelölt üzenet hívható operátorként (infix vagy prefix, argumentumszámától függően), és minden operátor hívható névvel jelölt üzenetként, ha a neve elé egy aláhúzás karaktert írunk. Például mindkét alábbi kifejezés a 3 és 4 objektumoknak küldött + üzenetet jelenti:

3 + 4
_+(3, 4)

illetve a következő két kifejezés mindegyike a bit_and üzenetet küldi a 3 és 4 objektumoknak:

bit_and(3, 4)
3 _bit_and 4

A Cecilben ugyan kizárólag az üzenetküldés szemantika létezik, de számos szintaktikus cukor létezik, melyek az általánosan elterjedt jelöléseket a Cecil terminológiájához igazítják.

A pont jelölés:

Megengedett, hogy az üzenet első argumentumát kiemeljük, és ponttal elválasztva az üzenet neve elé írjuk:

dot_msg ::= dot_expr ``.'' msg_name [``('' [exprs] ``)'']

Ha az üzenetnek csupán egy argumentuma van, akkor az üres zárójelek elhagyhatók. Következésképpen az alábbi három kifejezés ekvivalens (mindegyik az m üzenetet küldi az o objektumnak):

m(o)
o.m()
o.m

A következő két kifejezés szintén ekvivalens:

bit_and(3,4)
3.bit_and(4)

Ez a jelölés kicsit megtévesztő módon azt sugallja, hogy az első argumentum fontosabb, mint a többi, ám ez nem így van. Az argumentumok teljesen egyenértékűek.

Egy másik szintaktikus cukor az üzenetek értékadás formában történő írása. Minden üzenet állhat értékadás bal oldalán:

assign_msg ::= lvalue_msg ``:='' expr -- cukor: set_msg(exprs...,expr)
lvalue_msg ::= message
  | dot_msg
  | unop_msg
  | binop_msg

Minden ilyen esetben az értékadást "kiváltó" üzenet a set_x, ha x az értékadás bal oldalán álló üzenet neve. A küldött üzenet argumentumai pedig az értékadás bal oldalán álló üzenet argumanetumai, és az értékadás jobb oldalán álló kifejezés. Tehát az alábbi utasítások mind ekvivalensek:

set_foo(p,q,r);
foo(p,q) := r;
p.foo(q) := r;

ugyanúgy, ahogy a

set_top(rectangle, x);
rectangle.top := x;

és a

set_!(v,i,x);
v!i := x;
_!(v,i) := x;

utasítások is egyenértékűek. (A ! az standard könyvtárban definiált tömb indexelés bináris operátor).