ChucK

Operátorok

A ChucK operátor

A ChucK operátor (=>) többszörösen túl van terhelve, jelentése függ a típusoktól, melyeken használjuk, többfajta hatást fejt ki. Ezek a hatások láncba rendezhetők, kiértékelésük balról jobbra történik. A ChucK operátor szolgál a ChucK-kal történő munka végzésére (szűrők sorba fűzése). A ChucK operátor igazából operátorok családja. Az összes ChucK operátor balasszociatív.

Alapvető ChucK operátor

Először essék szó a hagyományos ChucK operátorról (=>). Mivel balasszociatív, segítségével bármilyen irányított adat-, taszk- vagy modulfolyam felépíthető (például unit generator-okból), beszélt nyelvhez hasonló szintaxissal. A (=>) viselkedése kontextusfüggő. Konkrét jelentése függ a bal oldalán (chucker) és jobb oldalán (chuckee) szereplő kifejezés típusától, és néha az entitástól is (változó vagy konstans).

Néhány példa:

// UGen objektumok összekapcsolása - az adatfolyam iránya jól látszik // (ebben az esetben a => az egyik UGen kimenetét a másik UGen bemenetére köti) SinOsc b => Gain g => BiQuad f => dac;
// 4-el megnöveli a foo változó értékét és az eredményt egy új 'int' változóba bar-ba helyezi // (ebben az esetben a => változó értékadást jelöl) 4 + foo => int bar;
// értékek (paraméterek) chuck-olása függvényhez // (ebben az esetben a => függvényhívást jelöl) // (a két sor ekvivalens) ( 30, 1000 ) => Math.random2f; Math.random2f( 30, 1000 );

Explicit értékadó ChucK operátor (@=>)

A ChucK-ban nincs értékadó operátor (=), az értékadás is ChucK operátorok segítségével történik. Eddigi példáink során a (=>) operátort használtuk értékadásra.

// 4-et értékül adjuk a foo változónak 4 => int foo; // 1.5-et értékül adjuk a bar változónak 1.5 => float bar; // 100 ezredmásodpercet értékül adjuk a duh időtartam változónak 100::ms => dur duh; // a later idő változóba a jelen (now) időtől 5 másodperccel későbbi időt adjuk értékül 5::second + now => time later;

Az @=> explicit értékadó operátor ugyanígy viselkedik a fenti típusokra. A különbség az, hogy a @=> használható objektumok referenciáinak értékadásához, míg a => csak beépített típusokon működik. A => viselkedése objektumokra függ a környezetétől.

// primitív típusok esetén az @=> megegyezik az => operátorral 4 @=> int foo; 1.5 @=> float bar; // (csak az @=> operátor alkalmazható objektum referenciák értékadására) // moe referenciáját adjuk értékül a larry objektumnak // (moe és larry változók ugyannara az objektumra hivatkoznak) Object moe @=> Object @ larry; // tömb inicializálás [ 1, 2 ] @=> int ar[]; // new kulcsszó használata new Object @=> moe;

Bár elsőre furcsának tűnhetnek a ChucK operátorok, megszűntetik az értékadó operátorok (@=> és =>) és az egyenlőségvizsgálat (==) között más nyelvekben felmerült kavarodást. A következő nem helyes ChucK utasítás:

// helytelen utasítás ChucK-ban! int foo = 4;

Aritmetikai ChucK operátorok (+=>, -=>, *=>, /=>, stb.)

Ezen operátorok segítségével int vagy float típusú változókra kombinálhatjuk az értékadást egy művelettel.

// foo tartalmát 4-el növeljük, az eredményt a foo változóban tároljuk foo + 4 => foo; // az előző utasítással megegyezik 4 +=> foo; // foo értékéből kivonunk 10-et, az eredményt a foo változóban tároljuk // figyelem ez az érték (foo-10), nem pedig (10-foo)! 10 -=> foo; // foo értékét megduplázzuk, az eredményt a foo változóban tároljuk 2 *=> foo; // foo értékét 4-el elosztjuk, az eredményt a foo változóban tároljuk // figyelem ez az érték (foo/4), nem pedig (4/foo)! 4 /=> foo;

Fontos különbséget tenni változó és érték között, mert ezen operátorok nem kommutatívak.

// foo változó értékének T-vel vett maradéka, az eredményt a foo változóban tároljuk T %=> foo; // bitenkénti ÉS a bar változóban tárolt érték és a 0xff érték között // az eredményt a bar változóban tároljuk 0xff &=> bar; // bitenkénti VAGY a bar változóban tárolt érték és a 0xff érték között // az eredményt a bar változóban tároljuk 0xff |=> bar;

Aritmetikai operátorok (+, -, *, /)

Ezen operátorok a C++-beliekhez hasonlóan működnek.

// osztás (és értékadás) 16 / 4 => int four; // szorzás 2 * 2 => four; // összeadás 3 + 1 => four; // kivonás 93 - 89 => four;

Konverziós operátorok

A ChucK az int típusú értékeket szükség esetén automatikusan konvertálja, de fordítva nem, ezért ha erre van szükségünk, explicit konverziós operátort kell hasznánunk.

// float és int összege float-ot eredményez 9.1 + 2 => float result; // float típus explicit kasztolással alakítható int-té 4.8 $ int => int foo; // foo == 4 // a random2f függvény két float típusú értéket vár Math.random2f( 30.0, 1000.0 ); // int típus implicit konvertálódik float típusúra Math.rand2f( 30, 1000 );

Moduló (%)

A moduló operátor megadja az egész, lebegőpontos, időtartam és idő/időtartam osztások maradékát.

// 7 mod 4 (result = 3) 7 % 4 => int result; // 7.3 mod 3.2 lebegőpontos maradék (resultf = .9) 7.3 % 3.2 => float resultf; // időtartam maradék (foo = 1::second) 5::second % 2::second => dur foo; // idő%időtartam maradék // (bar = az előző 5 mp-el osztható időpillanat óta eltelt idő) now % 5::second => dur bar; // szinkronizáláshoz az alábbi kódrészletet szokták alkalmazni // (then = a következő egész másodperc időpillanata) 1:: second - (now % 1::second) => time then;

Az utóbbi kódrészleteket (idő%időtartam) gyakran használják shredek közti szinkronizációra.

Logikai operátorok (&&, ||, ==, !=, >, >=, <, <=)

A logikai operátorok két operandust várnak, és értékük integer 0 vagy 1. Szemantikájuk a C++-beliekkel egyező.

// azonosan igaz állítások tesztje if( 1 <= 4 && true ) <<<"horray">>>;

Bitoperátorok (>>, <<, &, |, ^)

Ezen operátorok int értékeken dolgoznak. A logikai operátorokhoz hasonlóan szemantikájuk a C++-beliekkel egyező.

Növelő/csökkentő operátor (++, --)

Működésük a C++-beliekkel megegyező.

4 => int foo; foo++; foo--;

Unáris operátorok (!, +, -, new)

Ezen operátorok megelőzik az operandusukat.

// logikai negálás if( !true == false ) <<<"yes">>>; // aritmetikai negálás -1 => int foo; // példányosítás new object @=> object @ bar;