A Factor programozási nyelv

Nyelvi elemek

Jelkészlet és a stringek

UNICODE támogatás
A Factor nyelv és a hozzá adott környezet támogatja unicode jelkészlet használatát a forrásban, így például a következő rövid forráskód az értelemszerű eredményt (a német scharfes s betű kétkarakteres nagy-alakját) írja a kimenetre:

USING: prettyprint unicode.case "ß" ! "ß" string literál a veremre >upper ! verem tetején lévő string átalakítása uppercase-re . ! verem tetején álló objektum kiírása (prettyprint)

A fenti példán az is látszik, hogy a unicode karakterek string literáljait nem kell másképpen írni a forrászövegben. Ez utóbbi jelenség annak is köszönhető, hogy a Factor belső ábrázolásában, a string egyes standard ASCII karaktereihez csupán 7 bitet használ fel és csak az egyéb karakterek esetén használja a bővebb ábrázolási formát.

Case-sensitivity
A factor nyelv case sensitive, például a Unicode-támogatást szemléltető forrásban nem írhatunk 'USING:' helyett 'using:'-ot, sőt mivel, mint azt majd látni fogjuk a kettőspont is a szó része, nem írhatunk 'using :'-ot sem. Vagyis pontosabban fogalmazva: Az előző kettő esetben, két különböző szóra próbáltunk hivatkozni, utóbbi esetben pedig két szóra is egyszerre!

Fontosabb elválasztó jelek és jellemzésük

Egy factor forrásnyelvű program a gyakorlatban szóközzel elválasztott szavakból épül fel. Nagyon fontos, hogy bár a szavakat tetszőlegesen sok szóköz választhatja el egymástól, nem használhatunk tabulátor-karaktert (pl. indentálásra) az egymás melletti szóközök helyettesítésére. Ez igen szokatlan dolog, főleg, hogy látszólag a tabulátorokat semmi más célra nem használják, viszont ez így ebben a formában igen kellemetlen lehet azoknak a fejlesztőknek, akiknek a keze nem a space-ekkel történő egyenkénti indentálásra van ráállva.

A nyelvben ezen felül gyakran találkozhatunk bizonyos szerkezetek végét jelző pontosvessző jelekkel és ránézésre "blokkszerű" szavakkal(például "HAND{"), melyeket általában a } szó kell lezárjon. Azonban itt is érdemes figyelni, mert - mint arra előzőleg kitértünk már a fejezetben - a Factor program általánosságban egy szóközökkel elválasztott listája szavaknak és a fordító emiatt szintaktikus hibát fog jelezni, ha mondjuk egybe írjuk a szódefiníció végi pontosvesszőt az utolsó utasítással (nem teszünk a kettő közé egy space-t) és egyéb hasonló helyzetekben.
Néhány "rossz" példa, mellette kommentben a jó megoldás:

USING: prettyprint kernel poker : szavam ( -- ) 42 .; ! '.;' szó nincs, '. ;' írandó.. HAND{7C 7D} ! 'HAND{7C' és '7D}' szavak nincsenek, helyesen: ! HAND{ 7C 7D } jó, feltételezve, hogy USE: poker 4 5 <[0][1]if ! helyesen: 4 5 < [ 0 ] [ 1 ] if "alma" ! Ez viszont így helyes és nem " alma " formában, ! mert az utóbbi a space-eket is tartalmazó string!

Megjegyzések

A Factor nyelv egyelőre háromféle kommentelési lehetőséggel rendelkezik:

Nagyon fontos, hogy ezek is tulajdonképpen szavak csupán, azaz például a '5 ! komment' helyes sor, de az '5! komment' és a '5 !komment' már nem!
Nem teljesen egyértelmű a konvenció, hogy mikor melyiket alkalmazzák, de a legtöbbször inkább a fenti mezei egyetlen felkiáltójelet látni.

Factor-aritmetika, szavak és literálok

A Forth-hoz hasonlóan a Factor-ban is postfix formában értendő a legtöbb művelet. Az egymás mögé írt literálok vagy szavak futása balról jobbra olvasva történik úgy, hogy a literálok a veremre kerülnek, a szavak pedig a verem tetején dolgoznak. Persze akadnak kivételes esetek is (például a 'USING:', vagy a \ kombinátor), melyek például prefix műveletként viselkednek, mindazonáltal az általános képet postfix alakú kifejezések alkotják.
Ezekre mutatunk először néhány példát (a fentiek mellé):

USE: prettyprint USE: math 5 3 + . ! A veremre kerül az 5(literál), aztán erre a 3(literál). ! Utána a + kombinátor leszedi a verem két felső szám típusú értékét, ! összeadja, majd visszaírja a verem tetejére ! A . generikus prettyprint operátor látván, ! hogy a verem tetején egy szám található, kiírja azt az outputra. ! Az eredmény: 8 5 3 - . ! Hasonló az előzőhöz, az eredmény 2 lesz (mert 5 - 3 = 2) 5 3 * 4 / . ! Lépésenként a verem ! (az alja balra, teteje jobbra, ! @: a korábbi verem tartalma, ! #! után a vermet előállító nyelvi egység): ! @ ! @ 5 #! 5 ! @ 5 3 #! 3 ! @ 15 #! * ! @ 15 4 #! 4 ! @ 3+3/4 #! / ! @ #! . ! és az eredmény a képernyőn: 3+3/4 "alma" print ! Az alma string a veremre kerül, ! majd a print kiírja a verem tetején látott stringet. ! Eredmény: alma

A fenti példában Factor-szavak(az előfordulás sorrendjében):


A literálok pedig a számliterálok és a string literál voltak. A literálokkal a következő alszekcióban foglalkozunk bővebben.

Literálok

Factorban többféle literál létezik, de nagyon sok olyan dolog, ami első látásra literálnak nézhet ki (például 'V{ 1 2 3 }' ) a nyelvnek egy kiterjesztése, egy szavak és literálok kombinációjából előálló kifejezés, mely bár előállíthatja az eredményt fordítási időben, mégsem nevezhető hagyományos értelemben vett literálnak. Mivel a factor egy kiterjeszthető nyelv (ami még néha változik is), nehéz különbséget tenni aközött, hogy valami könyvtári egységként, vagy nyelvi elemként van benne megvalósítva. A most következő felsorolásunkban pont ezért nem feltétlenül azt fogjuk szem előtt tartani, hogy mi hogyan van megvalósítva, hanem mi az ami logikailag literálként fogható fel. Tesszük mindezt azért, mert inkább a hasznosság tekintetében szeretnénk bemutatni a lehetőségeket.

Számliterálok

#! Egészek: 123456 ! Egy pozitív egész -10 ! Negatív szám 2432902008176640000 ! Nagy pozitív egész BIN: 100 ! Bináris megadási mód ! érték: 4 (10-esbe) OCT: 31337 ! Oktális megadási mód ! érték: 13023 (10-esbe) HEX: ff ! Hexadecimális megadás ! érték: 255 #! Racionális számok: 75/33 ! Sima törtalak 1/10 ! Egy tized törtalakja -5/-6 ! lehet száml. és nev. is negatív 1+1/3 ! 4/3 -10-1/7 ! -77/7 #! Lebegőpontos számok: 10.5 -3.1456 7e13 1.0e-5 1.0E+5 ! Eddig Értelemszerűen (szokott módon) 1/0 ! NEM EGY KIFEJEZÉS, hanem plusz végtelen ! értékű literál -1/0 ! NEM EGY KIFEJEZÉS, hanem mínusz végtelen ! értékű literál 0/0 ! NAN (Not A Number) literál #! Komplex számok: C{ 1/2 1/3 } ! 1/2 + (1/3) * i C{ 0 1 } ! i

Kódidézet literálok(quotations)

USE: fry ! A másodikhoz kell [ 5 4 + . ] ! A stackre helyezi a [ és a ] között található kódot ! Végrehajtás: [ 5 4 + . ] call '[ _ _ + . ] ! "Lyukas-idézettkód" literál, ha a stackre tesszük előtte 4-et és 5-t, ! akkor ugyanaz, mint az előző.

Vektor és tömbliterálok

{ 1 2 3 } ! Számok tömbje { 1 2 "asdf" } ! Na ez már egy nyelvi érdekesség! { 1 { 2 } { { 3 } } } ! Ilyesmit is lehet(egymásba ágyazott tömbliterál) { "1" { 2 } { { 9/3 } } } ! Nem ugyanaz, mint az előző B{ 1 2 3 } ! Byte-array B{ 1 { 2 } } ! ERROR: ilyet nem lehet B{ 1 B{ 2 } } ! ERROR: ilyet sem { 1 B{ 2 3 } "asdf" } ! Ilyet viszont minden további nélkül lehet V{ 1 2 "asdf" B{ 3 } } ! Ez egy vektor(nőhet a mérete) és lehet ilyet B{ 0 V{ 1 } } ! ERROR: Bytearray csak számokat tartalmazhat... V{ } ! Üres vektor { } ! Üres tömb B{ } ! Üres Byte-tömb { B{ } V{ } "asdf" "" 1 2 } ! Tömb literál, amiben van: ! Egy üres byte tömb ! Egy üres vektor ! Egy string ! Egy üres string ! és két szám

String és karakterliterálok

CHAR: x ! x CHAR: \u000032 ! space CHAR: \u{exclamation-mark} ! felkiáltójel CHAR: exclamation-mark ! ez is a felkiáltójel CHAR: ugaritic-letter-samka ! valami varázslatos unicode betű "Hello World" ! Szokásos hello string "Hello World" ! Soremelést/újsort is tartalmazó string "\u{greek-capital-letter-sigma}i<-0..n : " ! Egy szumma jel, majd egy i<-0..n : """Azt mondta "halihó"... és szó nélkül hazament""" ! Triplastring: lehet benne idézőjel is "\\ \s \t \n \r \0 \e \"" ! \ space tab újsor kocsivissza ASCII0 ESC " SBUF"Hello world" ! Stringbuffer literál(átméretezhető stringekhez) P" c:\asdf.txt" ! PATHNAME literál. P" után a space szükséges!!!

Hasítótábla literálok

H{ { "tuna" "fish" } { "jalapeno" "vegetable" } } ! kulcs-érték párok: ! tuna->fish; japapeno>vegetable

Hashset literálok

HS{ 3 "foo" V{ 8 } } ! Hash adatszerkezettel reprezentált halmazliterál

Tuple(rekord) literálok

USE: colors T{ rgba f 1.0 0.0 0.0 } ! TUPLE objektum rgba class-ból ! feltöltve a megadott értékekkel(az a érték hiányzik) T{ rgba { red 1.0 } { green 0.0 } { blue 0.0 } } ! mint az előző T{ rgba { green 1.0 } { alpha 0.5 } ! DE! Ezzel lehet ilyet is..

Stack-effect literálok

(( x y -- y x )) ! A swap stack effect-je

A stack effekt literálok nem azok, amiket (majd később látni fogjuk) szódeklarációinkhoz írunk, hanem olyan literálok, amik ilyen deklarációkat jelképeznek és a veremre írjuk őket valamilyen okból. Használják például belső célokra, de használhatjuk mi is, ha például paraméterként a veremre akarjuk tenni, hogy egy-egy másik paraméterszó milyen módon működik (bizonyos értelemben egyfajta reflection támogatás).

XML literálok

USE: xml xml.syntax <XML <?xml version="1.0"?><document> ... </document> XML>

Az f és a t

f ! tényleges false logikai érték t ! konvenció szerinti true logikai érték

Fent az f leírásával egy false értéket jelképező singleton osztály(f osztály) egyetlen objektumát(f objektum) tesszük a veremre, t esetén viszont egy hagyományos szót csupán. Az okokra majd a következő fejezetben térünk ki, de t helyett használhatnánk akár a 42 értéket is true-ként, de ez nem lenne valami olvasható és ha lehet az ilyen és hasonló anti-patterneket kerüljük! Röviden: minden ami nem f true, de ha true-t akarunk írni, akkor írjunk le egy t betűt inkább!

Konstansok

A Factor nyelvben definiálhatunk konkstansokat is. Ezzel tulajdonképpen egy olyan szavat kapunk, ami egy konstans értékkel tér vissza:

CONSTANT: magic 1 ! '5 magic + .' azt írja ki majd, hogy 6 CONSTANT: science HEX: ff0f ! Ilyet is lehet, használhatóak a számrendszerek!