Deadline: 14 ianuarie 2024 (23:59)
Schelet: skel-bonus.zip
Bonus
In primele 3 etape ati implementat un lexer, etapa bonus consta in folosirea lexerului pentru a face un interpretor pentru un limbaj de programare simplist.
Punctul de intrare a interpretorului vostru o sa fie fisierul src/main.py
, care primeste ca argument fisierul care urmeaza sa fie interpretat si printeaza la stdout rezultatul interpretarii.
python3.12 -m src.main {argumente}
Limbajul L
O sa interpretam un limbaj functional, inspirat din Lisp (“List Processing”), dar mult mai simplificat.
Un program este o lista de atomi, unde un atom poate sa fie:
- un numar natural
- lista vida
()
- o expresie lambda
- o invocare de functie
- o alta lista de atomi
Outputul este un numar, sau o lista formata doar din:
- numere
- alte liste (formate doar din numere sau alte liste)
Pentru a ajunge de la program la output trebuie sa evaluam toate invocarile de functii. Daca o invocare de functie creaza o lista cu noi invocari de functii, acestea trebuie evaluate la randul lor, pana nu mai exista invocari de functii.
Se garanteaza ca programele pe care se testeaza sunt corecte, i.e. mereu se termina, si rezultatul lor o sa contina doar numere sau liste de numere.
Numere naturale
In L o sa folosim doar numere naturale, fara o limita superioara anume, un numar este orice secventa de cifre (de la 0 la 9).
Lista vida
Lista vida este o lista fara elemente, si este reprezentata prin string-ul ()
.
Expresii lambda
O expresie lambda reprezinta definerea unei functii 'custom'. Sintaxa pentru definirea unei expresii lambda este urmatoarea:
lambda {id}: {expr}
Unde:
lambda
este un keyword specific{id}
este un id, format numai din caractere [a-z] sau [A-Z]{expr}
este o lista rezultat, care poate sa contina pe langa atomi obsinuiti si keyword-ul {id}
Pentru a evalua o expresie lambda, inlocuim toate aparitiile id-ului din interior expresiei cu valoarea cu care este apelata expresia lambda.
Exemplu:
(lambda x: (x x) (1 2)) este evaluat la: ((1 2) (1 2))
Invocari de functii
O lista de forma (f x)
poate sa fie evaluata atat timp cat f
este:
- o expresie lambda
- o functie din libraria standard
Pentru simplitate, o sa ne limitam la 2 functii standard:
+
, care cand e aplicat pe o lista, face recursiv suma elementelor din lista si intoarce un atom (nu poate fi aplicat pe liste care contin alte functii/expresii)++
, care aplicat pe o lista, concateneaza toate listele componente (daca in lista exista atomi, acestia sunt adaugi la lista rezultat)
Exemple:
(+ (1 2 3)) se evalueaza la 6 (+ (1 (2 3) 4)) se evalueaza la 10 (+ (())) se evalueaza la 0 (++ (1 (2 3))) se evalueaza la (1 2 3) (++ ((1 2) (3 4) 5)) se evalueaza la (1 2 3 4 5) (++ ((1 2) () 3)) se evalueaza la (1 2 3) (++ ((1 2 ()) (3 4))) se evalueaza la (1 2 () 3 4)
Whitespaces
In cadrul programului putem folosi oricate spatii libere (si newline-uri) pentru identare fara a schimba semantica programului. Singurele spatii importante semantic sunt cele care separa numere / identificatori intre ei.
(1 2 3) este diferit de (123) dar nu este diferit de ( 1 2 3 ) sau de ( 1 2 3 )
Testare si notare
Pentru a testa solutia bonusului aveti la dispozitie scriptul check.sh
.
Important: Pentru echivalarea materiei nu este suficienta trecerea testelor din arhiva, notarea finala o sa se faca la prezentarea proiectului de la finalul semestrului.