Filip Czaplicki fc359081@students.mimuw.edu.pl
Program kompiluje się po wykonaniu make
.
Za pomocą bnfc
, happy
oraz alex
generowane jest z
gramatyki część źródeł.
Napisany przeze mnie kod wraz z wygenerowanym kompilowany
jest przez ghc
.
W korzeniu projektu powstaje binarka Latte
.
Program Latte
przyjmuje jako parametry:
- ścieżkę do pliku źródłowego
- (opcjonalnie) flagę
-O0
(słownie: minus o zero), która wyłącza optymalizacje
Wynik wypisuje na standardowe wyjście. Jest to 64-bitowy asembler notacji Intela, implementacja NASM.
Napisałem także dwa skrypty bashowe
odpalające Latte
: latc
oraz latc_x86_64
.
Działają one zgodnie ze specyfikacją zadania.
- BNFC
- kompilator języka Haskell ghc oraz jego standardowa biblioteka
- biblioteka mtl: monada ReaderWriterState - https://hackage.haskell.org/package/mtl
- biblioteka Data.List.Unique - https://hackage.haskell.org/package/Unique oraz jej zależność extra - https://hackage.haskell.org/package/extra
- biblioteka monad-loops - https://hackage.haskell.org/package/monad-loops
- NASM - nasm.us - kompilator asemblera
- gcc - kompilator C - do skompilowania runtime.c oraz zlinkowania
- src
- Backend
- Asm.hs - definicje typów/funkcji związanych z asemblerem
- Compiler.hs - główny plik backendu kompilatora
- EmitClass.hs - generowanie kodu klas
- EmitClass.hs-boot - plik nagłówkowy dla EmitClass.hs
- EmitExpr.hs - generowanie kodu dla wyrażeń
- EmitFunction.hs - generowanie kodu funkcji/metod
- EmitStmt.hs - generowanie kodu dla wyrażeń
- GC.hs - kod związany z Garbage Collection
- Label.hs - asemblerowe etykiety
- Locals.hs - liczenie ile potrzeba pamięci na zmienne lokalne
- Optimize.hs - optymalizacje
- State.hs - "stan" kompilacji
- Frontend
- Assert.hs - wszelakie asserty
- Check.hs - główny plik frontendu
- Classes.hs - sprawdzanie klas, dziedziczenia itp.
- Classes.hs-boot - plik nagłówkowy dla Classes.hs
- Context.hs - kontekst błędu
- Env.hs - "środowisko" - stan frontendu, częściowo używany w backendzie
- Errors.hs - funkcje pomocnicze do wypisywania błędów
- Functions.hs - sprawdzenie funkcji/metod
- Print.hs - funkcji pomocnicze związane z wypisywaniem błędów
- Print.hs-boot - plik nagłówkowy dla Print.hs
- Pure.hs - funkcje czyste, niekorzystające z monad
- Typecheck.hs - statyczna analiza kodu
- Typecheck.hs-boot - plik nagłówkowy dla Typecheck.hs
- Main.hs - główny plik kompilatora, obsługa IO, argumentów itp.
- Latte.cf - gramatyka języka
- Backend
- lib
- runtime.c - implementacja funkcji printInt itp. oraz wewnętrznie używanych
latc
latc_x86_64
- Makefile
- README
Optymalizacje zaimplementowane są w src/Backend/Optimize.hs. Funkcja:
optimizeStmt
robi "peephole optimization", lokalnie zastępuje instrukcje, usuwa niepotrzebneremoveUnusedLabels
usuwa nieużywane etykietyremoveDeadCode
usuwa martwy kod przy użyciu dfsa po instrukcjach asemblera.optimizeOnce
jest złożeniem tych funkcji.optimize
odpalaoptimizeOnce
aż do uzyskanie punktu stałego
Moje projekty:
- interpreter języka opartego na Latte (w ramach IPP) https://github.com/starsep/lang
- pierwsze zadanie z MRJP - kompilator Instant https://github.com/starsep/instant