Jednym z większych projektów na pierwszym roku studiów magisterskich było stworzenie kompilatora dla języka Latte, rozszerzonego o takie funkcjonalności jak tablice, struktury oraz obiekty z pojedynczym dziedziczeniem. Kod w języku Latte jest parsowany przy użyciu narzędzia BNFC i kompilowany do architektury x86 asemblera.

Kompilator reprezentuje monada Reader-Writer-State:

data Reader = Rd
    { func :: Map.Map String TType
    , clss :: Map.Map String ClassEnv
    }
type Writer = [AsmInstr]
data State = St
    { nextlab :: Int
    , newloc :: Int
    , env :: Map.Map String (TType, String)
    , rodata :: Map.Map String String
    , rspOff :: Int
    }

gdzie

  • Reader przechowuje informacje o funkcjach i klasach,
  • Writer zawiera generowane instrukcje asemblerowe,
  • State przechowuje zmienne oraz niskopoziomowe informacje asemblerowe.

Proces kompilacji obejmuje statyczne sprawdzanie typów, które koncepcyjnie jest zbliżone do tego użytego w Interpreterze Latte.

Kod źródłowy