Az Io programozási nyelv

Kifejezések

Az Io-ban nincsenek kulcsszavak vagy utasítások, csak kifejezések!

Egy kifejezés szintaxisa:

exp ::= { message | terminator } message ::= symbol [arguments] arguments ::= "(" [exp [ { "," exp } ]] ")" symbol ::= identifier | number | string terminator ::= "\n" | ";"

A true, false és nil azonosítók szingletonok, megpróbálva őket klónozni önmagukat kapjuk vissza. A true a logikai igaz érték, a false a logikai hamis érték, a nil egy érték hiányát jelzi.

Üzenetek

Az Io az objektumok közötti kommunikáció megvalósítására üzeneteket használ. Az üzenet szintaxisát a fenti kifejezés szintaxisnál találjuk.

Az Io-ban minden, ami nem szám, sztring vagy megjegyzés, egy üzenet a három lehetséges forma (normál, operátor vagy értékadás) valamelyikében megadva.

Normál üzenet

<üzenet neve>(<arg1>, <arg2>,...) <csatolt üzenet, új sor vagy pontosvessző>

A zárójelek opcionálisak, ha nincsenek argumentumok. A pontosvessző is opcionális. Az üzeneten belüli pontosvessző vagy return az adott üzenetlánc végét jelzi, különben a részkifejezés a következőképp értelmezendő: "Használd az eredményét a baloldalnak, mint a jobboldali üzenet célpontját!" Például:

Dog fetch(stick)

Minden állítás kifejezés az Io-ban, ezért minden állítás visszatér valamilyen értékkel.

Operátorok

Szintaktikai cukorkák

<operátor üzenet neve><argumentum><másik operátor, új sor vagy pontosvesszo>

A nyelv operátorait az alábbi módon lehet kiíratni:

OperatorTable
==> OperatorTable_0x249100: Operators 0 ? @ @@ 1 ** 2 % * / 3 + - 4 << >> 5 < <= > >= 6 != == 7 & 8 ^ 9 | 10 && and 11 or || 12 .. 13 %= &= *= += -= /= <<= >>= ^= |= 14 return Assign Operators ::= newSlot := setSlot = updateSlot To add a new operator: OperatorTable addOperator("+", 4) and implement the + message. To add a new assign operator: OperatorTable addAssignOperator("=", "updateSlot") and implement the updateSlot message.

A bal oldalon szereplő számok az operátorok precedenciaszintjét jelzik. A precedenciasorrend zárójelezéssel felülbírálható.

Példák:

1 + 2 //amit így értelmez az Io: 1 +(2) 1 +(2 * 4) //csoportosítás 1 + 2 * 3 + 4 //amit így értelmez az Io: 1 +(2 *(3)) +4
Saját operátor definiálása

Példa: Operátor létrehozása a kizáró vagy műveletre

OperatorTable addOperator("xor", 11)
==> OperatorTable_0x249100: Operators ... 10 && and 11 or xor || 12 .. ...
true xor := method(bool, if(bool, false, true))
==> method(bool, if(bool, false, true)
false xor := method(bool, if(bool, true, false))
==> method(bool, if(bool, true, false)
true xor true
==> false
true xor false
==> true
true xor true
==> false
false xor true
==> true
false xor false
==> false
Értékadó operátorok

Üzenetekként vannak megvalósítva. Nevük alfanumerikus karaktert nem tartalmazhat, kivéve: ";", "_", """, ". ", vagy egyike a következő szavaknak: or, and, return

a ::= 1 //newSlot("a", 1) a := 1 //setSlot("a", 1) a = 1 //updateSlot("a", 1)

Vezérlési szerkezetek

A vezérlési szerkezetek szintaktikai cukorkák nélkül lettek megvalósítva.

Elágaztatás

Az if-utasítás függvényként lett megvalósítva.

if(, , )

A feltétel hamisnak tekintendő, ha vagy false-ra vagy pedig nilre értékelődik ki.

if(a == 10, "a is 10" print) //az else-ág opcionális

Mivel az if az utoljára kiértékelt kifejezés értékével tér vissza, az alábbi if-kifejezések ekvivalensek.

if(y < 10, x = y, x = 0) //ekvivalensek x = if(y < 10, y, 0)
if(y < 10) then (x = y) else (x = 2) //nem olyan hatékony if(y < 10) then (x = y) elseif (y == 11) then (x = 0) else (x = 2) //az else-if is támogatott

A Smalltalk stílusú ifTrue, ifFalse, ifNil, ifNonNil metódusok is használhatók feltételes elágaztatás megvalósítására.

y := 11 (y < 10) ifTrue(x := y) ifFalse(x := 2)
==> false
Ciklusok
Végtelen ciklus
loop("foo" println)
Felsorolásos ciklus
3 repeat("foo" print)
==> foofoofoo
Kezdőfeltételes ciklus
while(<condition>, <do message>) a := 1; while(a < 10, a print; a := a + 1)
123456789 ==> 10
For-ciklus
for(<counter>, <start>, <end>, <optional step>, <do message>) for(a, 0, 10, a print " " print)
0 1 2 3 4 5 6 7 8 9 10 ==>
for(x, 0, 10, 3, x print " " print) //Lépésköz megadva
0 3 6 9 ==>
for(a, 10, 1, -1, a print " " print) //Lépésköz negatív és <start> > <end>
10 9 8 7 6 5 4 3 2 1 ==>

A ciklus magjában kiadva a break és a continue a ciklus szabályos befejeződését eredményezik.

for(i, 1, 10, if(i == 3, continue) if(i == 7, break) i print )
12456

Visszatérési értéket explicit módon meghatározni a return <kifejezés> üzenettel lehet.

test := method(123 print; return "abc"; 456 print) test
123==> abc

Message Reflection

A message reflection segítségével metainformációkat szerezhetünk egy üzenet küldéséről.

Egy üzenet esetében beszélhetünk küldőről, fogadóról és az üzenet paramétereiről, ha vannak. A küldő által küldött üzenetet (kontextussal együtt) a fogadó értékeli ki és hajtja végre.

A call üzenet segítségével az üzenetküldés folyamatába pillanthatunk be. A call értéke egy Call objektum, melynek segítségével információk nyerhetők ki egy metódus, illetve blokk hívásáról.