Az alábbi szöveget lényegében egy, a fordítóról szóló levélből vettem át. Ebben többek között megtalálja az olvasható nyelv szintaxisát.
Background information about the olvashato compiler
The following are (slightly changed) quotes from an email I wrote about the olvashato compiler. Among other things, they describe the syntax of the language.
This material is only available in hungarian.
Nyilván tudod, hogy ugyanazt a höföt (http://dp.iit.bme.hu/dp-current/dp06a-nhf.html) kell beadni sml-ben és prologban. Persze a legtöbb ember lusta teljesen külön megírni a kettőt, így azt csinálja, hogy először sml programot ír side effektek nélkül (a mutable táblák amúgy ehhez a feladathoz kényelmesek lennének), utána kézzel prologgá fordítja. Ezzel persze a prologot sem használja ki teljesen, hiszen nem használja a backtrackinget vagy a nyílt végű listákat. No most az sml kódot prologra fordítani elég unalmas munka (persze még mindig gyorsabb lenne, mint a fordítót megírni, de unalmasabb:). Tudniillik ahol egymásba ágyazott függvények szerepelnek, ott az összes közbülső eredménynek Nevet kell adni (kivéve az aritmetikát). Persze sok optimizációt így is meg lehetne csinálni a fordításnál, és ez tényleg segítene a prologot megérteni. Az sml-ben azonban szerintem semmit sem segített volna, ha kézzel írom, mivel az a nyelv, amiről fordítok, majdnem teljesen sml, csak egyszerűbb szintakszissal.
A fordító nem teljes, csak annyit csináltam meg belőle, ami a házihoz elég volt (sőt, még annál is kevesebbet, mert egy-két dolgot, ami csak egyszer kellett, kézzel megírtam prologban és sml-ben). Ebből adódóan a fordító -- úgy, ahogy most van -- a nagyházi kivételével a többi példát nem is fogja tudni sml-re lefordítani, csak prologra. (A hiányzó részeket nem lenne nehéz megírni.) Az svn repoban van valahol egy olyan verzió, ami még csak prologra fordít, azzal ezek a példák is működtek. Nos, a nyelvet, amiről fordítok, olvashatónak hívom. (Eredtileg azért, mert a cél az, hogy olvasható prolog és olvasható sml kimenetet kapjak, tehát a nyelv ezeknek a közös része. Most már inkább azért, mert az olvasható forrás sokkal olvashatóbb, mint a prolog kód amit kapok belőle.) Az olv nyelv szintaxisa S-expressionökből áll. A program deklarációk sorozata. A legfontosabb deklaráció a defun: (defun NAME (PARM1 ...) EXPR DOCSTRING) Ez egy függvényt definiál NAME néven, (PARM1, PARM2, ...) formális paraméterekkel, aminek a törzse EXPR. A DOCSTRING a függvény dokumentációját tartalmazza, aminek prologban és sml-ben is értelmesnek kell lennie, ezért némi helyettesítésen megy át. További deklarációk a következők: (impfun NAME (PARM1 ...)) Meglévő (nem olvasható-ban definiált) függvény importálása. (mutual (defun NAME (PARM1 ...) EXPR DOCSTR) ...) Kölcsönösen rekurzív függvénydefiníció. Csak a prolog fordító támogatja, pedig csak sml-ben lenne értelme. (deftype TYPENAME (CONSNAME ELT1 ...) ...) Definiál egy új konkrét adattípust. TYPENAME egy string, ami a típus sml nevét tartalmazza, esetleg típusparaméterekkel. CONSNAME a típus egy konstruktorának nevét adja meg, ez egy szimbólum, amit az olv kód később felhasználhat. A konstruktornak nulla vagy több paramétere lehet, ezeknek sml típusa rendre ELT1, ELT2, ... (imptype TYPENAME (CONSNAME ELT1 ...) ...) Ugyanaz, mint a fenti, de nem definiálja a típust, hanem feltételezi, hogy már definiálva van. (export OLVNAME NAME) Azt mondja meg, hogy ha később definiálsz vagy deklarálsz egy globális OLVNAME szimbólumot (ami lehet konstruktor vagy függvény), akkor azt a prolog ill sml kódban a NAME névvel kell jelölni. Az export híján a fordító maga választ egy (általában) megfelelő nevet. Az export deklarációt akkor kell használni, ha nem olv kódban is hivatkozol ugyanarra a névre, vagy ha a nevet egyenesen nem olv kód definiálja. (comment STR) Megjegyzést szúr be. (prolog CODE) (sml CODE) Kézzel írt prolog illetve sml kódot szúr be. (!!ifdef PREPROCESSOR_SYMBOL DECL ...) (!!ifdef PREPROCESSOR_SYMBOL DECL ... !!else DECL ...) (!!ifndef PREPROCESSOR_SYMBOL DECL ...) (!!ifndef PREPROCESSOR_SYMBOL DECL ... !!else DECL ...) Feltételes fordítás. Azért van rá szükség, hogy a prolog és sml program különbözhessen. A kifejezések a következőképpen nézhetnek ki (remélem, nem hagyok ki semmit). SYMBOL Lokális változó értékét adja eredményül. Lokális változót három dolog hozhat létre: a defun formális paraméterei, és a később ismertetendő let és lambda kif-ek. INTEGER Egész szám literál. (FUNCNAME ARGS ...) Defunnal vagy impfunnal definiált függvény hívása. (CONSNAME ARGS ...) Deftype-pal vagy imptype-pal definiált konstruktor hívása. A CONSNAME továbbá lehet az alábbi beépített konstruktorok egyike is: rec -- tuple list -- lista cons -- pontozott lista true -- boolean igaz false -- boolean hamis (+ X ...) (- X) (- X Y) (* X ...) (div X Y) Aritmetika. Negáció csak prologban. (< X Y) (<= X Y) (= X Y) (/= X Y) Számok összehasonlítása. (equal X Y) Tetszőleges kifejezések mély összehasonlítása. (and BOOL ...) (or BOOL ...) (not BOOL) Boolean műveletek, az első kettő short circuites. Csak prologban. (abort) Fatális hiba. (if COND THENEXPR ELSEEXPR) (if COND1 THENEXPR1 COND2 THENEXPR2 ELSEEXPR) ... Feltételes kifejezés. (let (EXPR) (VAR) BODY) A VAR új lokális változó értéke EXPR lesz a BODY kifejezésben. (let (EXPR) (PATT) BODY) (let (EXPR) (PATT1) BODY1 (PATT2) BODY2) ... Összetett kifejezéseket bont szét darabokra. Az első olyan BODY hajtódik végre, ahol a PATT minta illeszkedik az EXPR kifejezés értékére. Valamelyik mintának illeszkednie kell. A PATT általában tetszőleges minta lehet, ami új változónevekből és konstruktorhívásokból áll. Ha egy változónév többször is előfodrul, attól még különböző változókat jelent, vagyis pl a (rec x x) nem csak olyan tuplere illeszkedik, ami két azonos elemet tartalmaz, hanem akármilyen tuple-re, és az x értéke valamelyik lesz a kettő közül. (let (EXPR1 EXPR2) (PATT1 PATT2) BODY) (let (EXPR1 EXPR2) (PATT11 PATT21) BODY1 (PATT12 PATT22) BODY2) ... Több kifejezést illeszt egyszerre. (lambda (PARM ...) BODY) Névtelen függvényt hoz létre. (call FUN ARG ...) Meghív egy névtelen függvényt. A nyelv valójában statically typed, de a fordító erről nem tud, ő lényegében úgy fordítja, mintha dynamically typed lenne. A típusokat az sml fordító ellenőrzni.
Zsbán Ambrus, 2006. december 23.