Šokeerivate loogikaoperaatoritega Sholog
~b && (T \/ E1) + (foo || E2 /\ F)
Sholog on tõeväärtustega arvutamise keel, kus saab lisaks visata erindeid ja kasutada laiskasid (short-circuit) loogikaoperaatoreid.
AST
Keele AST klassid paiknevad toylangs.sholog.ast paketis ja nende ülemklassiks on ShologNode:
- ShologLit – tõeväärtusliteraal;
- ShologVar – muutuja;
- ShologError – vea-avaldis koos täisarvulise veakoodiga (erind);
- ShologEager – agaralt väärtustatavad binaarsed operaatorid (And, Or, Xor);
- ShologLazy – laisalt väärtustatavad binaarsed operaatorid (And, Or).
Klassis ShologNode on staatilised abimeetodid, millega saab mugavamalt abstraktseid süntaksipuid luua. Ülalolev avaldis moodustatakse järgmiselt:
xor(land(xor(var("b"), lit(true)), eor(lit(true), error(1))), lor(var("foo"), eand(error(2), lit(false))))
Alusosa: ShologEvaluator
Klassis ShologEvaluator tuleb implementeerida meetod eval, mis väärtustab tõeväärtusavaldise etteantud väärtuskeskkonnas. Väärtustamisele kehtivad järgmised nõuded:
- Literaalid ja muutujad käituvad standardselt.
- Vea-avaldise väärtustamisel visatakse sama veakoodiga ShologException.
- Defineerimata muutuja väärtustamisel visatakse ShologException koodiga 127.
- Agarad operaatorid käituvad standardselt, kusjuures alati väärtustatakse mõlemad argumendid vasakult paremale.
Näitekseand(lit(false), error(1))
viskab väärtustamisel erindi koodiga 1. - Laisad operaatorid käituvad standardselt, kuid teine argument väärtustatakse ainult siis, kui esimese argumendi väärtus ei määra juba tulemust ära (short-circuit väärtustamine).
Näiteksland(lit(false), error(1))
ei viska väärtustamisel erindit, vaid tagastab false.
Põhiosa: ShologAst
Failis Sholog.g4 tuleb implementeerida grammatika ja klassis ShologAst tuleb implementeerida meetod parseTreeToAst, mis teisendab parsepuu AST-iks. Süntaksile kehtivad järgmised nõuded:
- Tõene literaal on
T
ja väär literaalF
. - Muutuja koosneb vähemalt ühest ladina väiketähest.
- Vea-avaldis koosneb sümbolist
E
ja sellele järgnevast täisarvust, mis on selle veakood. SümboliE
ja täisarvu vahel ei ole lubatud tühisümbolid. - Binaarsed operaatorid koosnevad kahest avaldisest, mille vahel on operaator: agar ja laisk And on vastavalt
/\
ja&&
, Xor on+
, agar ja laisk Or on vastavalt\/
ja||
. Kõik on vasakassotsiatiivsed ja kahanevas järjekorras on nende prioriteedid: And, Xor, Or. - Lisaks on lubatud unaarne eitusoperaator
~
, millele järgneb avaldis. Eitusoperaatori prioriteet on kõigist binaarsetest operaatoritest kõrgem ning see tuleb AST-is esitada olemasolevate konstruktsioonide kaudu, kasutades samaväärsust:~x = x + T
. - Avaldistes võib kasutada sulge, mis on kõige kõrgema prioriteediga.
- Tühisümboleid (tühikud, tabulaatorid, reavahetused) tuleb ignoreerida.
Lõviosa: ShologCompiler
Klassis ShologCompiler tuleb implementeerida meetod compile, mis kompileerib tõeväärtusavaldise CMa programmiks. Kompileerimisele kehtivad järgmised nõuded:
- Tõeväärtused teisendatakse täisarvudeks CMaUtils.bool2int abil.
- Muutujate väärtused antakse stack’il etteantud järjekorras.
- Programmi täitmise lõpuks peab stack’i pealmine element olema avaldise väärtus, mis on sama nagu ShologEvaluator-iga väärtustades.
- Programmi veatu täitmise lõpuks tohivad stack’il olla ainult etteantud muutujate algsed väärtused ja arvutatud avaldise väärtus.
- Erindi viskamiseks lisatakse stack’i peale veakoodi vastandarv ja lõpetatakse programmi töö koheselt (
HALT
instruktsioon). Sel juhul peavad stack’ile alles jääma ka vahetulemused.
Näitekseand(lit(false), error(1))
lõpetab töö stack’iga [0, -1]. - Defineerimata muutuja korral programm kompileerub (st. ei viska kompileerimise ajal erindit), kuid lõpetab töö eelmises punktis kirjeldatud viisil, kasutades veakoodi 127.
Näitekseand(lit(false), var("jama"))
lõpetab töö stack’iga [0, -127].